cocos2d-x 勉強第4回「ドラッグ&ドロップ」

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー SEGAさん、DIVAの筐体ください(ズザー

今回の目標

前回は「Cocos2d-x 勉強第3回「タップ処理を実装してみる」」 でタップした時にログを流すまでを記事にしました。
今回はその延長で、「ドラッグ&ドロップ」に挑戦してみようと思います。
ミクさん画像を、タップしながら移動できるようにするでござるぞー!

プロジェクトの流用

前回の記事で使用したプロジェクトをそのまま流用します。

$ cd path/to/cocos2d-x/projects/study003taptaptap

まずは画像を小さく

今のミクさんの画像サイズでは大きすぎて、ドラッグ&ドロップするにしても移動幅が小さすぎるという問題があるので、 ミクさん画像をもうちょっと小さなサイズに縮めようと思います。

Classes/HelloWorldScene.cpp@diff

auto sprite = BFSprite::create("miku.JK.jpg");
- sprite->setScale(0.5);
+ sprite->setScale(0.2);

こんな感じでサイズを調整しておきます。

ドラッグ&ドロップ組み込み

タッチイベントの再確認

前回使用したonTouchBeganコールバックでしたが、タッチイベント関係のコールバックにどんな種類があるのか再確認しておきたいと思います。

kCCTouchesOneByOneモード(シングルタップ)の際のコールバック

  • onTouchBegan: タップ開始時にコールされる
  • onTouchMoved: タップ開始後、タップポイントが移動されるとコールされる
  • onTouchLongClicked: タップ開始後、長く同じポイントが押されつづけるとコールされる
  • onTouchEnded: タップの正常終了時にコールされる
  • onTouchCancelled: タップが何かしらの理由(システムコールなど)でキャンセルされた際にコールされる

kCCTouchesAllAtOnceモード(マルチタップ)の際のコールバック

  • onTouchesBegan: マルチタップ開始時にコールされる
  • onTouchesMoved: マルチタップ開始後、タップポイントが移動されるとコールされる
  • onTouchesEnded: マルチタップの正常終了時にコールされる
  • onTouchesCancelled: マルチタップが何かしらの理由(システムコールなど)でキャンセルされた際にコールされる

cocos2d-x 3.xと2.x系で大きく違うようなのでメモ

cocos2d-xにおけるタッチイベントに関してググると、下記のようなサンプルが目立つ。

// Classes/HelloWorldScene.h
bool ccTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);

ただ、3.x系ではccTouchBeganがfinal指定されていてオーバーライドができなくなっている。
これはタッチイベントに関して、onTouchBeganのようなコールバック形式に統一するという流れという認識でいいのかな…?

さて本題

こんな感じにドラッグ&ドロップ処理を記載していきました。

Classes/HelloWorldScene.h@diff

// タッチ関係のイベント
bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
+ void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
+ void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);

Classes/HelloWorldScene.cpp に下記の記述を追加

/**
* タップ開始後、移動するとコールされる
*
* @return void
*/
void HelloWorld::onTouchMoved(Touch* touch, Event* event)
{
BFSprite* sprite = (BFSprite*)this->getChildByTag(1);
if (sprite->isTapped(touch->getLocation())) {
sprite->setPosition(touch->getLocation());
}
}
/**
* タップが終了するとコールされる
*
* @return void
*/
void HelloWorld::onTouchEnded(Touch* touch, Event* event)
{
BFSprite* sprite = (BFSprite*)this->getChildByTag(1);
if (sprite->isTapped(touch->getLocation())) {
Point point = touch->getLocation();
sprite->setPositionY(point.y - 10);
}
}

動作イメージ

いい感じじゃないですかね!

次回に向けて

今回は詰まることなくさくっといけました。このまま突き進んでいける手応えありです。ウホッ。
次回は、そうだなー、「サウンドの再生」に関してやってみようかなー!

ソースコード

https://github.com/8823-scholar/cocos2d-x-study/tree/adfecc60407fd283f8e3f79c98105ad773810242/study003taptaptap