原創,轉載請注明出處:http://blog.csdn.net/dawn_moon/article/details/21240343
泰然的跑酷用的chipmunk實體引擎,我沒有仔細學過這個東西。不過我看了一下他們的用法,感覺跟box2d差不多。box2d用純真的面向對象C++開發,用在這裡應該沒有問題,試一下。
泰然的工程沒有加入box2d子產品,是以需要添加。将external/Box2D加入工程,将無用的引用删掉,加入後結構如下
然後建立一個PlayScene類,開始建立實體世界。
為了友善調試box2d實體世界,需要接入debug渲染器,将TestCpp/Classes/Box2DTestBed/下的GLES-Render.h和GLES-Render.cpp加入到工程,這個可以繪制出實體模型的形狀。
因為box2d針對0-10米的仿真做過優化,是以我這裡将像素大小映射到10左右
#define RATIO 32
看下PlayScene.h
//
// PlayScene.h
// Parkour
//
// Created by lerry on 14-3-14.
// Copyright (c) 2014年 Goonear Co.,Ltd. All rights reserved.
//
#ifndef __Parkour__PlayScene__
#define __Parkour__PlayScene__
#include "cocos2d.h"
#include "Box2D.h"
#include "GLES-Render.h"
#define RATIO 32
#define GROUND_HEIGHT 57
#define RUUNER_STARTX 80
class PlayScene : public cocos2d::CCLayer
{
b2World* mWorld;
GLESDebugDraw* mDebugDraw;
private:
// 初始化實體世界
void initPhysics();
// 繪制實體世界debug區域
void draw();
// 開啟實體世界debug
void setDebug(bool isDebug);
public:
virtual bool init();
virtual void update(float dt);
CREATE_FUNC(PlayScene);
static cocos2d::CCScene* scene();
};
#endif /* defined(__Parkour__PlayScene__) */
現在主要有一個初始化實體世界的函數initPhysics()函數,在這裡建立了一個地闆。
void PlayScene::initPhysics()
{
mWorld = new b2World(b2Vec2(0, -10));
mWorld->SetAllowSleeping(true);
mWorld->SetContinuousPhysics(true);
// mWorld->SetContactListener(this);
// 地闆body
b2Body* ground = NULL;
b2BodyDef bd;
ground = mWorld->CreateBody(&bd);
// 地闆
b2EdgeShape shape;
shape.Set(b2Vec2(0, GROUND_HEIGHT / RATIO), b2Vec2(INT_MAX, GROUND_HEIGHT / RATIO));
ground->CreateFixture(&shape, 0.0f);
setDebug(true);
}
這裡建立了一個邊緣形狀,邊緣形狀類似靜态物體,但是它沒有體積。box2d裡面的碰撞算法要求碰撞的兩個物體至少一個要有體積,是以邊緣形狀不能和邊緣形狀碰撞,可以和其他形狀類物體碰撞。
box2d的實體世界有自己的世界循環函數,跟cocos2d-x的update函數類似,是以在update函數裡面調用box2d的疊代函數
void PlayScene::update(float dt)
{
// 實體世界的疊代函數
mWorld->Step(dt, 10, 8);
}
Step函數的參數解釋一下,第一個時間參數,單步疊代步長,第二個參數單步時間内速度疊代次數,第三個參數但不是件内位置疊代次數。這幾個參數有建議值,我這裡就取這幾個值。
然後在MainScene.cpp的onPlay函數裡面填上回調的實作:
// start按鈕回調
void MainScene::onPay()
{
CCLog("onPlay click");
// 建立帶過渡的場景
CCScene* s = CCTransitionFade::create(1, PlayScene::scene());
CCDirector::sharedDirector()->replaceScene(s);
}
這裡加了一個過渡場景,跑起來看到一條線,初步完成。