cocos2d-x 3.0學習-使用Physicals創建物理世界

一、創建物理世界

在cocos2d-x 3.0版本中,封裝了方便模擬物理世界操作的一系列physicals類,在這之前一般是將box2d或者chipmunk集成到cocos2d-x中來。而現在,就方便多了,到底多簡單?看看就知道。接下來就來實現一個簡單的物理世界吧。

二、簡單的例子 - hello Physicals world

首先創建一個場景:

PhyScene.h

  1. #ifndef __PHY_SCENE_H__
  2. #define __PHY_SCENE_H__
  3.  
  4.  
  5. #include "cocos2d.h"
  6.  
  7. using namespace cocos2d;
  8.  
  9. class PhySceneDemo:public Layer{
  10. public:
  11. virtual bool init();
  12. static Scene* scene();
  13. CREATE_FUNC(PhySceneDemo);
  14. void setPhyWorld(PhysicsWorld *phyworld){this->m_world=phyworld;}
  15. void PhySceneDemo::onTouchesEnded(const std::vector<Touch*>& touches, Event *event);
  16.  
  17. private:
  18. PhysicsWorld *m_world;
  19.  
  20. };
  21.  
  22. #endif

PhyScene.cpp

  1. #include "PhyScene.h"
  2.  
  3. Scene* PhySceneDemo::scene(){
  4. auto scene = Scene::createWithPhysics();
  5. auto layer = PhySceneDemo::create();
  6. layer->setPhyWorld(scene->getPhysicsWorld());
  7. scene->addChild(layer);
  8. return scene;
  9. }
  10.  
  11. bool PhySceneDemo::init(){
  12.  
  13. if(!Layer::init()){
  14. return false;
  15. }
  16.  
  17. Size visiableSize = Director::getInstance()->getVisibleSize();
  18. Point point = Director::getInstance()->getVisibleOrigin();
  19. edge = Sprite::create();
  20.  
  21. auto body = PhysicsBody::createEdgeBox(visiableSize,PHYSICSBODY_MATERIAL_DEFAULT,3);
  22. edge->setPosition(Point(visiableSize.width/2,visiableSize.height/2));
  23. edge->setPhysicsBody(body);
  24. this->addChild(edge);
  25. edge->setTag(0);
  26. this->setTouchEnabled(true);
  27.  
  28. return true;
  29. }
  30.  
  31. void PhySceneDemo::onTouchesEnded(const std::vector<Touch*>& touches, Event *event){
  32. for(Touch *touch:touches){
  33. auto location = touch->getLocation();
  34. Sprite *sprite = Sprite::create("hero_00.png");
  35. sprite->setPosition(location);
  36. sprite->setTag(1);
  37. auto sbody = PhysicsBody::createBox(Size(31,32));
  38. sprite->setPhysicsBody(sbody);
  39.  
  40. this->addChild(sprite);
  41. }
  42.  
  43. }

最後修改AppDelegate.cpp文件,將啓動Scene設置成PhySceneDemo:

  1. auto scene = PhySceneDemo::scene();
  2. // run
  3. 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成員函數的實現,裏面有

  1. layer->setPhyWorld(scene->getPhysicsWorld());

這樣,Layer中就有了PhysicsWorld,然後可以讓添加到Layer中的Sprite等節點具有物理特效。具體來看init實現中的:

  1. edge = Sprite::create();
  2. auto body = PhysicsBody::createEdgeBox(visiableSize,PHYSICSBODY_MATERIAL_DEFAULT,3);
  3. edge->setPosition(Point(visiableSize.width/2,visiableSize.height/2));
  4. edge->setPhysicsBody(body);
  5. this->addChild(edge);

關鍵創建一個PhysicsBody對象,但是我們看到這裏是用createEdgeBox創建的。而後面的onTouchesEnded函數中的又是使用createBox函數創建的,其實還有更多的創建方式。雖然都是返回PhysicsBody對象,但是效果不一樣。舉例說明前者,我們進入createEdgeBox函數實現可以看到:

  1. PhysicsBody* body = new PhysicsBody();
  2. if (body && body->init())
  3. {
  4. body->addShape(PhysicsShapeEdgeBox::create(size, material, border, offset));
  5. body->_dynamic = false;
  6. body->autorelease();
  7. return body;
  8. }

其實在創建PhysicsBody對象的同時,會給他賦予Shape屬性和其它一些屬性,這裏是一個PhysicsShapeEdgeBox,從名稱可以看到是一個邊緣盒子模型(物理世界的邊緣)。最後設置精靈對象的PhysicsBody屬性爲之前的body對象,這樣這個精靈就成爲了一個物理世界的精靈。

總結

簡單介紹瞭如何使用texturepacker並在cocos2d-x中創建精靈動畫。

##文檔信息

 2014-06-15 11:50:00

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章