当前位置 : 主页 > 手机开发 > 其它 >

cocos2dx 物理碰撞

来源:互联网 收集:自由互联 发布时间:2021-06-13
https://www.cnblogs.com/JiaoQing/p/3906780.html 四个响应函数 1 EventListenerPhysicsContact* evContact = EventListenerPhysicsContact::create(); // 创建一个物理世界的碰撞事件 2 evContact-onContactBegin = [](PhysicsContact c

https://www.cnblogs.com/JiaoQing/p/3906780.html

四个响应函数

 1 EventListenerPhysicsContact* evContact = EventListenerPhysicsContact::create();//创建一个物理世界的碰撞事件
 2     evContact->onContactBegin = [](PhysicsContact& contact)
 3     {
 4         CCLOG("Begin!\n");
 5         return true;
 6     };
 7     evContact->onContactPreSolve = [](PhysicsContact& contact,PhysicsContactPreSolve& solve)
 8     {
 9         CCLOG("PreSolve!\n");
10         return true;
11     };
12     evContact->onContactPostSolve = [](PhysicsContact& contact,const PhysicsContactPostSolve& solve)
13     {
14         CCLOG("PostSolve!\n");
15     };
16     evContact->onContactSeperate = [=](PhysicsContact& contact)//该函数在两个碰撞的刚体分离后调用
17     {
18         CCLOG("Seperate!\n");
19         auto bodyA = (Sprite*)(contact.getShapeA()->getBody()->getNode());//两个碰撞刚体相对应的节点之A
20         auto bodyB = (Sprite*)(contact.getShapeB()->getBody()->getNode());//两个相碰撞刚体对应节点之B
21         if(!bodyA||!bodyB)//按理说碰撞发生之后不会发生有一个刚体的节点不存在的情况,但是实际测试时发现bodyA或bodyB有为NULL的情况,因此我们在这里做一个判断排除节点为空的情况
22             return;
23         int tagA = bodyA->getTag();
24         int tagB = bodyB->getTag();
25         if(tagA == 3)
26         {
27             bodyA->removeFromParentAndCleanup(true);
28         }
29         if(tagB == 3)
30         {
31             bodyB->removeFromParentAndCleanup(true);
32         }
33     //    prop->setVisible(true);
34     };
35     _eventDispatcher->addEventListenerWithSceneGraphPriority(evContact,this);//注册碰撞事件

 

 

1:接触测试掩码 ContactTestBitmask(默认值:0xFFFFFFFF)

2:类别掩码 CategoryBitmask (默认值:0x00000000)

3:碰撞掩码 CollisionBitmask (默认值:0xFFFFFFFF)

 

    只有两者的接触测试掩码执行“逻辑与”运算,如果结果为非0值,表明这两个物体会触发碰撞检测事件,

也就是会执行onContactBegin和onContactSeperate函数。

    假设有三个物体(body1、body2、body3),设置接触测试掩码如下:

body1->setContactTestBitmask(0x01)  //0001

body2->setContactTestBitmask(0x03)  //0011

body3->setContactTestBitmask(0x02)  //0010

body1和body2,以及body2和body3是可以触发碰撞检测事件的,会执行会执行onContactBegin和onContactSeperate函数。

而body1和body3是不能的,上面的四个函数也不会执行。

 

   对于类别掩码和碰撞掩码,他们的作用是检测两个物体接触时是否发生“碰撞反应”。“碰撞反应”会表现为一个物体受到另外

物体的碰撞,而改变运动方向。由于两个物体是“刚体”,在碰撞时两个物体不会交叉。

   类别掩码:定义了一个物体所属类别,每一个物体在场景中能被分配到多达32个不同的类别。

   碰撞掩码:当两个物体接触时,改物体的碰撞掩码与另一个物体的类别掩码执行“逻辑与”运算,如果结果为非0值,

该物体能够对另一个物体的碰撞发生反应。会执行onContactPostSolve和onContactSeperate函数(前提是碰撞检测事件会触发,

也就是上面说的ContactTestBitmask进行逻辑与为非0),

 

经测试:

1:ContactTestBitmask逻辑与非0    ContactTestBitmask和ContactTestBitmask逻辑与非0

      上述四个函数均会触发(前提是前两个函数返回都为true),也会产生“碰撞反应”:

2:ContactTestBitmask逻辑与:0    ContactTestBitmask和ContactTestBitmask逻辑与非0

      上述四个函数均不会触发,会产生“碰撞反应”:     

3:ContactTestBitmask逻辑与非0    ContactTestBitmask和ContactTestBitmask逻辑与为0

      上述四个函数均会触发(前提是前两个函数返回都为true),不会产生“碰撞反应”(就是会直接穿过,交叉);

4:ContactTestBitmask逻辑与为0    ContactTestBitmask和ContactTestBitmask逻辑与为0

      上述四个函数均不会触发,不会产生“碰撞反应”(就是会直接穿过,交叉);

网友评论