关于物理引擎,在3.0中有了全新的Physics integration,把chipmunk和Box2D封装到引擎内部,简化开发者的开发步骤。再也不用关心底层具体是用哪个物理引擎,也不用直接调用物理引擎的接口。
物理引擎和cocos2d-x进行了深度融合:
(1) 物理世界被融入到Scene中,即当创建一个场景时,就可以指定这个场景是否使用物理引擎。
(2) Node自带body属性,也就是sprite自带body属性。
(3) Cocos2d-x 3.0对物理引擎的Body(PhysicsBody),Shape(PhysicsShape),Contact(PhysicsContact),Joint (PhysicsJoint),World(PhysicsWorld)进行了封装抽象,使用更 简单。
(4) 更简单的碰撞检测监听EventListenerPhysicsContact。
默认创建的工程已经支持物理引擎,内部默认使用chipmunk。当然,你也可以改为Box2D。但这并不对游戏开发产生影响。
我们来创建一个带物理世界的场景scene,并传递给child layer。
在HelloWorldScene.h中添加如下代码:
private: PhysicsWorld* m_world; public: void setPhyWorld(PhysicsWorld* world){ m_world = world;}
auto scene = Scene::createWithPhysics(); scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); auto layer = HelloWorld::create(); layer->setPhyWorld(scene->getPhysicsWorld());
(2)Scene的getPhysicsWorld()方法用来获取PhysicsWorld实例。
(3)PhysicsWorld的setDebugDrawMask()方法,在调试物理引擎中是很有用的,它把物理世界中不可见的shape,joint,contact可视化。当调试结束,游戏发布的时候,你需要把这个debug开关关闭。
(4)通过setPhyWorld()方法来传递PhysicsWorld给ChildLayer。一个scene只有一个PhysicsWorld,其下的所有layer共用一个PhysicsWorld实例。
我们知道物理世界中,所有物体受重力的影响。
物理引擎提供staticShape创建一个不受重力影响的形状,在Cocos2d-x 2.0中,我们需要了解物理引擎的staticShape相关的各种参数来完成边界设置。
在3.0中,PhysicsShape属于Node的一个属性,要设置PhysicsWorld的属性,都需要通过一个Node实例来中介传达。
下面的代码展示如何创建一个围绕屏幕四周的物理边界。
Size visibleSize = Director::getInstance()->getVisibleSize(); auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3); auto edgeNode = Node::create(); edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2)); edgeNode->setPhysicsBody(body); scene->addChild(edgeNode);
矩形区域大小,这里设置为visibleSize。
设置材质,可选参数,默认为PHYSICSBODY_MATERIAL_DEFAULT。
边线宽度,可选参数,默认为1。
(2)然后我们创建一个Node,把刚才创建的body附加到Node上,并设置好Node的position为屏幕中心点。
(3)最后,把Node添加到scene。
(4)Node的addChild方法,在3.0中,有对物理body做处理,它会自动把node的body设置到scene的PhysicsWorld上去。
(5)PhysicsBody中的工程方法,针对参数设置的body大小,会自动创建对应的PhysicsBody和一个PhysicsShape,这也是通常情况下,直接使用物理引擎创建一个body需 要做的事情。3.0的Physics integration极大的简化了使用物理引擎的代码量
在3.0中创建一个受重力作用的sprite其实不难。示例代码如下:
void HelloWorld::addNewSpriteAtPosition(Point p) { auto sprite = Sprite::create("circle.png"); sprite->setTag(1); auto body = PhysicsBody::createCircle(sprite->getContentSize().width / 2); sprite->setPhysicsBody(body); sprite->setPosition(p); this->addChild(sprite); }
cocos2d-x中,事件派发机制做了重构,所有事件均有事件派发器统一管理。物理引擎的碰撞事件也不例外,
下面的代码注册碰撞begin回调函数。
auto contactListener = EventListenerPhysicsContact::create(); contactListener->onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
注明:本篇文章参考自泰然网