-(void)beginEndCollisionBetweenMarioAndCoin:(LHContactInfo*)contact{
if([contact contactType])
NSLog(@"Mario ... Coin begin contact");
else
NSLog(@"Mario ... Coin end contact");
}
-(void)beginEndCollisionBetweenMarioAndTurtle:(LHContactInfo*)contact{
if([contact contactType])
NSLog(@"Mario ... Turtle begin contact");
else
NSLog(@"Mario ... Turtle end contact");
}
-(void)beginEndCollisionBetweenMarioAndCheckpoint:(LHContactInfo*)contact{
if([contact contactType])
NSLog(@"Mario ... Checkpoint begin contact");
else
NSLog(@"Mario ... Checkpoint end contact");
}
-(void)preCollisionBetweenMarioAndCoin:(LHContactInfo*)contact{
NSLog(@"Mario ... Coin");
}
-(void)preCollisionBetweenMarioAndTurtle:(LHContactInfo*)contact{
NSLog(@"Mario ... Turtle");
}
-(void)preCollisionBetweenMarioAndCheckpoint:(LHContactInfo*)contact{
NSLog(@"Mario ... Checkpoint");
}
-(void)postCollisionBetweenMarioAndCoin:(LHContactInfo*)contact{
NSLog(@"Mario ... Coin");
}
-(void)postCollisionBetweenMarioAndTurtle:(LHContactInfo*)contact{
NSLog(@"Mario ... Turtle");
}
-(void)postCollisionBetweenMarioAndCheckpoint:(LHContactInfo*)contact{
NSLog(@"Mario ... Checkpoint");
}
Now that we have defined our functions that will perform the actions we need, lets
instruct LevelHelper to call the apropriate action when a collion occurs.
So after we have loaded our level we do:
//creating the objects
[lh addObjectsToWorld:world cocos2dLayer:self];
...
[lh useLevelHelperCollisionHandling];//necessary or else collision in LevelHelper will not be performed
[lh registerBeginOrEndColisionCallbackBetweenTagA:COIN
andTagB:MARIO
idListener:self
selListener:@selector(beginEndCollisionBetweenMarioAndCoin:)];
[lh registerBeginOrEndColisionCallbackBetweenTagA:CHECKPOINT
andTagB:MARIO
idListener:self
selListener:@selector(beginEndCollisionBetweenMarioAndCheckpoint:)];
[lh registerBeginOrEndColisionCallbackBetweenTagA:TURTLE
andTagB:MARIO
idListener:self
selListener:@selector(beginEndCollisionBetweenMarioAndTurtle:)];
[lh registerPreColisionCallbackBetweenTagA:COIN
andTagB:MARIO
idListener:self
selListener:@selector(preCollisionBetweenMarioAndCoin:)];
[lh registerPostColisionCallbackBetweenTagA:COIN
andTagB:MARIO
idListener:self
selListener:@selector(postCollisionBetweenMarioAndCoin:)];
[lh registerPreColisionCallbackBetweenTagA:CHECKPOINT
andTagB:MARIO
idListener:self
selListener:@selector(preCollisionBetweenMarioAndCheckpoint:)];
[lh registerPostColisionCallbackBetweenTagA:CHECKPOINT
andTagB:MARIO
idListener:self
selListener:@selector(postCollisionBetweenMarioAndCheckpoint:)];
[lh registerPreColisionCallbackBetweenTagA:TURTLE
andTagB:MARIO
idListener:self
selListener:@selector(preCollisionBetweenMarioAndTurtle:)];
[lh registerPostColisionCallbackBetweenTagA:TURTLE
andTagB:MARIO
idListener:self
selListener:@selector(postCollisionBetweenMarioAndTurtle:)];
In the collision handling functions the argument "contact" will return the info about the collision.
-(void)preCollisionBetweenMarioAndCoin:(LHContactInfo*)contact{
NSLog(@"Mario ... Coin");
b2Body* coin = [contact bodyA];
b2Body* mario= [contact bodyB];
}
More info is available in the LHContactInfo class.
LHSprite* sprA = [contact spriteA]; | Sprite with Tag A. Use this to get the exact LHSprite* which has the tag A. |
LHSprite* sprB = [contact spriteB]; | Sprite with Tag B. Use this to get the exact LHSprite* which has the tag B. |
[contact contactType]; | In the case of beginEnd callback this will tell what kind of contact this is.
Returns the following values: 1 if its begin contact 0 if its end contact -1 if its pre solve contact -2 if its post solve contact A better aproach is to use the LH_CONTACT_TYPE enum that contains the following definition
enum LH_CONTACT_TYPE
{
LH_BEGIN_CONTACT = 1,
LH_END_CONTACT = 0,
LH_PRE_SOLVE_CONTACT = -1,
LH_POST_SOLVE_CONTACT = -2
};
e.g
if(LH_BEGIN_CONTACT == [contact contactType])
{
NSLog(@"Contact between objects has just begin");
}
|
b2Body* bodyA = [contact bodyA]; | Body with Tag A. Use this to get the exact body which has the tag A. |
b2Body* bodyB = [contact bodyB]; | Body with Tag B. Use this to get the exact body which has the tag B. |
b2Contact* boxContact = [contact contact]; | The Box2d contact info - Look inside this class to find get all the info. |
b2Contact* boxContact = [contact contact]; | The Box2d contact info - Look inside this class to get all the info. |
const b2Manifold* oldManifold = [contact oldManifold]; | old manifold info. Available only at pre collision. Can be NULL if one of the body in the current contact is Sensor. Check for NULL before using this. Get the current manifold info from the b2Contact class. |
const b2ContactImpulse* impulse = [contact impulse]; | the impulse info of the contact. Available only at post collision. Can be NULL if one of the body in the current contact is Sensor. Check for NULL before using this. |
-(void)beginEndCollisionBetweenMarioAndCoin:(LHContactInfo*)contact{
if(LH_END_CONTACT == [contact contactType])
{
[loader markSpriteForRemoval:[info spriteA]];
}
}
IMPORTANT NOTE:
-(void) tick: (ccTime) dt
{
...
//Iterate over the bodies in the physics world
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL)
{
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite *myActor = (CCSprite*)b->GetUserData();
if(myActor != 0)
{
//THIS IS VERY IMPORTANT - GETTING THE POSITION FROM BOX2D TO COCOS2D
myActor.position = [LevelHelperLoader metersToPoints:b->GetPosition()];
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
.....
[lh removeMarkedSprites]; //this will remove the sprites
}