I want to put coins in my game (collision detection)

Hi all.

I’m making an unlimited runner game with cocos2d-x. My ball is running, everything is ok but I want to put coin groups in my game. My ball will be able to collect coins when it collides with them. But I don’t know how to detect collision in cocos2d-x.

How can I detect collision between sprites?


I have 1 more question. What is the best way for creating coins in game? I mean, sprite array or something else? Because coin sprites will exist in groups, not single. But I will detect collision one by one (separate for each coin). Is it hard?

Sorry for my bad English. Thanks in advance.

This should work:

if(ball->getBoundingBox().intersectsRect(coin->getBoundingBox())){
    
}

put it in the update function.

You can also use physics to detect collisions:

http://www.cocos2d-x.org/docs/programmers-guide/physics/index.html

Answering the second question it depends. I think an ordinary Sprite should be fine. If you have grouped “packs” of coins, just extract them from the parent before adding to the scene. This should help with collision detection. If you need more performance use object pool.

1 Like

There are lots of examples in cpp-tests for this question and so many others. I would make it a habit of consulting it. Our own engineering team uses this as how we test functionality.

Also as @piotrros mentioned we have docs with examples. A whole new docs system is even coming soon.

1 Like

Do you guys suggest simple way ( intersectsRect() ) or should I use Physics?

for just this simple case use @piotrros advice. Make sure to read the Physics chapter too.

1 Like

If it is a question of 2 round objects, then it is better to use the ball radius and the coin radius to find collisions

if(ball->getPosition().getDistance(coin->getPosition()) <= ballRadius + coinRadius ) {
// your code
}

or faster equivalent (not calling sqrt())

if(ball->getPosition().getDistanceSq(coin->getPosition()) <= (ballRadius + coinRadius) * (ballRadius + coinRadius) ) {
// your code
}
1 Like

But there will be tons of round coins in my game.

So?

By 2 round objects I meant the ball and any coin.

You can speed up collision checking if you will first look for coins closest to the ball.

Suppose this is a vertical runner. If you store pointers to your coins in a vector. Then

for(auto coin : coins) {
    if(std::abs(ball->getPositionY() - (coin->getPositionY())) <= ballRadius + coinRadius)
        if(ball->getPosition().getDistanceSq(coin->getPosition()) <= (ballRadius + coinRadius) * (ballRadius + coinRadius) ) {
            // your code
        }
}
  • Note

This will work if the coins and the ball belong to the same parent, if not then you need to convert the coordinates yourself, or just use convertToWorldSpace().

@Priority10 : It looks like he’s talking about keeping track of all interactable objects that appear on the screen dynamically. It could become a CPU hog if all objects try to check collision.

@mhmtemnacr : One option is to use the intersectsRect (as suggested by piotrros) collision check with only the closest object.

I used to keep a reference of closest object with the main character. All on-screen interactable objects sent a request to register as the closest object at certain intervals, and based on their distance from the main character, the reference of the closest one used to be saved.

However, I’d recommend using Colliders for collision detection instead of all of those nitty-gritty. Colliders are easy to implement and reliable.

I agree that it is better to find closest objects first.

By Colliders do you mean using physics?

This is a horizontal runner but… I think I will use Physics. Because there will be obstacles etc. not only coins. I hope I can learn physics from documentation and use it.

then try this

for(auto coin : coins) {
    if(std::abs(ball->getPositionX() - (coin->getPositionX())) <= ballRadius + coinRadius)
        if(ball->getPosition().getDistanceSq(coin->getPosition()) <= (ballRadius + coinRadius) * (ballRadius + coinRadius) ) {
            // your code
        }
}

I am developing a vertical runner now, even with the fact that my logic of collision checking is more complex (because of the shape of my objects), it still seems faster than using physics.

But using physics is really a simpler way. And this knowledge will be useful to you if you will ever develop something based on physics. :slight_smile:

Of course, comparisions are way faster than physics. It all depends on what you need.

I changed my mind. I will use the simple way (comparison). Because my shapes are not complex, they’re either box or circle. And because I’m too lazy to learn physics.

@piotrros
Initially, I was not so sure, especially with my strange logic. :smile:
But you are right of course.

@mhmtemnacr
Checking the collision between a circle and a rectangle

for(auto rectangle : rectangles) {
    if(std::abs(ball->getPositionX() - (rectangle->getPositionX())) <= ballRadius + rectangleSize / 2)
        if(rectangle->getBoundingBox().intersectsCircle(ball->getPosition(), ballRadius)) {
            // your code
        }
}

Or something like that.

And @piotrros already wrote the code to check the collision between two rectangles.

1 Like

Yes I meant Physics.

I used to think Physics is faster compared to manual checks. Looks like I’ll have to rethink the way my current fast paced game is implemented. Maybe I’ll be able to improve on the FPS.