一、创建物理世界
在cocos2d-x 3.0版本中,封装了方便模拟物理世界操作的一系列physicals类,在这之前一般是将box2d或者chipmunk集成到cocos2d-x中来。而现在,就方便多了,到底多简单?看看就知道。接下来就来实现一个简单的物理世界吧。
二、简单的例子 - hello Physicals world
首先创建一个场景:
PhyScene.h
- #ifndef __PHY_SCENE_H__
- #define __PHY_SCENE_H__
- #include "cocos2d.h"
- using namespace cocos2d;
- class PhySceneDemo:public Layer{
- public:
- virtual bool init();
- static Scene* scene();
- CREATE_FUNC(PhySceneDemo);
- void setPhyWorld(PhysicsWorld *phyworld){this->m_world=phyworld;}
- void PhySceneDemo::onTouchesEnded(const std::vector<Touch*>& touches, Event *event);
- private:
- PhysicsWorld *m_world;
- };
- #endif
PhyScene.cpp
- #include "PhyScene.h"
- Scene* PhySceneDemo::scene(){
- auto scene = Scene::createWithPhysics();
- auto layer = PhySceneDemo::create();
- layer->setPhyWorld(scene->getPhysicsWorld());
- scene->addChild(layer);
- return scene;
- }
- bool PhySceneDemo::init(){
- if(!Layer::init()){
- return false;
- }
- Size visiableSize = Director::getInstance()->getVisibleSize();
- Point point = Director::getInstance()->getVisibleOrigin();
- edge = Sprite::create();
- auto body = PhysicsBody::createEdgeBox(visiableSize,PHYSICSBODY_MATERIAL_DEFAULT,3);
- edge->setPosition(Point(visiableSize.width/2,visiableSize.height/2));
- edge->setPhysicsBody(body);
- this->addChild(edge);
- edge->setTag(0);
- this->setTouchEnabled(true);
- return true;
- }
- void PhySceneDemo::onTouchesEnded(const std::vector<Touch*>& touches, Event *event){
- for(Touch *touch:touches){
- auto location = touch->getLocation();
- Sprite *sprite = Sprite::create("hero_00.png");
- sprite->setPosition(location);
- sprite->setTag(1);
- auto sbody = PhysicsBody::createBox(Size(31,32));
- sprite->setPhysicsBody(sbody);
- this->addChild(sprite);
- }
- }
最后修改AppDelegate.cpp文件,将启动Scene设置成PhySceneDemo:
- auto scene = PhySceneDemo::scene();
- // run
- director->runWithScene(scene);
通过以上代码便完成了具有物理效果的一个物理场景,是不是非常简单,最后看下运行效果,然后我们再解释关键代码的意思。
三、关键代码讲解
相信大家都看到上图的效果了,那么现在来具体讲解下前面程序中,是如何创建一个物理世界的。 首先还是创建了一个场景叫做PhyScene.h的头文件,其中大部分与普通场景的创建类似,比如自带的HelloWorld场景。只不过新增了一个PhysicsWorld *m_world 的私有成员变量和一个void setPhyWorld(PhysicsWorld *phyworld){this->m_world=phyworld;}成员函数。由于PhySceneDemo类其实是一个继承Layer的类,本身是没有PhysicsWorld的,PhysicsWorld是在Scene类中的,上面新增的这两个就是将Scene的PhysicsWorld传递到Layer中,是得Layer具有物理世界的性质。具体传递可以看PhyScene.cpp的scene成员函数的实现,里面有
- layer->setPhyWorld(scene->getPhysicsWorld());
这样,Layer中就有了PhysicsWorld,然后可以让添加到Layer中的Sprite等节点具有物理特效。具体来看init实现中的:
- edge = Sprite::create();
- auto body = PhysicsBody::createEdgeBox(visiableSize,PHYSICSBODY_MATERIAL_DEFAULT,3);
- edge->setPosition(Point(visiableSize.width/2,visiableSize.height/2));
- edge->setPhysicsBody(body);
- this->addChild(edge);
关键创建一个PhysicsBody对象,但是我们看到这里是用createEdgeBox创建的。而后面的onTouchesEnded函数中的又是使用createBox函数创建的,其实还有更多的创建方式。虽然都是返回PhysicsBody对象,但是效果不一样。举例说明前者,我们进入createEdgeBox函数实现可以看到:
- PhysicsBody* body = new PhysicsBody();
- if (body && body->init())
- {
- body->addShape(PhysicsShapeEdgeBox::create(size, material, border, offset));
- body->_dynamic = false;
- body->autorelease();
- return body;
- }
其实在创建PhysicsBody对象的同时,会给他赋予Shape属性和其它一些属性,这里是一个PhysicsShapeEdgeBox,从名称可以看到是一个边缘盒子模型(物理世界的边缘)。最后设置精灵对象的PhysicsBody属性为之前的body对象,这样这个精灵就成为了一个物理世界的精灵。
总结
简单介绍了如何使用texturepacker并在cocos2d-x中创建精灵动画。
##文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
- 原文网址:http://www.cocosk.com/articles/2014⁄6/15/cocos2d-x-3-physicals.html
- 作者:卧雪Sirk