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.
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.
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.
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.
18.226.251.70