Most simple way to detect collisions

I am wondering what is the most simple way to detect a collision between two objects? say a bullet and a target which are just plain sprites?
is it something to do with CCRectMake when you make the sprite and then checking for collisions with the scheduler? and what happens when there is multiple versions of the same sprite and i only want to remove the one that had the collision?
All help is greatly appreciated!

1 Like

you can just iterate over your sprite array and check if bounding box of the target sprites and and bullet intersects. If it intersects that means they collide. Something like the following code.

for(unsigned int i = 0; i < targetSpriteArray~~>size; i++)
{
//where targetSpriteArray is CCArray which contains your target sprites and bulletSprite is the sprite of your bullet
CCSprite* targetSprite = targetSpriteArray~~>objectAtIndex(i);
CCRect targetRect = targetSprite~~>boundingBox;
CCRect bulletRect = bulletSprite~~>boundingBox();
if(bulletRect.intersectsRect(targetRect))
{
// collided
// here you can remove targetSprite from your layer or scene
}
}

Hope it will help you.

Try using box2d, see http://www.gmtdev.com/blog/2011/08/19/how-to-use-box2d-for-just-collision-detection-with-cocos2d-x/

here you go , check simplegame example in the source tree
http://www.cocos2d-x.org/wiki/Chapter_5_-_How_to_Detect_the_Collisions

Hello, is there any simple way to check collision between sprites that have different parent?
let’s say Sprite A has child named Sprite B, and Sprite C has child named Sprite D, is there any simple way to check collision between Sprite B and Sprite D?

Thank you,

guys you better use a physics engine if you’re going to check collisions of a lot of sprites unless there are only 2 esp. if your character is compose of different bounding boxes with all the parents and child composition. Box2d is relatively simple and you’ll be inform of the collisions. It’s not over kill even on the simplest game bec. you’ll never know what features you’ll add in the future so better ready.
This is the best box2d tuts i’ve ever read so far, it even surpass books about the subject.
http://www.iforce2d.net/b2dtut/
I think the author even ans. some questions here.

@newstar55a Thank You for Your reply, I’ll check this tutorial.

another simple and fast collision detection is to use circles instead of bounding box, this is faster than bounding box, and might be more accurate for some type of games

simply give every object a radius, you check the distance between 2 objects, if the distance is less than the 2 radius combined, you have a collision

3 Likes

by the books! :smiley:

I got bounding box for sprite like this
sprite->boundingBox() but how can i get circle for sprite

If you want a radius to check collisions, just get one component of the boundingBox and divide it by 2. If you don’t want to do this calculation every time, you can add a method to Node or Sprite, or if you don’t want to modify classes from Cocos2dx, create a new class that inherits from the one you want to have that method and implement the method in the new class.

A better (more efficient and clear) way is the one Wuhao said:

Just noticed this.
Using circles cannot surely be faster than bounding box as, to calculate the distance between two points requires Sin/Cosine calculation which is surely slower than simple value comparisons?
Or am I missing something?

You don’t need Sin/Cos calculation here. First, look at this. Given two points in space A and B, the distance between is:

That would be:

c = sqrt( (xA-xB)*(xA-xB) + (yA-yB)*(yA-yB) )

But sqrt is a very slow operation, so unless you really need to know the real distance, you’ll probably want to avoid using sqrt for better performance. This is also known as square distance and allows to compare distances without using the slow sqrt operation. It’s useful to check if some object A is nearer to an object X than B, but in a scenario where you don’t care about the exact value of the distance. You only need to remember to compare the value with other squared values. In this case, you’d need to compare it with the addition of the two radiuses:

if ( (xA-xB)*(xA-xB) + (yA-yB)*(yA-yB) < (rA+rB)*(rA+rB) )
    //collision

(A and B are the points representing the center of two circles. rA and rB are the radiuses of each circle).

I hope this makes sense to you and that I didn’t make any mistake!

2 Likes

Excellent - thanks.
Although this is still slower than a bounding box calculation, it is much more reasonable!

1 Like

Why do you think it’s slower than bounding box method? I think it’s not that easy to say which is faster or slower without making real tests. Also, the code I posted is not optimized. I found this article which does a good job at that. Let me quote the conclusion:

[…] looks like bounding boxes are faster when there is no collision, while bounding circles are faster when there is a collision. So it really comes down to the nature of your game. If objects are collision checked often and are usually not colliding (such as a projectile flying through the air), it is probably faster to use bounding box checks.

One last note. If you store the squared radius of each object, instead of calculating it each time, you can speed it up a bit. I haven’t ran that test, though I imagine it could put the distance-based collision back ahead of the bounding box.

So again, I think that if you really need to squeeze the last drop out of performance for your game, the best approach is to test and measure each method in your game. Therefore you can be certain that one is faster than the other for your game.

Also, games with lots of objects that are usually not colliding may benefit from spatial partitioning. With this technique, you only check collisions between objects in the same spatial partition, so depending on the game you can avoid lots of collision checks and save CPU time.

Let us know the results if you do the tests! :wink:

Interesting indeed.
I had assumed slower than bounding box because using an optimal bounding box means you will try two simple value checks (less than or greater than) on average before exiting with the knowledge that no collision has taken place, whereas with a radius check you always have to square two numbers and do one value test.
Which kind of agrees with the conclusions of that article (very useful, by the way!)

Interestingly I did run a couple of (very basic) tests with thousands of random vectors - and the results generally agree with those from the article (i.e. if collisions are rare, bounding box is better) but usually the results aren’t staggeringly different with either method.

In the real world (well, the game world anyway) it honestly looks like this would be a case of premature optimisation in all but the extreme cases.

I use a physics engine to do my collisions for me anyway :wink:

We have a video covering this https://www.youtube.com/watch?v=lJoYwFKBcXU

1 Like

I think you have an error. Shouldn’t it be:

c = sqrt( (xA-xB)*(xA-xB) + (yA-yB)*(yA-yB) )

with a +?

1 Like

My bad! It’s certainly with a + instead of *. I’ll edit the post. Thank you for letting me know!

can this be done with nodes such as these two ?

	auto rectNode1 = DrawNode::create();
	Vec2 rectangle1[4];
	rectangle1[0] = Vec2(-40 / TIscale, -15 / TIscale);
	rectangle1[1] = Vec2(40 / TIscale, -15 / TIscale);
	rectangle1[2] = Vec2(40 / TIscale, 15 / TIscale);
	rectangle1[3] = Vec2(-40 / TIscale, 15 / TIscale);

	Color4F white(1, 1, 1, 0.1);
	rectNode1->drawPolygon(rectangle1, 4, white, 1, white);
	this->addChild(rectNode1);

	auto rectNode2 = DrawNode::create();
	Vec2 rectangle2[4];
	rectangle2[0] = Vec2(-40 / TIscale, -15 / TIscale);
	rectangle2[1] = Vec2(40 / TIscale, -15 / TIscale);
	rectangle2[2] = Vec2(40 / TIscale, 15 / TIscale);
	rectangle2[3] = Vec2(-40 / TIscale, 15 / TIscale);

	Color4F white(1, 1, 1, 0.1);
	rectNode2->drawPolygon(rectangle2, 4, white, 1, white);
	this->addChild(rectNode2);