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

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

今回の目標

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

プロジェクトの流用

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

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

まずは画像を小さく

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

Classes/HelloWorldScene.cpp@diff

1
2
3
  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におけるタッチイベントに関してググると、下記のようなサンプルが目立つ。

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

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

さて本題

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

Classes/HelloWorldScene.h@diff

1
2
3
4
  // タッチ関係のイベント
  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 に下記の記述を追加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * タップ開始後、移動するとコールされる
 *
 * @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://www.youtube.com/watch?v=xT1_tZDYx2k

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

次回に向けて

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

ソースコード

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