cocos2d-x + Box2d 物理体のデバッグ表示

物理体のデバッグ表示です。

今回使用したバージョン

  • Cocos2d-x 3.9

こちらを参考にさせていただきました。
cocos2d-x 3.2 + Box2D iOSでDebugDrawの実行まで - Qiita

動作するサンプルはこちら。 https://github.com/okahiro/Cocos2dxBox2d
(Cocos2d-xのフルプロジェクトなので容量大きいです)

実装
Box2dAndPEScene.hpp

class Box2dAndPEScene : public cocos2d::Layer
{
private:
	b2World *_world;	// 物理ワールド
	GLESDebugDraw *_debugDraw;	// 物理体デバッグ表示
	
	int _blockNo = 0;	// ブロックにつける番号
private:
	Box2dAndPEScene();
	~Box2dAndPEScene();
	
public:
	virtual bool init() override;
	static cocos2d::Scene* createScene();
	CREATE_FUNC(Box2dAndPEScene);
	
	void update(float delta) override;
	
	virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
	
	// ブロックを作成
	void createBlock(int x,int y);
	// 地面を作成
	void createGround();
};

GLESDebugDraw型のプロパティとdrawメソッドを定義します。


Box2dAndPEScene.cpp

Box2dAndPEScene::Box2dAndPEScene() : _world(nullptr),_debugDraw(nullptr)
{
	
}
Box2dAndPEScene::~Box2dAndPEScene()
{
	// b2Worldを解放
	if(_world)
	{
		delete _world;
		_world = nullptr;
		
		CCLOG("b2World has been safely deleted.");
	}
	// GLESDebugDrawを解放
	if(_debugDraw)
	{
		delete _debugDraw;
		_debugDraw = nullptr;
		
		CCLOG("DebugDraw has been safely deleted.");
	}
}

// 初期化
bool Box2dAndPEScene::init()
{
	if ( !Layer::init() )
	{
		return false;
	}
	
	Size winSize = Director::getInstance()->getWinSize();
	
	// 物理設定
	b2Vec2 gravity;
	gravity.Set(0.0f, -25.0f);	// 重力の値は動きを見ながら調整
	
	// World作成
	_world = new b2World(gravity);
	_world->SetAllowSleeping(true);
	_world->SetContinuousPhysics(true);
	
	// DebugDrawを設定
	_debugDraw = new GLESDebugDraw(PTM_RATIO);
	_world->SetDebugDraw(_debugDraw);
	
	uint32 flags = 0;
	flags += b2Draw::e_shapeBit;
	//        flags += b2Draw::e_jointBit;
	//        flags += b2Draw::e_aabbBit;
	flags += b2Draw::e_pairBit;
	//        flags += b2Draw::e_centerOfMassBit;
	this->_debugDraw->SetFlags(flags);

        ...


// デバッグ情報表示
void Box2dAndPEScene::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags) {
	Layer::draw(renderer, transform, flags);
	Director* director = Director::getInstance();
	
	GL::enableVertexAttribs( cocos2d::GL::VERTEX_ATTRIB_FLAG_POSITION );
	director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
	this->_world->DrawDebugData();
	director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

コンストラクタでnullptr初期化、デストラクタで解放します。
initメソッドでオブジェクト生成し、worldに設定します。

描画はdrawメソッドで行います。

注意点として、物理体にSpriteを設定している場合、デバッグ表示がSpriteの裏に隠れてしまいます。
Spriteを非表示にするか、半透明にするなどする必要があります。