I'm currently working on a game in which a list of enemies is spawned into the level randomly on the x-axis using a list up to the point of the maximum number to spawn (currently set at 10) I have a large portion of the game working however I currently have the problem that the enemies can overlap/stack on top of each other.
What I want is if the collision box of the enemy is intersecting another enemy in the list, for it to no overlap. (if that makes sense) this is the code I have for it so far.
foreach (EnemyClass enemy1 in enemies)
{
if (enemy1.position.X < myPlayer.position.X - 10 && !enemy1.stopMoving)
{
enemy1.position.X += enemy1.amountToMove;
}
if (enemy1.position.X > myPlayer.position.X - 50 && !enemy1.stopMoving)
{
enemy1.position.X -= enemy1.amountToMove;
}
foreach (EnemyClass enemy2 in enemies)
{
if (enemy1 != enemy2 && enemy1.collisionBox.Intersects(enemy2.collisionBox))
{
System.Console.WriteLine("Collision Detected");
}
}
enemy1.collisionX = (int)enemy1.position.X;
enemy1.Update(graphics.GraphicsDevice);
}
Any help would be greatly appreciated.
EDIT: What I missed off was that they technically do collide, however they collide when they are 1000 pixels apart, when the sprite is actually 50 pixels wide.
EDIT: This is the changed collision code..
foreach (EnemyClass enemy in enemies)
{
enemy.collisionX = (int)enemy.position.X;
if (enemy.position.X < myPlayer.position.X - 10 && !enemy.stopMoving)
{
enemy.position.X += enemy.amountToMove;
}
if (enemy.position.X > myPlayer.position.X - 50 && !enemy.stopMoving)
{
enemy.position.X -= enemy.amountToMove;
}
for (int i = 0; i < enemies.Count; i++)
{
for (int j = i + 1; j < enemies.Count; j++)
{
if (enemies[i].collisionBox.Intersects(enemies[i].collisionBox))
{
System.Console.WriteLine("Collision Detected");
}
}
}
enemy.Update(graphics.GraphicsDevice);
}
EDIT: Here is the EnemyClass, which is where the collisionBox is contained:
public EnemyClass(Texture2D newTexture, Vector2 newPosition)
{
texture = newTexture;
position = newPosition;
collisionBox = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
randX = random.Next(1, 3);
speed = new Vector2(randX, 0);
}
public void Update(GraphicsDevice graphics)
{
collisionBox = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
It seems that the collision is being detected before all of the collision boxes have been updated.
My suggestions for how to order things:
foreach (EnemyClass enemy in enemies)
{
if (enemy.position.X < myPlayer.position.X - 10 && !enemy.stopMoving)
{
enemy.position.X += enemy.amountToMove;
}
if (enemy.position.X > myPlayer.position.X - 50 && !enemy.stopMoving)
{
enemy.position.X -= enemy.amountToMove;
}
enemy.Update(graphics.GraphicsDevice);
}
for (int i = 0; i < enemies.Count; i++)
{
for (int j = i + 1; j < enemies.Count; j++)
{
if (enemies[i].collisionBox.Intersects(enemies[j].collisionBox))
{
System.Console.WriteLine("Collision Detected");
}
}
}
The above code also has an advantage in not detecting the same collision twice (i.e. enemy1/enemy2 and enemy2/enemy1).