官术网_书友最值得收藏!

9.2 工作流程

這里直接從Box2d自帶的HelloWorld示例開始,從Box2d官網下載的源碼包中可以找到這個例子,這是一個沒有圖形顯示的HelloWorld,正因為如此,呈現的內容更加精簡,后面的內容會介紹怎樣把Box2d的模擬效果顯示在Cocos2d-x上面,現在先把渲染拋到腦后吧。首先需要了解一下最純粹的Box2d。

Box2d的運行流程大致如圖9-1所示,首先是初始化Box2d,然后可以執行各種操作,如創建對象,操作對象、在循環中更新物理世界,Box2d會自動執行碰撞處理,并觸發碰撞監聽。需要注意的是,創建對象等操作不能在碰撞監聽回調中執行。

圖9-1 運作流程

Box2d的物理模擬全部發生在b2World這個類中,其表示整個物理世界,使用Box2d的第一步就是要把b2World創建出來,構造函數很簡單,只有一個參數,表示這個世界的重力加速度,地球的重力加速度是-9.8f,一般可以取近似值-10.0f(月球上的重力為地球的1/6大約為1.63f)。Box2d用b2Vec2來描述一個向量,重力也是一個向量,其結構等于一個Vec2,下面這段代碼創建了一個世界。

        b2Vec2 gravity(0.0f, -9.8f);
        b2World world(gravity);

有了世界之后,需要在世界里面添加各種各樣的對象,這些對象不需要并且不允許使用new來創建,應該直接調用World的Create系列函數,由World來創建。

Box2d中使用了SOA(小對象分配器)來快速有效地使用內存(能夠高效地創建大量50~300字節大小的對象), Box2d每創建一個對象,都需要先填充一個對象的描述結構(這點和PhysX非常相似,這里使用一個b2BodyDef結構來填充描述。

        b2BodyDef groundBodyDef;
        groundBodyDef.position.Set(0.0f, -10.0f);
        b2Body* groundBody = world.CreateBody(&groundBodyDef);

有了一個b2Body對象之后,還需要描述這個對象的形狀,Box2d提供一個b2PolygonShape對象來描述一個多邊形,調用它的SetAsBox()函數傳入寬和高可以得到一個四邊形,調用它的Set()函數傳入一個頂點數組,可以得到一個N邊形,把這個形狀直接設置到b2Body對象中。

        //創建一個寬為50.0f,高為10.0f的四邊形,并設置到groundBody
        b2PolygonShape groundBox;
        groundBox.SetAsBox(50.0f, 10.0f);
        groundBody->CreateFixture(&groundBox, 0.0f);

上面設置了地板的形狀,它的質量為0,默認是一個靜態的物體,靜態的物理在物理世界中不會移動,但在游戲中,還需要創建一些動態的物體。要創建動態剛體的話,需要更多的設置,首先需要設置b2BodyDef的type,默認為b2_staticBody,動態物體需要將它設置為b2_dynamicBody。動態物體的形狀描述也需要更多的內容,如質量、摩擦力……Box2d提供b2FixtureDef結構體來描述這些內容。

        //定義動態Body并創建
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(0.0f, 4.0f);
        b2Body* body = world.CreateBody(&bodyDef);

        //定義另外一個四邊形
        b2PolygonShape dynamicBox;
        dynamicBox.SetAsBox(1.0f, 1.0f);

        //定義動態Body的配置
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &dynamicBox;

        //動態對象的密度不為0
        fixtureDef.density = 1.0f;

        //設置摩擦力
        fixtureDef.friction = 0.3f;

        //將形狀配置到Body
        body->CreateFixture(&fixtureDef);

初始完一個World以及相關的對象之后,需要讓整個世界動起來,這需要調用World對象的Step()方法,其需要幾個參數,第一個是從上一次調用到現在的時間間隔,這個參數可以直接使用Cocos2d-x在Update()函數中傳入的參數。一般情況下,在每一幀的Update()調用一次Step。Box2d當運行比較復雜的運算的時候,需要一定的迭代次數來保證模擬的精度,Step要求傳入兩個迭代次數,即需要傳入速度迭代數和位置迭代數,Box2d給出的默認值是8和3,如果對精度要求比較高,可以適當地增加這兩個值,該值越大,相應地性能越低。velocityIterations表示速度約束的遍歷次數,positionIterations表示位置約束的遍歷次數,可以根據游戲的具體情況來設置這兩個值。

        world.Step(dt, velocityIterations, positionIterations);

在游戲更新的過程中,會不斷地創建新的對象到世界中,也會不斷地刪除一些舊的對象,不管怎樣,在World被析構的時候,這個世界的一切,都會從內存中被釋放。

主站蜘蛛池模板: 岑溪市| 两当县| 综艺| 柳林县| 三都| 腾冲县| 洪湖市| 汽车| 阳山县| 清原| 随州市| 商都县| 平武县| 乌拉特中旗| 太保市| 云安县| 陵川县| 永仁县| 徐州市| 砚山县| 宝山区| 郁南县| 南木林县| 卢氏县| 元阳县| 杭锦后旗| 云浮市| 通江县| 新昌县| 保山市| 饶阳县| 东山县| 惠来县| 廉江市| 河间市| 嘉兴市| 横峰县| 株洲县| 祁阳县| 武定县| 类乌齐县|