Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Collision detection between two sprites in different classes  (Read 3053 times)

0 Members and 1 Guest are viewing this topic.

Portalboat

  • Newbie
  • *
  • Posts: 9
    • View Profile
Collision detection between two sprites in different classes
« on: February 08, 2011, 05:25:21 am »
Right now what my program does is this:
It creates and renders a Player sprite, a Bullet sprite, and a Centipede sprite. The Bullet and Player sprite are in one class, and the Centipede sprite in a different class. The Bullet sprite is 'parented' to the Player sprite: When it moves, the Bullet moves too.
When I press spacebar, the bullet sprite changes color and moves until it reaches the top of the screen. When it does, it changes it's color back to white, and continues following the Player sprite. However, when the Bullet sprite touches the Centipede sprite, (It's X coordinate is greater then it's left corner, but less then it's right corner, etc.) I want the Centipede sprite to disappear to show it's been hit.
What would be the best way to do this? (The player has a reference of the Centipede instance, so I can just call a function)
Do I remove the entire instance of the Centipede class using the delete command, or just the sprite? Do I just set the color of the sprite to black?

Walker

  • Full Member
  • ***
  • Posts: 181
    • View Profile
Collision detection between two sprites in different classes
« Reply #1 on: February 08, 2011, 07:24:33 am »
There is some simple collision detection code in the wiki, which takes two sprites. This is suitable for your application. There are many alternatives though. You have pretty much stated the simple logic required for your own simple collision detection ("It's X coordinate is greater then it's left corner, but less then it's right corner, etc."). This logic can be worked into a series of if statements very easily.

As for deleting the centipede... It really depends on what your game is meant to do. If the game ends when you hit the centipede, I would destroy the instance and quit, though perhaps you can just let it fall out of scope -- It really depends on your specific application. Perhaps if a new one appears, you could reuse the same instance. It's a very broad question.

XDest

  • Newbie
  • *
  • Posts: 8
    • View Profile
Collision detection between two sprites in different classes
« Reply #2 on: February 08, 2011, 11:00:23 pm »
First, I suggest the Bullet being a different class. And that the Player/Centipede/Bullet be derived from the same base class.

Then, I believe the easiest way in SFML to do bounding box detection is just to use Rect.Intersects(Rect). Then you can always get the Rect from one of your player classes like this:

Code: [Select]
FloatRect Entity::myRect() {
   return sprite.GetPosition().x,
          sprite.GetPosition().y,
          sprite.GetSize().x,
          sprite.GetSize().y,
}

bool Entity::Collides(Entity *e) {
   return myRect().Intersects(e->myRect());
}


If the Bullet, Centipede, and Player are all derived from Entity, it becomes really easy to track this. And you can always the hitboxes smaller/larger that way by just overloading the myRect() function.

For "deleting" the Centipede, I would flag it as dead, or set an "alive" bool to false. Then something in my Game class (or whoever has the instance) would come collect and destroy it. This way if you want to have multiple centipedes later on, you can just iterate through them in that function and see if any of them are dead yet.

Code: [Select]
void Game::Collision() {
   if (centipede) {
      if (p1->Collides(centipede))
         centipede->Kill(); // Kill() would just set alive to false.
   }
}

void Game::Recycle() {
   if (centipede) {
      if (!centipede->Alive()) { // Alive() would just be a getter of the alive status.
         delete centipede;
         centipede=NULL;
      }
   }
}


If you wanted something to happen first while the Centipede is dying, you could store a separate bool for alive and dead possibly. And then when alive is false and dead is false, do an animation, or fade it out, etc... until a certain point. Then when it reaches that certain point, set dead to true. Then the game can check if that dead bool is true, and come to delete it.

Then, you just stop calling the Centipede's functions when the centipede pointer is NULL, to prevent any dereferencing errors. For example:

Code: [Select]
if (centipede) centipede->Draw();

As the previous poster said, it's a pretty broad question, and there's several ways to go about it. If I had a little more information, I could probably help you out more.