一、創建物理世界
在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