Windowsソフト、iPhoneアプリ、ゲーム音楽素材の「Meteoric Stream」 -> 資料室 -> Cocos2d-x -> 【Cocos2d-x】シングルタッチ、スワイプ、マウスクリック、マウスドラッグの実装方法

【Cocos2d-x】シングルタッチ、スワイプ、マウスクリック、マウスドラッグの実装方法

Cocos2d-xで、タッチ、またはマウスのイベントを取得する方法です。まずは、シングルタッチ、もしくはマウスクリックの場合です。

auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [this](cocos2d::Touch* touch, cocos2d::Event* event)->bool{
Point p = touch->getLocation();
auto r = label1->getBoundingBox();
if(r.containsPoint(p)){
// label1がクリック/タッチされた場合の処理
}
r = label2->getBoundingBox();
if(r.containsPoint(p)){
// label2がクリック/タッチされた場合の処理
}
r = label3->getBoundingBox();
if(r.containsPoint(p)){
// label3がクリック/タッチされた場合の処理
}
return true;
};
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

上記のように、onTouchBeganのイベントリスナー処理を、ひとつのクラスに対して一つのみ作成します。その中で、各ラベルやスプライトの座標と、クリック/タップされた座標を比較し、座標が範囲内であれば、個別の処理を行う、という具合です。
ちなみに、onTouchBeganを、onTouchEndedに変更すれば、タップが終了/クリックが終了した時にイベントを走らせる事ができます。
場合によっては、そっちの方が実用的かもしれませんね。

次に、スワイプの方法です。下記の方法では、指一本でのスワイプでも、マウスのクリックして移動してマウスを離す、という動作でも同じ処理を行う事が出来ます。考え方によっては、ドラッグアンドドロップにも応用できると思います。

// イベントリスナーの生成
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [this](cocos2d::Touch* touch,cocos2d::Event* event)->bool{
GameMain::touchStart(touch);
// スワイプが始まった時に呼び出すメソッドの例
return true;
};
listener->onTouchMoved = [this](cocos2d::Touch* touch,cocos2d::Event* event)->bool{
GameMain::touchMove(touch);
// スワイプの移動が行われた時に呼び出すメソッドの例
return true;
};
listener->onTouchEnded = [this](cocos2d::Touch* touch,cocos2d::Event* event)->bool{
GameMain::touchEnd(touch);
// スワイプが終わった時に呼び出すメソッドの例
return true;
};
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

上記のような感じで、イベントリスナーを登録しておき、あとは、各メソッドを作成して、個別の処理を記述すればオッケーです。例えば、下記のような感じになります。

#define SWIPE_LEFT 1
#define SWIPE_RIGHT 3
#define SWIPE_DOWN 2
#define SWIPE_UP 4
#define SWIPE_CENTER 0
Point touchStartPoint; // タッチの最初の座標
Point touchEndPoint; // タッチの終わりの座標
int swipeRotate; // スワイプの方向
void GameMain::touchStart(cocos2d::Touch* touch){
auto loc = touch->getLocation();
touchStartPoint = Point(loc.x, loc.y);
touchEndPoint = Point(loc.x, loc.y);
swipeRotate = SWIPE_CENTER;
}
void GameMain::touchMove(cocos2d::Touch* touch){
auto offset = 6;
auto loc = touch->getLocation();
auto start = touchStartPoint;
auto end = touchEndPoint;
if(loc.x < start.x - offset){
swipeRotate = SWIPE_LEFT; // left
}else{
if(loc.x > start.x + offset){
swipeRotate = SWIPE_RIGHT; // right
}
}
if(swipeRotate == SWIPE_CENTER || (swipeRotate != SWIPE_CENTER && std::abs(loc.x - start.x) < std::abs(loc.y - start.y))){
if(loc.y < start.y - offset){
swipeRotate = SWIPE_DOWN; // down
}
if(loc.y > start.y + offset){
swipeRotate = SWIPE_UP; // up
}
}
}
void GameMain::touchEnd(cocos2d::Touch* touch){
// ここで初めて、スワイプ時の処理を行う
GameMain::onSwipe(swipeRotate, touchStartPoint.x, touchStartPoint.y);
// 座標の初期化
touchStartPoint = touchEndPoint = Point(-9999, -9999);
}
void GameMain::onTouch(int rotate, int x, int y){
Rect r = label1->getBoundingBox();
if(r.containsPoint(Point(x, y))){
if(swipeRotate == SWIPE_UP){
// label1に対して上スワイプされたときの処理を記述
}
if(swipeRotate == SWIPE_RIGHT){
// label1に対して右スワイプされたときの処理を記述
}
if(swipeRotate == SWIPE_LEFT){
// label1に対して左スワイプされたときの処理を記述
}
if(swipeRotate == SWIPE_RIGHT){
// label1に対して右スワイプされたときの処理を記述
}
}
}

この記事の最終更新日:2017/12/05
最初に記事を書いた日:2017/12/05

この記事をシェアする

このエントリーをはてなブックマークに追加

関連記事

Meteoric Streamについて

管理人

Windowsソフト、iPhoneアプリ、ゲーム音楽素材の「Meteoric Stream」 -> 資料室 -> Cocos2d-x -> 【Cocos2d-x】シングルタッチ、スワイプ、マウスクリック、マウスドラッグの実装方法