画面を眺めててもゲームにはならないよ。画面タッチしたいんだけど!
前回までで画像を表示できるようになりましたが、コレではまだゲームとは言えませんね。
今回と次回で、ボールをタップしたら好きな角度で動かせるようにしてみましょう。
ボール移動の仕様
ボール移動操作の大きな仕様は以下の3つです。
- ボールをタップすると矢印画像を表示する。
- そのままタップを移動することで、矢印画像を360度回転できる。
- タップを離すとボールが指定された角度で移動する。矢印画像は削除する。
まずアプリがタップを検知できるようになるために、前準備として以下のプログラムを記述しておく必要があります。
HelloWorldScene.h
// touch virtual bool onTouchBegan(cocos2d::Touch* pTouch, cocos2d::Event* pEvent); virtual void onTouchEnded(cocos2d::Touch* pTouch, cocos2d::Event* pEvent); virtual void onTouchMoved(cocos2d::Touch* pTouch, cocos2d::Event* pEvent);
HelloWorldScene.cpp HelloWorld::init
// タップイベントを取得する auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this); listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this); this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
・「onTouchBegan」
cocos2dxのメソッドで、タップした瞬間に1回だけ実行されます。
・「onTouchMoved」
cocos2dxのメソッドで、タップして移動している最中に何回も実行されます。
・「onTouchEnded」
cocos2dxのメソッドで、タップを離した瞬間に1回だけ実行されます。
これらはイベントリスナーと呼ばれるものです。お決まりのプログラムなので、今回のような単純なタップイベントを取得する際は毎回コピペして使用できます。
上記を記述したらタップ処理の下準備は完了です。タップに反応するプログラムを記述していきましょう。
1.タップすると矢印画像を表示する。
それではプログラムを記述していきましょう。
HelloWorldScene.h
// キャラクター関連 cocos2d::Sprite* _ball; // プレイヤーが操作するボール cocos2d::Sprite* _allow; // ボールの侵攻方向を表す矢印画像 float _degree = .0; // ボールの進行方向のための角度 // ドロップ接触、プレイヤー攻撃関連 float getDegree(cocos2d::Vec2 o, cocos2d::Vec2 t); // 2点間の角度を取得する
また、resourcesに矢印の画像を追加してください。
第2回でHelloWorld::init内に記述したボール変数を以下のように変更してください。(ハイライト部分)
HelloWorldScene.cpp HelloWorld::init
// プレイヤー(ボール) _ball = Sprite::create("ball.png"); _ball->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2)); this->addChild(_ball, 1, 0);
ボール変数を変更する理由ですが、複数のメソッドで利用するためにクラス変数としたいからです。
HelloWorldScene.cpp HelloWorld::onTouchBegan
bool HelloWorld::onTouchBegan(Touch* pTouch, Event* pEvent){ // タップした座標を取得 Vec2 touchPoint = convertTouchToNodeSpace(pTouch); // タップした座標がボール画像の中に入っているかどうかを判断 if(_ball->boundingBox().containsPoint(touchPoint)){ // タップした座標とボール画像の座標の二点間の角度の取得 _degree = getDegree(_ball->getPosition(), touchPoint); // 矢印オブジェクトの角度を設定 _allow = Sprite::create("allow.png"); _allow->setPosition(Vec2(_ball->getPosition().x, _ball->getPosition().y)); _allow->setRotation(_degree); this->addChild(_allow, 0, 7); return true; } return false; }
それではonTouchBegan内のプログラムを解説してきます。
1.タップした座標を取得
この1行でタップポイント(X座標、Y座標)を取得します。
2. タップポイントがボール画像内であるかどうかの判定
ボールにタップしたら矢印画像を出したいので、タップした座標がボールないにあれば処理を続行します。
・boundingBox().containsPoint()
cocos2dxのメソッドで、引数に座標を入れることでオブジェクト内にポイントが存在するかどうかを判定します。
3.角度の取得
・getDegree
自作のメソッドです。説明は後述します。
4.矢印オブジェクトの角度を設定して画像表示
画像表示自体は第2話で行ったやり方同じです。ただし、setRotation()で画像を回転させています。
・setRotation
cocos2dxのメソッドで、設定した角度分画像を回転させます。他にも画像に色々なアクションを起こすためのメソッドが用意されています。
角度の取得
角度の取得については上記のとおり、getDegreeメソッドで行います。下記のgetDegreeメソッドを追記してください。
HelloWorldScene.cpp HelloWorld::getDegree
float HelloWorld::getDegree(Vec2 o, Vec2 t){ float radian; radian = ccpToAngle(ccpSub(o, t));// 角度をRADIANで取得 float degree = CC_RADIANS_TO_DEGREES(radian); degree *= -1; degree -= 180; return degree; }
・ccpToAngle
cocos2dxのメソッドで、二点間の角度をRADIANで取得します。
・CC_RADIANS_TO_DEGREES
cocos2dxのマクロで、RADIAN角度をDEGREE角度に変更します。
「cppToAngle」、「CC_RADIANS_TO_DEGREES」で角度を取得できますが、予め用意した矢印画像に対して適切な角度に調整したかったため、このgetDegreeメソッドを用意しました。
2.そのままタップを移動することで、矢印画像を360度回転できる。
続いて、下記プログラムを追記しましょう。
HelloWorldScene.cpp HelloWorld::onTouchMoved
void HelloWorld::onTouchMoved(Touch* pTouch, Event* pEvent){ Vec2 touchPoint = convertTouchToNodeSpace(pTouch); // 角度の再取得 _degree = getDegree(_ball->getPosition(), touchPoint); // 矢印オブジェクトの角度を更新 _allow->setRotation(_degree); }
1.角度の再取得
移動した先のタップポイントでgetDegreeを使用し、角度を更新します。
2.矢印オブジェクトの角度を更新
再びsetRotationで画像の角度を更新します。
タップを離すとボールが指定された角度で移動する。矢印画像は削除する。
ここでは矢印画像の削除処理のみを追加しましょう。ボールの移動は次章で行います。
下記のプログラムを追記してください。
HelloWorldScene.cpp HelloWorld::onTouchEnded
void HelloWorld::onTouchEnded(Touch* pTouch, Event* pEvent){ if(_allow != nullptr){ _allow->removeFromParent(); _allow = nullptr; } }
・removeFromParent()
cocos2dxのメソッドで、表示済みの画像を消すことができます。
ただし、タップを離すたびにこのメソッドを実行してしまうと二重、三重に画像を消そうとしてしまうので、_allowインスタンスが存在している場合のみ消すようにしておきます。
シミュレータの起動
ここまででいつものようにシミュレータを起動してみましょう。プログラムの記述ミスがなければビルドが成功してシミュレータが立ち上がるはずです。
うん、タップすると無事矢印が出て、くるくると動かせますよね。
次回へ続きます!
次回