Handling collisions in Chipmunk

It's relatively easy to handle collisions within Cocos2d when using Chipmunk (as is pretty much everything else in Cocos2d). That is why so many developers use Cocos2d. To do so, we need to do a few different steps so that Cocos2d can properly detect and handle our collisions.

Setting the collision delegate

The delegate pattern is a common way to handle messages sent by a class to any of its potential parent classes. For example, if you want to use UITableView (which is the standard table in UIKit), you must set the delegate of the table view to the class you're adding it to so that when the table view tries to refresh the data in the table, it knows which class' methods to call.

That being said, we need to tell MainScene that it will be a delegate for our collision handler, so open up MainScene.h and add CCPhysicsCollisionDelegate to the @interface line. This will allow the CCPhysicsNode object to set collision detection events on our MainScene class:

@interface MainScene : CCScene <CCPhysicsCollisionDelegate>

Then open MainScene.m, and in the init method, set the world object's collision delegate to self, like this:

world.collisionDelegate = self;

Recall that world is our CCPhysicsNode object, so any collision detection events that happen within that world (or simulation) will need to be sent somewhere to be handled further. We're setting it to self because self refers to the current MainScene instance (our currently running scene). Finally, this helps us determine which objects collide with other objects. Without this line of code, we wouldn't be able to see in the code when two objects collide, let alone tell which objects they actually are.

Although this doesn't do anything directly if you run the game now, it properly sets up your physics simulation to be able to detect and handle collisions.

Setting collision tags on game objects

Before we can create the method that will detect our collisions, we need to specify which objects will be colliding with one another. For now, we'll only be considering squares colliding with other squares.

Therefore, in the touchBegan method of the MainScene.m file, add the following line of code so that the collision detection delegate knows what object is colliding:

squareBody.collisionType = @"square";

You can do this with any physics body, but for now, this is our only object. With that in place, let's add the code to detect the actual collision between two squares.

Detecting collision

The way Chipmunk handles collisions in Cocos2d is by detecting all collisions and sending method calls to the respective functions for each collision type. So, since we're going to be detecting the collision between two squares, both parameters have to be named square. Otherwise, the method won't get called properly. The actual names of the variables of the parameters (firstSquare and secondSquare) don't matter for the sake of detection.

So, anywhere in MainScene.m, add the following method:

-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair square:(CCNode *)firstSquare square:(CCNode *)secondSquare
{
  NSLog(@"squares collided!");
  return YES;
}

If you run the game at this point, you should see the squares collided! text being printed to the console output every time a square collides with another. If it doesn't, go back and make sure you add everything correctly. From here onwards, you can do whatever you want when the two objects collide, as you have a pointer to both objects as well as their types.

As another example, suppose we want to detect collisions between the squares and a wall; it's very easy. First, add wall as collisionType to the body in the addWallWithRect method:

wallBody.collisionType = @"wall";

Then, add the method to detect square-wall collisions (notice the name change in the parameter from the previous collisionBegan method we added):

-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair square:(CCNode *)nodeA wall:(CCNode *)nodeB
{
  NSLog(@"square-wall collision!");
  return YES;
}

If you run the game at this point and spawn a square, as soon as it hits a wall, you should see the output being printed. And that's it for detecting collisions! Just set the collisionDelegate property, set the collisionType property, and add the collision methods.

What if you want to detect collisions on objects, but don't want them to be bouncing with other objects? In Chipmunk, you can do that.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.251.70