首页 > 代码库 > cocos2d-x 3.x 物理碰撞机制
cocos2d-x 3.x 物理碰撞机制
最近又弄了物理引擎,写一下吧,下面有在其他博客学习到的知识,加上自己的理解,总结下。
cocos2d-x 3.X 中全新的封装的物理引擎给了开发者最大的便捷,你不用再繁琐与各种物理引擎的细节,完全的封装让开发者可以更快更好的将物理引擎的机制添加到自己的游戏中,简化的设计是从2.0到3.X的一个质的飞跃。
cocos2d-x 3.0+中的物理属性:
1、物理世界被集成到场景中,当你创建一个场景,你可以直接创建基于物理世界或者不使用物理世界的场景。
2、Node拥有它自己的body属性。(sprite也是node)‘
3、cocos2d-x 3.0 已经封装了物理属性Body(PhysicsBody),Shape(PhysicsShape),Contact(PhysicsContact),Joint(PhysicsJoint)和World(PhysicsWorld),更加方便使用。
4、方便的使用listener-EventListenerPhysicsContact进行碰撞检测。
当然,封装好的物理引擎可以简化开发难度,如果有能力的话也可以直接使用Box2D和Chipmunk的原生的物理引擎进行开发,这样难度会有所提升。
下面的代码创建一个带物理世界的场景,并传递到场景中的层上。
PhysicsLayer.h中
- class PhysicsLayer : public cocos2d::Layer
- {
- ...
- // add following codes设置层中的物理世界
- void setPhyWorld(PhysicsWorld* world){m_world = world;}
- private:
- PhysicsWorld* m_world;
- ...
- }
- Scene* PhysicsLayer::createScene()
- {
- ...
- // add following codes
- auto scene = Scene::createWithPhysics();
- scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);//调试
- auto layer = HelloWorld::create();
- layer->setPhyWorld(scene->getPhysicsWorld());//将创建的物理世界传递到子层中
- scene->addChild(layer);
- return scene;
- }
Scene类有一个新的static工厂方法createWithPhysics()创建一个带物理世界的场景。可以通过getPhysicsWorld()来获取PhysicsWorld的实例。
上述代码中注释为调试的代码在调试中非常有用,它会显示游戏中物体所带有的物理边界,便于观察碰撞中的细节等。
同时一个场景中只能有一个物理世界,所有属于这个场景的子层都共享这一个物理世界,所以在子层中用到物理世界时都会有这个定义的函数
- void setPhyWorld(PhysicsWorld* world){m_world = world;}
PhysicsWorld拥有默认的重力设置,Vector(0.0f,-98.0f),当然你也可以随意设置你想要的重力加速度,setGravity(Vect(0.0f,-200.0f)),设置重力加速度为20米每二次方秒。
创建物理边界
- Size visibleSize = Director::getInstance()->getVisibleSize();
- auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);//设要添加到节点中的物理body ,这个Box是不受碰撞检测的!!!
- auto edgeNode = Node::create();
- edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
- edgeNode->setPhysicsBody(body);//将物理body加入到创建的节点中
- scene->addChild(edgeNode);场景中添加创建的物理节点
创建受重力影响的精灵
- void HelloWorld::addNewSpriteAtPosition(Point p)
- {
- auto sprite = Sprite::create("circle.png");//创建精灵
- sprite->setTag(1);//设置精灵的便签值
- auto body = PhysicsBody::createCircle(sprite->getContentSize().width / 2);//创建一个附加在精灵身体上的圆形物理body
- sprite->setPhysicsBody(body);//将创建的body加到精灵身上
- sprite->setPosition(p);
- this->addChild(sprite);//添加精灵
- }
下面讲一下真正的重点所在——物理碰撞检测
- auto contactListener = EventListenerPhysicsContact::create();
- contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
- CategoryBitmask = 0xFFFFFFFF;
- ContactTestBitmask = 0x00000000;
- CategoryBitmask & ContactTestBitmask = 0,所以不会发送碰撞信号
- CollisionBitmask = 0xFFFFFFFF;
- CategoryBitmask & CollisionBitmask = 0xFFFFFFFF
- 所以物体会碰撞,但是不会响应碰撞回调函数。
cocos2d-x 3.x 物理碰撞机制