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

Author Topic: Collision detection problem  (Read 2145 times)

0 Members and 1 Guest are viewing this topic.

mapPhil

  • Newbie
  • *
  • Posts: 11
    • View Profile
Collision detection problem
« on: July 15, 2011, 12:36:55 pm »
My frame rate is at 60fps

I wrote this code and sometimes it detects a collision and sometimes it does not.

My ship is meant to collide with mines and crates, but sometimes it will just pass through them, or the mine or crate will just explode before it should.

Any help would be appreciated.


Code: [Select]
bool Collision::HasCollided(sf::Sprite& sprite1, sf::Sprite& sprite2)
{
// this function checks if the two inputted sprites have
// collided using circle collision detection

if(sprite1.GetSize().x > sprite1.GetSize().y)
{
r1 = sprite1.GetSize().x/2;
}
else
{
r1 = sprite1.GetSize().y/2;
}

if(sprite2.GetSize().x > sprite2.GetSize().y)
{
r2 = sprite2.GetSize().x/2;
}
else
{
r2 = sprite2.GetSize().y/2;
}

circle1 = sf::Shape::Circle(0, 0, r1, sf::Color(255,255,255,200));
circle1.SetPosition(sprite1.GetPosition().x, sprite1.GetPosition().y);

circle2 = sf::Shape::Circle(0,0,r2,sf::Color(255,255,255,200));
circle2.SetPosition(sprite2.GetPosition().x, sprite2.GetPosition().y);

distX = circle2.GetPosition().x - circle1.GetPosition().x;
distY = circle2.GetPosition().y - circle1.GetPosition().y;

distance = sqrt((distX*distX)+(distY*distY));
sumOfRadii = r1 + r2;

if(distance <= sumOfRadii)
{
return true;
}
else
{
return false;
}
}

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
Collision detection problem
« Reply #1 on: July 15, 2011, 03:42:11 pm »
Are the objects circles? At least the crate is probably a square or a rectangle.

About the code, you don't need to create a circle object, you can just calculate it directly:
Code: [Select]

bool Collision::HasCollided(sf::Sprite& sprite1, sf::Sprite& sprite2)
{
   // this function checks if the two inputted sprites have
   // collided using circle collision detection

   if(sprite1.GetSize().x > sprite1.GetSize().y)                
   {
      r1 = sprite1.GetSize().x/2;
   }
   else
   {
      r1 = sprite1.GetSize().y/2;
   }

   if(sprite2.GetSize().x > sprite2.GetSize().y)                  
   {
      r2 = sprite2.GetSize().x/2;
   }
   else
   {
      r2 = sprite2.GetSize().y/2;
   }

   distX = sprite2.GetPosition().x - sprite1.GetPosition().x;
   distY = sprite2.GetPosition().y - sprite1.GetPosition().y;

   distance = sqrt((distX*distX)+(distY*distY));
   sumOfRadii = r1 + r2;

   if(distance <= sumOfRadii)                                  
   {
      return true;
   }
   else
   {
      return false;
   }
}

Make sure that your objects are circles (unless you can live with the inaccuracy), and that the actual images are squares not rectangles if possible, otherwise the detection will be off.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Collision detection problem
« Reply #2 on: July 15, 2011, 04:39:35 pm »
Somewhat offtopic, but I felt obligated to chime in because I see people doing this a lot.


Pythagorean Theorum is a*a + b*b = c*c
Somehow people got it in their heads that sqrt(a*a + b*b) = c is a better way to do it.  But really, it's not, because sqrt is expensive.

You're better off sticking with the original theorum unless you need the exact value of c (which, for this collision detection, you don't).

Example of what I mean:

Code: [Select]

   // what you're doing:
   distance = sqrt((distX*distX)+(distY*distY));
   sumOfRadii = r1 + r2;

   return distance <= sumOfRadii;

Code: [Select]

   // what would be better:
   distanceSquared = (distX*distX)+(distY*distY);  // get rid of sqrt
   sumOfRadiiSquared = r1 + r2;
   sumOfRadiiSquared *= sumOfRadiiSquared;  // multiplication is cheaper

   return distanceSquared <= sumOfRadiiSquared;

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Collision detection problem
« Reply #3 on: July 15, 2011, 04:45:28 pm »
By the way, as soon as you use such stuff more often, you should really write an abstraction for vectors (or use an existing one) instead of handling single vector components all the time. Functions like dot product, length and angle simplify vector algebra and 2D geometric calculations a lot, especially when rotation is involved.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: