Cocos2dx 3.x box2dを使用してカメラをフォローさせる

raharu(仮名)(プログラマー)
これがダイバージェンス1%の先の世界か。。。

なんか横スクロールっぽい物を作成したいなと思って前々回位に
Cocos2dx 3.0 物理演算を試してみる
という記事を書いたのですが、Cocos2dx 3.xで追加されたこの方法では

setPhysicsBodyしたNodeにカメラFollowが出来ない
※2014/5/25日現在

致命的じゃないか!詳細は
closed #4150: fix physics position and rotation bug.
と解決策が出そうな出なさそうなというところです。早く直してほしい。。

しかし、Box2d使えば行けるらしいよ?
という情報をTさんから頂き早速やってみました。

まずは準備

【Cocos2d-xで学ぶBox2D超入門第0回】Box2Dを使う準備〜DebugDraw〜
Cocoa部さんの記事でBox2dを使用する為の準備を詳しく書いてくれていました、
DebugDrawを表示出来るところまで作成しましょう。

ボールと床の作成

HelloWorld::init()に以下の記述をします

//画面サイズサイズを取得
windowSize = Director::getInstance()->getWinSize();
//メニューボタンを使う
ball = Sprite::create("CloseSelected.png");
ball->setPosition(Point(windowSize.width / 2, windowSize.height / 2));
addChild(ball);
//ボールの作成
b2BodyDef player_body_def;
player_body_def.type = b2_dynamicBody;
player_body_def.position.Set(ball->getPositionX() / PTM_RATIO, ball->getPositionY() / PTM_RATIO);
b2Body *body = _world->CreateBody(&player_body_def);
b2CircleShape circle;
circle.m_radius = 10.0 / PTM_RATIO;
b2FixtureDef fixtureDef;
fixtureDef.shape = &circle;
fixtureDef.density = 2;
fixtureDef.restitution = 0;
fixtureDef.friction = 0.7;
body->CreateFixture(&fixtureDef);
//ballをセット
body->SetUserData(ball);
//フォローさせる
this->runAction(Follow::create(ball));
//床の作成
b2BodyDef boxBodyDef;
boxBodyDef.position.Set(windowSize.width / 2 / PTM_RATIO, 10 / PTM_RATIO);
b2Body *boxBody = _world->CreateBody(&boxBodyDef);
b2PolygonShape rect;
rect.SetAsBox(200 / PTM_RATIO, 10 / PTM_RATIO);
b2FixtureDef boxFixtureDef;
boxFixtureDef.shape = ▭
boxFixtureDef.density = 0.4;
boxFixtureDef.friction = 0.5;
boxFixtureDef.restitution = 1.0;
boxBody->CreateFixture(&boxFixtureDef);

HelloWorld::updateに同期する処理を追記します

void HelloWorld::update(float delta)
{
_world->Step(delta, 10, 10);
//物理オブジェクトと位置を同期させる
for (b2Body* b = _world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
auto ball = (Sprite*)b->GetUserData();
ball->setPosition( Point( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
ball->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
}
}
}

エミュレートすると床部分とボールが出来ていて、 カメラがバウンドとともに上下するはずです。

次回はTileMapEditorの使い方をやります