好久都没写文章了,就来一篇吧。这个方法是在制作《胖鸟大冒险》时用到的。《胖鸟大冒险》中使用Box2D来进行物理模拟和碰撞检测,因此对每个机关需要创建一个b2body。然后《胖鸟》是根据《超级马里奥兄弟》设计的,所以机关可以是各种运动轨迹的平台,绕圈转的乌龟,蹦蹦跳的乌龟等。如果用box2d来做这些运动的话要自己写这些轨迹。但是Cocos2d-x已经提供了很多的action,自己增加action也很方便。反过来用sprite去设置box2d的b2body的位置就很方便了。
要求:所有的机关都设置为body type为b2_kinematicBody,这个type的好处是可以有速度,但是不会物理模拟,并且可以和type为b2_dynamicBody的body发生碰撞检测。
假设我们用一个重复移动的平台机关为sprPlatform,这个平台重复上下移动,代码如下:
sprPlatform->runAction(CCRepeatForever::create(CCSequence::create(CCMoveBy::create(2, ccp(0, 100)), CCMoveBy::create(2, ccp(0, -100)), NULL)));
void update(float delta) { //更新位置 float angle = getRotation(); CCPoint curPos = getPosition(); b2Vec2 shapeCenter(curPos.x/PTM_RATIO, curPos.y/PTM_RATIO); body->SetTransform(shapeCenter, CC_DEGREES_TO_RADIANS(360-angle) ); //更新速度,这个是为了让机关保持匀速 body->SetLinearVelocity(b2Vec2((curPos.x-lastPos.x)/gPlatformMovingFactor, (curPos.y-lastPos.y)/gPlatformMovingFactor)); lastPos = curPos; }
至于gPlatformMovingFactor,在《胖鸟》里为1.066681。因为b2_kinematicBody只有速度没有质量,所以只能根据某段时间内body移动了多少像素来计算这个数据。总之达到sprite的移动和b2body的移动匹配。b2_kinematicBody如果没有velocity的话,b2_dynamicBody就无法被platform带动。
另外需要注意的是b2body的anchor point是(0.5,0.5),而cocos2dx的sprite可以自己设置,所以需要自己做些简单的转换。
这样b2body就被sprite带动了。