LevelHelper Cocos2d-x with Box2d(二)处理碰撞事件
1、在各种不同类型的精灵之间注册碰撞
考虑到你的游戏中拥有各种不同类型的精灵,但有时候我们只关心其中某两种类型之间的碰撞。
例如在超级玛丽中,马里奥(Mario)和关卡中的硬币、站点(CheckPoint,不知道咋翻译)、乌龟之间的碰撞。在这种情况下,让我们先来定义碰撞的回调函数吧。
你可以同时定义碰撞前后的回调函数,也可以只定义碰撞前,或者碰撞后。具体得按你游戏中需求来做,代码如下
voidHelloWorld::preCollisionBetweenMarioAndCoin(LHContactInfo*contact){CCLog("PREMario...Coin");}voidHelloWorld::preCollisionBetweenMarioAndTurtle(LHContactInfo*contact){CCLog("Mario...Turtle");}voidHelloWorld::preCollisionBetweenMarioAndCheckpoint(LHContactInfo*contact){CCLog(@"Mario...Checkpoint");}voidHelloWorld::postCollisionBetweenMarioAndCoin(LHContactInfo*contact){CCLog(@"Mario...Coin");}voidHelloWorld::postCollisionBetweenMarioAndTurtle(LHContactInfo*contact){CCLog(@"Mario...Turtle");}voidHelloWorld::postCollisionBetweenMarioAndCheckpoint(LHContactInfo*contact){CCLog(@"Mario...Checkpoint");}
现在定义好了我们所需要的函数,接下来就只要让LevelHelper在碰撞发生的时候去调用它们就行了。首先在我们载入关卡的后面写上以下方法:
//creatingtheobjectsloader->addObjectsToWorld(world,this);...loader->useLevelHelperCollisionHandling();//这个方法是必要的,否则碰撞将不会执行loader->registerPreColisionCallbackBetweenTagA(COIN,MARIO,this,callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndCoin))loader->registerPostColisionCallbackBetweenTagA(COIN,MARIO,this,callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndCoin))loader->registerPreColisionCallbackBetweenTagA(CHECKPOINT,MARIO,this,callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndCheckpoint))loader->registerPostColisionCallbackBetweenTagA(CHECKPOINT,MARIO,this,callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndCheckpoint))loader->registerPreColisionCallbackBetweenTagA(TURTLE,MARIO,this,callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndTurtle))loader->registerPostColisionCallbackBetweenTagA(TURTLE,MARIO,this,callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndTurtle))
在碰撞事件的函数中,会发现有一个参数LHContactInfo* contact,它将返回所有发生碰撞时的信息。
为了获得碰撞的两个物体,可以很简单的通过contact来获得:
voidHelloWorld::preCollisionBetweenMarioAndCoin(LHContactInfo*contact){CCLog("Mario...Coin");b2Body*coin=contact->bodyA;b2Body*mario=contact->bodyB;}
更多可用的信息都在LHContactInfo这个类中,详细可以查看具体的源码。下面我简单描述部分属性:
//获得TagA/TagB属性对应的bodyb2Body*bodyA=contact->bodyA;b2Body*bodyB=contact->bodyB;//获得TagA/TagB属性对应的精灵对象,//如果发生碰撞的是贝塞尔曲线/直线,则返回NULL,所以使用之前需要核查是否为空LHSprite*sprA=contact->spriteA();LHSprite*sprB=contact->spriteB();//Box2dcontactinfo,可以查看源码获得它更多的信息b2Contact*boxContact=contact->contact;//oldmanifoldinfo,只在preCollision有效//如果发生碰撞的body具有Sensor属性,则返回NULL,使用之前需检查constb2Manifold*oldManifold=contact->oldManifold;//碰撞发生时的冲量信息,只在postCollision有效//如果发生碰撞的body具有Sensor属性,则返回NULL,使用之前需检查constb2ContactImpulse*impulse=contact->impulse;
2、静态物体与静态物体, 或者手动移动静态物体与其他类型的物体发生碰撞
在Box2D中,会将静态物体的质量存储为零,静态物体可以让用户手动移动,它速度为零。另外它不会和其他任意类型的物体相互碰撞。
但有时候我们需要检测到静态物体间的相互碰撞。那该怎么做呢?
想象你有一个台阶(platform静态)通过LevelHelper的路径动画上下来回移动;
想象你需要有一个在台阶与玩家之间碰撞发生时的回调函数。
这时,像刚才那样定义的回调函数是不会执行的。
解决方法:
*复制一份platform, 并在LevelHelper中设置为不可见。
*设置新的这个platform属性为:"Is Sensor", "Dynamic", "Is Bullet", "Fixed Rotation",
*设置新的platform tag 与之前的匹配,
*通过距离关节把这两个platform绑定在一块。
现在两个物体就会同时运动,但在游戏中我们看不到新的这个platform,因为它是不可见的。但它却能帮你检测碰撞。帮你处理其他更多的逻辑信息。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。