[Cocos2d-x 3.0] Physics 基本設定

[Cocos2d-x 3.0] Physics 基本設定

大家都知道 Cocos2d-x 3.0 特別在物理引擎這塊做了一些整合

 

在 Box2D 和 Chipmunk 的上層做了一個新類別「Physics」來做承接

 

加快關於使用物理的開發

 

使用者可以透過改變參數來決定下層是要使用 Box2D 還是 Chipmunk

 

但目前 Cocos2d-x 3.0 的版本(Beta)底層還是只有 Chipmunk

 

box2D 還沒有引入

 

不過還是介紹在 Windows 底下如何更改參數

 

官方文件裡有寫到

 

只要將「CC_ENABLE_CHIPMUNK_INTEGRATION = 1」

 

改成「CC_ENABLE_BOX2D_INTEGRATION = 1」即可

 

但你可能在 VIsual Studio 2012/2013 裡面搜尋整個方案還是找不到這串巨集是定義在哪

 

image

 

在專案底下「按右鍵」選擇「屬性」

 

image

在「C/C++」層的「前置處理器」中找到「前置處理器定義」

 

並將紅色框標記起來的「CC_ENABLE_CHIPMUNK_INTEGRATION = 1」改成

 

「CC_ENABLE_BOX2D_INTEGRATION = 1」即可

 

只是在目前 Cocos2d-x 3.0(Beta)的版本改了也沒用

 

底層還是以「Chipmunk」來實作

 


 

b2World 改為 PhysicsWorld

 

要建立一個物理世界

 

b2World 是不可或缺的

 

所有的物理運作都得加在它上面才能運行

 

因為在每個場景中,我們得自己宣告一個 b2World

 

並定義它的重力和其他參數

 

而在新版的物理引擎中則使用的是「PhysicsWorld」

 

而且我們不需要去特別宣告它或定義它參數

 

而是在建立「Scene」的時候就要決定是否使用到「Physics」

 

一旦決定使用後,系統(Scene)會自動產生一個「PhysicsWorld」

 

我們只要去取用即可

 

class PhysicsMain : public cocos2d::Layer
{
public:
    static Scene* createScene();

    virtual bool init();

    CREATE_FUNC(PhysicsMain);

private:
    PhysicsWorld* m_World;

    void SetPhysicsWorld(PhysicsWorld* _world){ this->m_World = _world; }

 

為了在取用的時候指定方便

 

我們特別宣告一個函式「SetPhysicsWorld」

 

並將得到的 PhyscisWorld 指定給成員變數 m_World

 

Scene* PhysicsMain::createScene()
{
    auto scene = Scene::createWithPhysics();
    //auto scene = Scene::create();
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_NONE);

    auto layer = PhysicsMain::create();
    layer->SetPhysicsWorld(scene->getPhysicsWorld());
    scene->addChild(layer);

    return scene;
}

 

而在建立 Scene 的時候

 

如果要建立一個有物理世界的場景

 

則我們得使用「createWithPhysics()」的靜態函式

 

若沒有要使用,則就如以前一樣,使用「create()」即可

 

而「setDebugDrawMask」的函式可以選擇是否要顯示 Debug 的線

 

也就是我們以前得用 b2DebugDraw 來實作的功能

 

現在也只要用這一行指定就可以了

 

即使不使用任何的圖片,我們還是可以看到物理環境的運作

 

最後在從 scene 中取得我們的「PhysicsWorld」即可

 


 

 

Sprite 和 Physics 的綁定

 

在以前使用 Box2D 的時候

 

我們得定義一個「b2BodyDef」

 

並將「userData」指定為某個「Sprite」

 

而且我們得在「update」函式中

 

根據目前物件(b2Body)的位置來更新 userData(Sprite)的位移和旋轉

 

auto sprite = Sprite::create("sprite.png");
b2CircleShape *circle = new b2CircleShape();
circle->m_radius = 5 / 64;
b2FixtureDef fd;
fd.density = 3;
fd.friction = 0;
fd.restitution = 0;
fd.shape = circle;
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x / 64, p.y / 64);
bodyDef.userData = sprite;
b2Body *particleBody = this->m_World->CreateBody(&bodyDef);
particleBody->CreateFixture(&fd);

 

在 update 的函式中

this->m_World->Step(1 / 60, 8, 1);
for (b2Body* bd = this->m_World->GetBodyList(); bd; bd->GetNext())
{
    if (bd->GetUserData() != NULL)
    {
        Sprite *w = (Sprite*) bd->GetUserData();
        w->setPosition(Point(bd->GetPosition().x * 64, bd->GetPosition().y * 64));
        w->setRotation(-1 * CC_RADIANS_TO_DEGREES(bd->GetAngle()));
    }
}

 

 

在新版 Physics 裡

 

Sprite 本身就有「body」的屬性

 

Sprite 也多了一個「setPhysicsBody」的函式

 

可以將定義好的「PhysicsBody」指定給 Sprite

 

這樣一來,我們就可以不需要在「update」函式中更新 Sprite 的位置和旋轉了

 

auto sprite = Sprite::create("sprite.png");
auto material = PhysicsMaterial::PhysicsMaterial(10, 0.0f, 0.1f);
auto spriteBody = PhysicsBody::createCircle(4, material, Point::ZERO);
sprite->setPosition(p);
sprite->setPhysicsBody(spriteBody);
this->addChild(sprite);

 

當在初始化的時候

 

只要宣告好 Sprite 和 PhysicsBody

 

透過 Sprite 的 「setPhysicsBody」函式,將 PhysicsBody 指定進去

 

Sprite 就會有 Body 的屬性

 

不需要在 update 中去更新 Sprite 的位置和旋轉

 

若你還是想在 update 中取得每個物件

 

也可以透過下列程式碼中取得

 

Vector<PhysicsBody*>::const_iterator d = this->m_World->getAllBodies().begin();
for (; d != this->m_World->getAllBodies().end(); d++)
{
    PhysicsBody *body = (*d);
    Sprite *sprite = ((Sprite*)(*d)->getNode());
}
原文链接:http://kw0006667.wordpress.com/2014/02/14/cocos2d-x-3-0-physics-基本設定/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值