cocos2d-x 勉強第3回「タップ処理を実装してみる」

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

今回の目標

「スマフォアプリ開発はタップに始まり、タップに終わる」
そんな事を誰かが言ったかは知らないけれど、タップ処理を書けないと何も始まらない!
というわけで、本日の課題は「タップ処理を実装してみる」です。

プロジェクトの作成

まずはプロジェクトを作成します。
プロジェクト名は「study003taptaptap」とでもしておきます。

$ cd path/to/cocos2d-x
$ ./create-multi-platform-projects.py -p study003taptaptap -k jp.co.befool.study003taptaptap -l cpp
New project has been created in this path: /Users/hayabusa/development/hayabusa/cocos2d-x/cocos2d-x/projects/study003taptaptap
Have Fun!

ディレクトリ階層、ファイル群の確認

今までは作成されたデフォルトの状態のものを、iOS向けにビルドしたり、Android向けにビルドしたりしていただけだったのであまり意識していなかったけど、 作成されたファイル群のどこをいじって開発する事になるのか、大ざっぱに把握しておきたいと思います。

  • study003taptaptap/
    • Classes/
      ここにクラスを配置していく(?)
      • AppDelegate.cpp
        起動時における処理や、バックグラウンドに回された時の処理など、アプリの大外枠にあたる部分の処理を担当するクラス
      • AppDelegate.h
        AppDelegateクラスに関する構造を定義しているファイル(?)「@brief」しか目に入らない。ブリーフ!
      • HelloWorldScene.cpp
        AppDelegate::applicationDidFinishLaunching内で生成され、起動されるシーンクラス
      • HelloWorldScene.h
        HelloWorldSceneクラスの構造を定義するファイル(?)こちらにはブリーフはない
    • Resources/
      ここに画像などを配置していく(?)
    • proj.android/
      Android用ビルド関連一式
    • proj.ios_mac/
      iOS用ビルド関連一式
    • proj.linux/
      Linux用ビルド関連一式
    • proj.win32/
      Windows用ビルド関連一式

画像の差し替え

今のままビルドすると、cocos2d-xのマスコットキャラクターが出てくるだけなので、それをミクさんに差し替えてしまいます。
Resources/miku.JK.jpgとして保存します。
やる気でてきたぞ…JK! JK! JK!

Classes/HelloWorldScene.cpp内で、シーンの詳細が記述されています。
さし当たっては下記の部分を変更して、JKミクさんを表示させてあげます。

// add "HelloWorld" splash screen"
// auto sprite = Sprite::create("HelloWorld.png");
auto sprite = Sprite::create("miku.JK.jpg");

no such file

これだけでいけるのかなーと思っていたら、僕の環境ではiOS向けにビルド後、「no such file」的なエラーが発生して困った。
いや、確かにファイルはあるのになーなんて思っていたんだけど、Xcode側のファイルツリーにmiku.JK.jpgが表示されていない…。
Xcodeに明示的にファイルを追加(Menu > File > Add files to “HelloCpp”)することでエラーが解決された。
これは自動でやってくれないのかな。。。

タップ処理の追加

ググるより、cocos2d-xのソースコードを見た方が早いという事が分かりました…。
細かい課程は吹き飛ばして、結果だけを残すとします。

Classes/BFSprite.h

#ifndef __BFSPRITE_H__
#define __BFSPRITE_H__
#include "cocos2d.h"
class BFSprite : public cocos2d::Sprite
{
public:
BFSprite();
cocos2d::Rect getRect();
bool isTapped(cocos2d::Point);
};
#endif // __BFSPRITE_H__

Classes/BFSprite.cpp

#include "BFSprite.h"
USING_NS_CC;
/**
* タップされたかどうか
*
* @param cocos2d::Point point 座標点
* @return boolean
*/
bool BFSprite::isTapped(Point point)
{
Rect rect = this->getRect();
bool tapped = rect.containsPoint(point);
if (tapped) {
log("ok");
} else {
log("ng");
}
return tapped;
}
/**
* Spriteの座標点の範囲を取得
*
* @return cocos2d::Rect
*/
Rect BFSprite::getRect()
{
Point point = this->getPosition();
int w = this->getContentSize().width * this->getScaleX();
int h = this->getContentSize().height * this->getScaleY();
return CCRectMake(point.x - (w / 2), point.y - (h / 2), w, h);
}

Classes/HelloWorldScene.h

class HelloWorld : public cocos2d::Layer
{
// snip...
// タッチ関係のイベント
bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
// snip...
}

Classes/HelloWorldScene.cpp

bool HelloWorld::init()
{
// snip...
// シングルタッチモードにする
this->setTouchMode(kCCTouchesOneByOne);
// タッチを有効にする(内部的にEventDispatcherに登録される)
this->setTouchEnabled(true);
// snip...
// auto sprite = Sprite::create("miku.JK.jpg");
auto sprite = BFSprite::create("miku.JK.jpg");
// snip...
}
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
BFSprite* sprite = (BFSprite*)this->getChildByTag(1);
if (sprite->isTapped(touch->getLocation())) {
CCLOG("miku tapped !! H !");
}
return true;
}

えっち!

次回に向けて

ただ「タップ処理を記述する」というだけで、Spriteの拡張が必要だったりと、思いの外遠い道のりがあって、途中気が遠くなりました…。
cocos2d-xは、まだまだ伸び代のあるプロジェクトだということですかね…!

ところで、c++でfloatをstringにキャストする最も簡単な方法を教えてくれませんかね!

次回は、ドラッグ&ドロップを試してみたいと思います。

ソースコード

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

記事を書くにあたって参考にさせていただいたサイト

感謝です!