いくつかジョイント機能のうち今回はマウスジョイントをお知らせします。
マウスジョイント
マウスジョイントとはマウスで物体を掴んで、
タッチ位置を起点に物体を振り回したりドラッグしたり出来ます。
結構面白い動きになるので、発想によっては色々と応用が効きそうです。
実際の動きはこんな感じ!
LevelHelperを利用してますが、
cocos2d-xでも利用できるソースですので、ご利用ください!
SpriteHelperを開いて、オブジェクトにBox2Dを付与していきます。

LevelHelperに配置していきます。

続いて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;
}
}
スポンサーサイト