がおまる開発ブログ

cocos2d-xやlevelhelperを使って iPhone/Androidアプリの作り方を解説します

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[LevelHelper講座]第9回:Box2dの衝突処理

Box2dにはオブジェクト同士の衝突を検知する事ができます。
LevelHelperにはそのオブジェクト同士の衝突を簡単に検知と処理できる機能があります。

まずは、SpriteHelperでDynamicなBodyを作りましょう
s_20130127_0.png

LevelHelperを開いて、
新しいタグ「GROUND」を追加しましょう
s_20130127_1.png

今回は地面に当たると消したいので、
Bottom Borderにタグを指定してください。
s_20130127_2.png

Xcodeでソースを編集しましょう。
ヘッダーファイルに衝突の初期化と地面衝突時のメソッドを書きます

#include "cocos2d.h"
#include "Box2D.h"
#include "LevelHelperLoader.h"

class HelloWorld : public cocos2d::CCLayer {
public:
~HelloWorld();
HelloWorld();

// returns a Scene that contains the HelloWorld as the only child
static cocos2d::CCScene* scene();

void initPhysics();
virtual void draw();
virtual void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
void update(float dt);

private:
b2World* world;
LevelHelperLoader* lh;

// 衝突処理初期化
void setupCollisionHandling();
// 地面と衝突した時の処理
void groundCollision(LHContactInfo* contact);

};



void HelloWorld::initPhysics()
{

b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
world = new b2World(gravity);

// Do we want to let bodies sleep?
world->SetAllowSleeping(true);
world->SetContinuousPhysics(true);

// LevelHelper初期化
lh = new LevelHelperLoader("GaomarTest.plhs");
LHSettings::sharedInstance()->setLhPtmRatio(PTM_RATIO);
lh->addObjectsToWorld(world, this);

if(lh->hasPhysicBoundaries())
lh->createPhysicBoundaries(world);

if(!lh->isGravityZero())
lh->createGravity(world);

// 衝突処理初期化
this->setupCollisionHandling();


}

////////////////////////////////////////////////////////////////
void HelloWorld::setupCollisionHandling()
{
// 初期化処理これは絶対に要るやつ
lh->useLevelHelperCollisionHandling();

// タグで指定して呼び出すメソッドを指定
lh->registerBeginOrEndCollisionCallbackBetweenTagA(
GROUND,
ANIMAL,
this,
callfuncO_selector(HelloWorld::groundCollision));
}
////////////////////////////////////////////////////////////////
void HelloWorld::groundCollision(LHContactInfo *contact) {
if(LH_BEGIN_CONTACT == contact->contactType ) {

// GROUNDはspriteA()、ANIMALはspriteB()になってるはず
if (contact->spriteB()->getTag() == ANIMAL) {

LHSprite* spr = contact->spriteB();

// 接触したらスプライトを消す
spr->removeSelf();

}
}
}



これで地面にライオンが当たれば、
画像が消えます。
s_20130127_3.png


衝撃度によって処理をかえる
ぶつかった時の衝撃度に応じた処理もあると思います。
Box2dでは計算で求めることも可能です。

先ほどのソースに一部修正を加えます。
衝撃度の計算はそのままコピペすれば使えると思います。

void HelloWorld::groundCollision(LHContactInfo *contact) {
if(LH_BEGIN_CONTACT == contact->contactType ) {
// GROUNDはspriteA()、ANIMALはspriteB()になってるはず
if (contact->spriteB()->getTag() == ANIMAL) {
b2Contact* boxContact = contact->contact;
b2WorldManifold worldManifold;
boxContact->GetWorldManifold(&worldManifold);
b2Vec2 point = worldManifold.points[0];

b2Body* body1 = contact->bodyA;
b2Body* body2 = contact->bodyB;
b2Vec2 vA = body1->GetLinearVelocityFromWorldPoint(point);
b2Vec2 vB = body2->GetLinearVelocityFromWorldPoint(point);
b2Vec2 now = vB-vA;
float32 force = abs(b2Dot(now, worldManifold.normal));

CCLog("force=%f", force);

// 指定した値以上の衝突の場合にだけ消す
if (force >= 10 ) {

LHSprite* spr = contact->spriteB();
spr->removeSelf();

}
}
}
}


衝撃度が取得出来ていると思います。
これを利用して様々な事が出来ますよね。
s_20130127_4.png
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://gaomar.blog.fc2.com/tb.php/26-c2269cc5
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。