Reputation: 43
I have a simple little game that I'm working on just to get my feet wet in the designing process. I ran into a problem while trying to do collision detection for an item in a list. I have an enemy class that will spawn three enemies at a time and then those ships will each have the ability to fire three bullets at a time. Problem I'm getting is that my collision detection is tracking the ship and not each individual bullet even though the collision rect is getting the bullet position. In the shoot bullets method, I assign a Vector2 to copy the bullet position (pretty sure I have to do something with passing in the index, but I don't know where to begin with that). Any help/guidance would be much appreciated!
SpriteManager.cs
for (int j = 0; j < enemies.Count; j++)
{
Enemies e = enemies[j];
//Update Sprite
e.Update(Game.GraphicsDevice, gameTime);
//Check for Collision
if (e.collisionRect.Intersects(player.collisionRect))
{
lives -= 1;
}
}
Enemies.cs
public void ShootBullets()
{
Bullets newBullet = new Bullets(bulletTexture);
newBullet.velocity.X = velocity.X - 3f;
newBullet.position = new Vector2(position.X + newBullet.velocity.X,
position.Y + (texture.Height / 2) - (bulletTexture.Height / 2));
//Test
bulletPos = newBullet.position;
newBullet.isVisible = true;
if (bullets.Count() < 3)
bullets.Add(newBullet);
}
public Rectangle collisionRect
{
get
{
return new Rectangle(
(int)bulletPos.X + collisionOffset,
(int)bulletPos.Y + collisionOffset,
bulletTexture.Width - (collisionOffset * 2),
bulletTexture.Height - (collisionOffset * 2));
}
}
Edit to add Bullets class:
public class Bullets
{
// Variables
public Texture2D texture;
public Vector2 position;
public Vector2 velocity;
public bool isVisible;
//public Rectangle boundingBox;
//public Vector2 origin;
//public float speed;
// Methods
// Constructor
public Bullets(Texture2D newTexture)
{
// speed = 10;
texture = newTexture;
isVisible = false;
}
// Draw
public void draw(SpriteBatch spritebatch)
{
spritebatch.Draw(texture, position, Color.White);
}
}
}
Upvotes: 1
Views: 508
Reputation: 2296
Instead of just looping through the enemies, you also need to loop through each of the enemy's bullets.
Simplest modification to your code would look something like
for (int j = 0; j < enemies.Count; j++)
{
Enemies e = enemies[j];
//Update Sprite
e.Update(Game.GraphicsDevice, gameTime);
for (int u = 0; u < e.bullets.count; u++) {
Bullet b = e.bullets[u];
//Check for Collision
if (b.collisionRect.Intersects(player.collisionRect))
{
lives -= 1;
}
}
}
however, please be aware there are several things generally not recommended that you are doing here.
First of all, instead of each enemy having their own list of bullets, there should be one global list for all bullets, which each enemy adds to as they "fire" their bullets.
then you can only search through that one list, instead of looking up each enemy, then looking up again each bullet from that one enemy.
Secondly, instead of writing out custom for loops like you are
for (int j = 0; j < enemies.Count; j++) {
Enemies e = enemies[j];
consider simply doing
//same thing
foreach (var e in enemies) {
Also, please be sure when performing update logic on those bullets to delete any bullets that go out of bounds or hit other objects. There are lots of ways to optimize when objects can be destroyed and which objects you need to check for collision. Collision checks should generally be performed against as little objects as you can get away with, because they are one of the slower things you need to do in a game. Althoguh simple rectangle intersections are pretty fast, so maybe no need to worry about optimizing that part yet.
Upvotes: 3