cocos2d-x タッチイベント取得
概要
- タッチイベントを取得してゲーム中で使用する
参考
- タッチイベント関連のリファレンス(ccTouchで検索)
ブランチ「develop/multi-scene-stack」をベースにする
- 前回サンプルに追加実装した
タッチイベントコールバックをオーバーライド
- cocos2d-xのクラスリファレンスを見るとタッチイベント用関数の仮想関数があるのでそれをアプリ用ヘッダでも宣言する
void registerWithTouchDispatcher(); bool ccTouchBegan( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent ); void ccTouchEnded( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent );
タッチイベント実装
- cpp側でオーバーライドした関数の実装を行う
- http://dummyimage.com/ で画像つくってボタンを押したら画像がかわるようにする
- CCSpriteのオブジェクトをメンバ変数で保持してるようにしているが省略
bool Title::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { this->mSprite->initWithFile("background_touch_began.png"); return true; } void Title::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { this->mSprite->initWithFile("background_touch_end.png"); }
タッチイベントをとるオブジェクトの設定
- イベントを検出するオブジェクトとして設定する必要がある
- タッチイベントを処理するオブジェクトを設定する必要があるが公式のリファレンスの呼び方ができなくなってる
- priorityが設定できるがサンプルのままの値を設定したらCCMenuのボタンがイベントをとれなくなったので注意
- CCMenuはデフォルトではpriorityが-128で設定されるようだが、これより大きい数を設定したらCCMenuが優先されるようになった
void Title::registerWithTouchDispatcher() { //CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-129,true); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-127,true); }
タッチイベントの有効化
- デフォルトでも有効かもしれないが一応initの中で呼んどく
// enable touch event this->setTouchEnabled(true);
動かす
cocos2d-x 別シーンに行って元のシーンに戻る
概要
- 前回のサンプルでは切り替えたら前のシーンには戻れなかったが、ポップアップメニューや設定画面など、完了したら元の画面に戻りたい画面を作る
前回のリポジトリから続ける
scene切り替え処理を変更する
- TitleSceneのreplaceSceneは完全にシーンを置き換える処理だったが、pushSceneにするとシーンのスタックに積まれる
TitleScene.cpp
void Title::menuChangeScene(CCObject *pSender) { //CCDirector::sharedDirector()->replaceScene( HelloWorld::scene()); CCDirector::sharedDirector()->pushScene(HelloWorld::scene()); }
前のシーンに戻る
- 子として作ったHelloWorldから前のTitleSceneに戻る処理を作る
- とりあえず終了ボタンを押した時の処理を戻る機能にして確認してみる
HelloWorld.cpp
void HelloWorld::menuCloseCallback(CCObject* pSender) { /* CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif */ CCDirector::sharedDirector()->popScene(); }
前のシーンに戻るボタンを作る
- 終了ボタンは元の処理に戻して、専用ボタンを作る
- ボタンを作った時の記事を参考にする
cocos2d-xでシーンを切り替える
概要
- タイトル、ゲームメニュー、ゲームのように複数シーンの時の切り替え処理を作る
シーンクラス追加
- 新規でシーンクラスを作る
- メニューと選択物は下記画像参照
背景画像用意
- タイトルシーン用背景を作成してプロジェクトに追加
- TitleSceneで読み込んでる背景画像名を変更する
TitleScene.cpp
// add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("title_back.png");
起動時のシーンをタイトルシーンにする
- AppDelegate.cppのrunWithSceneの引数をTItleSceneのオブジェクトにする
AppDelegate.cpp
// create a scene. it's an autorelease object CCScene *pScene = Title::scene();
- とりあえずここまでで動かす
タイトルシーンから次のシーンに行くボタンをつける
- とりあえずなんかボタン押したらcocos2d-xの画面が出るようにする
- ボタン作成とコールバックはHelloWorldから持ってくる
TitleScene.h
// a selector callback void menuChangeScene(CCObject* pSender);
TitleScene.cpp:ボタン作成
///////////////////////////// // 2. add a menu item with change scene CCMenuItemImage *pChangeSceneItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(Title::menuChangeScene) ); pChangeSceneItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) ); // create menu, it's an autorelease object CCMenu* pMenu = CCMenu::create(pChangeSceneItem, NULL); pMenu->setPosition( CCPointZero ); this->addChild(pMenu, 1);
TitleScene.cpp:ボタンのコールバック
void Title::menuChangeScene(CCObject *pSender) { CCDirector::sharedDirector()->replaceScene( HelloWorld::scene()); }
動かす
- 最初にタイトルが出てボタンを押すとcocos2d-xのマスコットの画面が出る
cocos2d-xで画像を動かす
追記
- githubにサンプルプロジェクト作成
- https://github.com/kambayashia/cocos2d-x-game/tree/develop/move-sprite
画像配置コード確認
- 今までのサンプルでも参考にしているHelloWorldの全画面に出ている画像をどう出しているか確認する
- コードは前回ボタンを追加したコードにそのまま追加。なのでボタン2つでてる
// add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("HelloWorld.png"); // position the sprite on the center of the screen pSprite->setPosition( ccp(size.width/2, size.height/2) ); // add the sprite as a child to this layer this->addChild(pSprite, 0);
左右に揺らしてみる
- 正弦の値を使って揺らす
追加するメンバ
- ひと揺れの中のフレーム番号(ループ変数)
- 動かす画像オブジェクト
- 定期的に呼び出される関数
class HelloWorld : public cocos2d::CCLayer { private: cocos2d::CCLabelTTF *mLabel; // ボタンを押したときにテキストを変更するラベル int mLoopCount; // ひと揺れの中のフレーム番号 cocos2d::CCSprite *mSprite; // 動かす画像オブジェクト public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // new callback function void menuTextChangeCallback(CCObject *pSender); // move sprite logic void gameLogic(); // implement the "static node()" method manually LAYER_CREATE_FUNC(HelloWorld); };
画像オブジェクト保存
// add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("HelloWorld.png"); this->mSprite = pSprite; // 画像オブジェクトを保存
毎フレーム座標更新
- チュートリアルを参考に定期的に呼び出されるメソッドの準備をする
this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 / 60.0 ); return true; }
- 画像移動処理実装
- 久しぶりに書いたら三角関数忘れてたのでコード汚いけどこんな感じ
void HelloWorld::gameLogic() { float x = 0; CCSize size = CCDirector::sharedDirector()->getWinSize(); const float PI = 3.1415f; int max_loop_count = 60 * 1; float cos_value = cosf(PI * ((float)this->mLoopCount++ / (float)max_loop_count)); x = (float)size.width * cos_value; if( this->mLoopCount > (max_loop_count * 2) ) { this->mLoopCount = 0; } this->mSprite->setPosition( ccp( x + size.width / 2, size.height / 2) ); }
画面
- 静止画だけど左右に揺れてる
cocos2d-xでボタンを作る
ボタン機能を見てみる
- 付属しているサンプルをもとにUIのボタンを追加してみる。
- HelloWorld.cppの中を見るとこんな感じでボタンを作っている。
///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback) ); pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );
画面中の右下の丸いのがこのボタンで押すとmenuCloseCallbackが呼ばれてアプリが終了する。
このボタンの上に表示されるようにボタンを追加してみる。
コード追加
- 元のボタン作成コードのすぐ下で変数名、コールバック名、座標をかえたコードを入れる。
- CCMenuのオブジェクトを作ったあとにaddChildでボタンをメニューに追加する。
- CCLabelTTFで作成しているテキストラベルはあとで変更できるようにメンバ変数として保存する
- まだこの段階ではコールバック関数がなくてエラーで動かない
///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback) ); pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) ); CCMenuItemImage *pTextChangeItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuTextChangeCallback) ); pTextChangeItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 40) ); // create menu, it's an autorelease object CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->addChild(pTextChangeItem, 1); pMenu->setPosition( CCPointZero ); this->addChild(pMenu, 1); ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Thonburi", 34); this->mLabel = pLabel;
ヘッダ編集
- ラベルを保存する変数をメンバに追加
- コールバックで呼ばれる関数を追加
class HelloWorld : public cocos2d::CCLayer { private: cocos2d::CCLabelTTF *mLabel; // ボタンを押したときにテキストを変更するラベル public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // new callback function void menuTextChageCallback(CCObject *pSender); // implement the "static node()" method manually LAYER_CREATE_FUNC(HelloWorld); };
コールバック関数の実装追加
- cppにもどりコールバック関数を実装する
void HelloWorld::menuTextChangeCallback(CCObject* pSender) { this->mLabel->setString("Pressed"); }
画面
- ボタンが表示されて押すと画面上部のテキストが変わった