chipmunk创建和销毁刚体过程

1.物理空间初始化

CC_ENABLE_CHIPMUNK_INTEGRATION 这个宏要在预编译的时候设置为1,默认已经设置好了,cpSpaceNew 创建一个物理空间,通过cpSpaceAddCollisionHandler设定碰撞的回调函数,同事指定哪两个类型的sprite的可以产生碰撞。


   
   
  1. void GameLayer::initPhysics()
  2. {
  3. #if CC_ENABLE_CHIPMUNK_INTEGRATION
  4. //创建一个物理空间
  5. m_pSpace = cpSpaceNew();
  6. //设定空间的加速度,xy方向都是0,没有重力影响
  7. m_pSpace->gravity = cpv( 0, 0);
  8. CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
  9. m_pWalls[ 0] = cpSegmentShapeNew( m_pSpace->staticBody,
  10. cpv(pEGLView->getVisibleOrigin().x,pEGLView->getVisibleOrigin().y - pEGLView->getVisibleSize().height),
  11. cpv(pEGLView->getVisibleOrigin().x + pEGLView->getVisibleSize().width,
  12. <span> </span>pEGLView->getVisibleOrigin().y - pEGLView->getVisibleSize().height),
  13. 2.0f);
  14. // top
  15. m_pWalls[ 1] = cpSegmentShapeNew( m_pSpace->staticBody,
  16. cpv(pEGLView->getVisibleOrigin().x,pEGLView->getVisibleOrigin().y + pEGLView->getVisibleSize().height * 2),
  17. cpv(pEGLView->getVisibleOrigin().x + pEGLView->getVisibleSize().width,
  18. <span> </span>pEGLView->getVisibleOrigin().y + pEGLView->getVisibleSize().height * 2),
  19. 2.0f);
  20. for( int i= 0;i< 2;i++) {
  21. m_pWalls[i]->e = 1.0f;
  22. m_pWalls[i]->u = 1.0f;
  23. //设定碰撞类型标识
  24. m_pWalls[i]->collision_type=COLLISIONTYPE_WALL;
  25. m_pWalls[i]->group = CP_GROUP_WALL;
  26. //添加墙体到物理空间
  27. cpSpaceAddStaticShape(m_pSpace, m_pWalls[i] );
  28. }
  29. //子弹和敌机 设置碰撞的回调函数 EnemyCollision
  30. cpSpaceAddCollisionHandler(m_pSpace,COLLISIONTYPE_ENEMY,COLLISIONTYPE_BULLET,EnemyCollision, NULL, NULL, NULL, NULL);
  31. // Physics debug layer
  32. // m_pDebugLayer = CCPhysicsDebugNode::create(m_pSpace);
  33. // this->addChild(m_pDebugLayer, Z_PHYSICS_DEBUG);
  34. #endif
  35. }


2.刚体创建过程

cpBodyNew创建刚体,cpPolyShapeNew创建形状,分别通过cpSpaceAddBody和cpSpaceAddShape加入到空间里,body和shape是有关联的,通过shape可以找到对应关联body,但是不能通过body找到对应的shape,没找到对应的关系,哪位知道,麻烦告知。我是通过一个 map记录了他们的对应关系,以便在需要的时候使用,就是sp_sh一个sprite到shape的指针映射。


   
   
  1. bool GameLayer::assembleCPSprite(CCSprite* sprite, CCPoint &pos, cpCollisionType
  2. collision_type, cpGroup group, bool isplane, cpBodyPositionFunc position_func)
  3. {
  4. #if CC_ENABLE_CHIPMUNK_INTEGRATION
  5. CCSize spriteSize=sprite->getContentSize() * sprite->getScale();
  6. int num = 4, length = 0;
  7. if (isplane)
  8. length = spriteSize.width/ 5;
  9. else
  10. length = spriteSize.width/ 3;
  11. cpVect verts[] = {
  12. cpv( 0-length, 0-length),
  13. cpv( 0-length, length),
  14. cpv(length, length),
  15. cpv(length, 0-length),
  16. };
  17. cpBody *body = cpBodyNew( 1.0f, cpMomentForPoly( 1.0f, num, verts, cpvzero));
  18. body->p = cpv(pos.x, pos.y);
  19. body->data = (void *)sprite;
  20. if(position_func)
  21. body->position_func = position_func;
  22. cpSpaceAddBody(m_pSpace, body); //创建刚体
  23. cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero);
  24. shape->e = 0.5f; shape->u = 0.5f;
  25. shape->collision_type=collision_type;
  26. shape->group = group;
  27. shape->data=sprite;
  28. cpSpaceAddShape(m_pSpace, shape);
  29. ((CCPhysicsSprite*)sprite)->setCPBody(body);
  30. #endif
  31. //设置位置一定要在setCPBody(body)之后
  32. sprite->setPosition(pos);
  33. sp_sh.insert(std::make_pair(sprite, shape));
  34. return true;
  35. }

3.回调函数

通过CP_ARBITER_GET_SHAPES获得了两个刚体的shape,然后通过cpSpaceAddPostStepCallback设置回调函数postStepRemove,把shape传进去,这样就能找到对应的body,已经对应的sprite,进行分别消除。。。这个地方如果传入的是 body,就无法找到shape了…


   
   
  1. int GameLayer::EnemyCollision(cpArbiter *arb, cpSpace *space, void *data)
  2. {
  3. #if CC_ENABLE_CHIPMUNK_INTEGRATION
  4. //获取碰撞的shape,a代表用cpSpaceAddCollisionHandler添加碰撞回调时的碰撞对象类型a,b亦然
  5. CP_ARBITER_GET_SHAPES(arb, a, b);
  6. //设置物理空间在结束当前动作时的回调函数,用于安全释放对象,此调用只会在完成当前动作后调用一次
  7. cpSpaceAddPostStepCallback(space,(cpPostStepFunc)postStepRemove,a, NULL);
  8. cpSpaceAddPostStepCallback(space,(cpPostStepFunc)postStepRemove,b, NULL);
  9. #endif
  10. //返回值为false时,碰撞对象会只在初次碰撞时执行回调函数,两个碰撞对象会重叠在一起
  11. return true;
  12. }

4.刚体销毁

销毁要注意顺序,顺序不对,可能会程序崩溃还有并不是什么时候都可以销毁的,一定要在结束当前动作时销毁,不然会有各种锁的问题导致程序崩溃,试试就知道了


   
   
  1. void GameLayer::postStepRemove(cpSpace *space, cpShape *shape, void *unused)
  2. {
  3. CCPhysicsSprite *sprite = (CCPhysicsSprite*)shape->data;
  4. //释放碰撞的对象,这里释放时要注意顺序
  5. //先释放形状
  6. cpSpaceRemoveShape(space, shape);
  7. cpShapeFree(shape);
  8. //释放刚体
  9. cpSpaceRemoveBody(space, sprite->getCPBody());
  10. cpBodyFree(sprite->getCPBody());
  11. //移除精灵
  12. sprite->removeFromParentAndCleanup( true);
  13. sp_sh.erase(sprite);
  14. }


            </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值