タッチイベントを利用しよう! (6/6)
作成:2015-06-20 11:24
更新:2015-06-20 11:24
更新:2015-06-20 11:24
■スプライトをタッチするには?
スプライトをマウスでクリックしたり、スマホなどでタッチしたら何かを行う、というのはゲームなどで他用意されるイベント処理ですね。
タッチ関係のイベント処理について簡単に説明しましたが、タッチイベント処理は、基本的に「画面の中の何処かをタッチしたら発生するイベントの処理」でした。ver. 3.0以降では、EventListenerというオブジェクトを作成し、これをEventDispatcherに組み込んで使うようになっていましたね。
このEventListenerによるタッチイベントの処理は、「画面内のどこでもいいからタッチしたらイベントが発生する」というようになっています。例えば、SpriteインスタンスにEventListenerを組み込んだら、そのSpriteをタッチした時だけイベントが発生するか?というと、そうではありません。どのウィジェットに組み込んでも、タッチイベントが発生したらそれらすべてが呼び出されてしまうのです。
従って、普通にタッチイベントのイベントリスナーを用意し、その中で「タッチ地点が、スプライトの領域内かどうか?」を調べて処理するのが一番でしょう。
下に簡単なサンプルを用意しておきました。ここではHelloWorldクラスのヘッダーに以下のフィールド宣言文を用意しておくようにしてください。
実行したら、スプライトをタッチしてみましょう。スプライトが消えてしまいます。スプライト以外のところをクリックしても消えません。スプライトをタッチした時だけ処理が実行されていることがわかるでしょう。
ここでは、onTouchBeganに組み込んでいるラムダ式の部分で、タッチ時の処理をしています。行っている処理を簡単に整理しましょう。
●タッチした位置を取得する
●Spriteの領域を得る
●PointがRect内にあるかチェックする
結果がtrueだった場合には、スプライトを非表示にしています。
●スプライトの表示をON/OFFする
――これらがひと通りわかれば、スプライトをタッチして処理できるようになります。位置と大きさの構造体(Rect、Point)をしっかり理解しておきましょう。
タッチ関係のイベント処理について簡単に説明しましたが、タッチイベント処理は、基本的に「画面の中の何処かをタッチしたら発生するイベントの処理」でした。ver. 3.0以降では、EventListenerというオブジェクトを作成し、これをEventDispatcherに組み込んで使うようになっていましたね。
このEventListenerによるタッチイベントの処理は、「画面内のどこでもいいからタッチしたらイベントが発生する」というようになっています。例えば、SpriteインスタンスにEventListenerを組み込んだら、そのSpriteをタッチした時だけイベントが発生するか?というと、そうではありません。どのウィジェットに組み込んでも、タッチイベントが発生したらそれらすべてが呼び出されてしまうのです。
従って、普通にタッチイベントのイベントリスナーを用意し、その中で「タッチ地点が、スプライトの領域内かどうか?」を調べて処理するのが一番でしょう。
下に簡単なサンプルを用意しておきました。ここではHelloWorldクラスのヘッダーに以下のフィールド宣言文を用意しておくようにしてください。
cocos2d::Sprite* sprite;
実行したら、スプライトをタッチしてみましょう。スプライトが消えてしまいます。スプライト以外のところをクリックしても消えません。スプライトをタッチした時だけ処理が実行されていることがわかるでしょう。
ここでは、onTouchBeganに組み込んでいるラムダ式の部分で、タッチ時の処理をしています。行っている処理を簡単に整理しましょう。
●タッチした位置を取得する
Point p = touch->getLocation();
引数で渡されるTouchインスタンスの「getLocation」メソッドで、タッチした位置が取り出せます。得られる値は、Point構造体という値になります。●Spriteの領域を得る
Rect r = sprite->boundingBox();
Spriteの領域を「boundingBox」メソッドで取得します。これは、Spriteがぴったりはめ込まれる四角形の領域(位置と大きさ)を取り出すものです。値は、Rect構造体というものの値になります。●PointがRect内にあるかチェックする
if (r.containsPoint(p)) ……
後は、タッチした位置(Point)が、Spriteの領域(Rect)の中にあるかどうかを調べるだけです。これは「containsPoint」というメソッドを使います。これはRectにあるもので、引数のPointが領域内にあるかどうかをチェックします。領域内にあれば、trueを返します。結果がtrueだった場合には、スプライトを非表示にしています。
●スプライトの表示をON/OFFする
sprite->setVisible(false);
Spriteにある「setVisible」は表示・非表示を切り替えるもので、これをfalseにすれば画面に表示されなくなります。――これらがひと通りわかれば、スプライトをタッチして処理できるようになります。位置と大きさの構造体(Rect、Point)をしっかり理解しておきましょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
#pragma execution_character_set("utf-8") #include "HelloWorldScene.h" USING_NS_CC; Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if (!Layer::init()) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); Director::getInstance()->setDisplayStats(false); // stats OFF sprite = Sprite::create("character.png"); sprite->setAnchorPoint(Vec2(0.5, 0.5)); sprite->setPosition(origin.x + 100, origin.y + visibleSize.height / 2); this->addChild(sprite, 1); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [this](cocos2d::Touch* touch, cocos2d::Event* event)->bool { Point p = touch->getLocation(); Rect r = sprite->boundingBox(); if (r.containsPoint(p)) { sprite->setVisible(false); } return true; }; this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); return true; }
※関連コンテンツ
「初心者のためのCocos2d-xゲームプログラミング入門」に戻る