がおまる開発ブログ

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

スポンサーサイト

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

Box2Dのジョイントを試す:マウスジョイント編

Box2Dには物体同士をくっつけたりするジョイントという機能があります。
いくつかジョイント機能のうち今回はマウスジョイントをお知らせします。

マウスジョイント
マウスジョイントとはマウスで物体を掴んで、
タッチ位置を起点に物体を振り回したりドラッグしたり出来ます。
結構面白い動きになるので、発想によっては色々と応用が効きそうです。

実際の動きはこんな感じ!


LevelHelperを利用してますが、
cocos2d-xでも利用できるソースですので、ご利用ください!

SpriteHelperを開いて、オブジェクトにBox2Dを付与していきます。
s_20130209_0.png

LevelHelperに配置していきます。
s_20130209_1.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 ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
virtual void ccTouchesMoved(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
virtual void ccTouchesCancelled(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
virtual void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
void update(float dt);

private:
b2World* world;
LevelHelperLoader* lh;

// マウスジョイント変数定義
b2MouseJoint* mouseJoint;

// マウスジョイント取得
b2MouseJoint* getMouseJoint(cocos2d::CCPoint p);

// マウス移動処理
void setMouseTarget(CCPoint p);

// マウスジョイント破棄
void setDestroyMouseJoint();


};

#endif // __HELLO_WORLD_H__



HelloWorld::HelloWorld()
{
setTouchEnabled( true );

CCSize s = CCDirector::sharedDirector()->getWinSize();

// 初期化
this->initPhysics();

scheduleUpdate();
}

HelloWorld::~HelloWorld()
{
delete lh;
lh = NULL;

delete world;
world = NULL;

delete m_debugDraw;
}

// 初期処理
void HelloWorld::initPhysics()
{

CCSize s = CCDirector::sharedDirector()->getWinSize();

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);

// マウスジョイント変数初期化
mouseJoint = NULL;
}

// タッチダウン
void HelloWorld::ccTouchesBegan(CCSet* touches, CCEvent* event)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();

//Add a new body/atlas sprite at the touched location
CCSetIterator it;
CCTouch* touch;

for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);

if(!touch)
break;

CCPoint location = touch->getLocationInView();
location = CCDirector::sharedDirector()->convertToGL(location);

// マウスジョイント取得
mouseJoint = this->getMouseJoint(location);
}
}

// タッチ移動時
void HelloWorld::ccTouchesMoved(CCSet* touches, CCEvent* event)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();

//Add a new body/atlas sprite at the touched location
CCSetIterator it;
CCTouch* touch;

for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);

if(!touch)
break;

CCPoint location = touch->getLocationInView();
location = CCDirector::sharedDirector()->convertToGL(location);

if (mouseJoint != NULL) {

// マウスジョイントがあれば、オブジェクト移動させる
this->setMouseTarget(location);

} else {
// 無いのでマウスジョイント取得する
mouseJoint = this->getMouseJoint(location);

}
}
}

// タッチキャンセル時
void HelloWorld::ccTouchesCancelled(CCSet* touches, CCEvent* event)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();

//Add a new body/atlas sprite at the touched location
CCSetIterator it;
CCTouch* touch;

for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);

if(!touch)
break;

// マウスジョイント破棄
this->setDestroyMouseJoint();

}
}


// タッチアップ時
void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();

//Add a new body/atlas sprite at the touched location
CCSetIterator it;
CCTouch* touch;

for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);

if(!touch)
break;

// マウスジョイント破棄
this->setDestroyMouseJoint();

}
}

////////////////////////////////////////////////////////////////////////////////
// マウスジョイント取得
b2MouseJoint* HelloWorld::getMouseJoint(CCPoint p) {
b2Vec2 locationWorld = b2Vec2(p.x/PTM_RATIO, p.y/PTM_RATIO);

// ANIMALタグだけを取得
CCArray* spritesWithTag = lh->spritesWithTag(ANIMAL);
CCObject* data = NULL;
CCARRAY_FOREACH(spritesWithTag, data) {
// スプライト取得
LHSprite* spr = (LHSprite*)data;

// スプライトがタッチされたかどうか?
if (spr->isTouchedAtPoint(p)) {
// スプライトに付与されているBodyを取得
b2Body* b = spr->getBody();
b2MouseJointDef md;
b2BodyDef groundBodyDef;
b2MouseJoint* mouseJoint;
b2Body* groundBody = world->CreateBody(&groundBodyDef);
md.bodyA = groundBody;//ground Body
md.bodyB = b;
md.target = locationWorld;
md.collideConnected = true;
md.maxForce = 1000.0f * b->GetMass();

b->SetAwake(true);

// ジョイント取得
mouseJoint = (b2MouseJoint *)world->CreateJoint(&md);
return mouseJoint;
}

}

return NULL;
}
////////////////////////////////////////////////////////////////////////////////
// マウスジョイント移動処理
void HelloWorld::setMouseTarget(CCPoint p) {
if (mouseJoint) {
mouseJoint->SetTarget(b2Vec2(p.x/PTM_RATIO, p.y/PTM_RATIO));
}
}
////////////////////////////////////////////////////////////////////////////////
// マウスジョイント破棄
void HelloWorld::setDestroyMouseJoint() {
if (mouseJoint) {
world->DestroyJoint(mouseJoint);
mouseJoint = NULL;

}
}

スポンサーサイト

コメント

コメントの投稿


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

トラックバック

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

FC2Ad

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