2014/04/12 ・SE関連(sharedEngine→getInstance) に追記しました。
前回は、cocos2d-x ver3.0betaのインストールと実行までについて記載致しました。
今回は、これまでの経験者向けに以前のバージョンのプロジェクト(ver2系)をver3系に移植する上でしたことを書いていこうと思います。
ということで、経験者向けの記事になります。ご了承くださいです。
新しく前回作ったプロジェクトに、これまでのClassやResourcesを入れ替える・・・だけでは、どうも動かないようです。
ということで、ちょびちょびと直していこう思います。
その他、ver3系ではC++11準拠になったことから、便利な機能の追加や、変更された点などもあります。
そのあたりも一緒に書いていこうかと思っております。
とりあえず羅列していきましたが、他にも気づいたら追加していこうと思います。
なお、あくまで私がやったことなので、「これが正しいか」はまた別問題。そのあたりもご了承ください。
その他、
cocos2d-xに最初から入っているサンプルは、大いに参考になるのではないかと思いまする。
目次:
・基本
・schedule
・CCArray→Vector
・子を走査する
・CCCallFunc→CallFunc(さらに新たにラムダ式に)
・タッチイベント(ccTouch→onTouch)
・BGM関連(sharedEngine→getInstance)
・SE関連(sharedEngine→getInstance)
おそらくそのままビルドしてみると、いーっぱい警告マークがつくと思います。
それもそのはず。
cocos2d-x 3.0ではこれまで使ってきた [CCなんたら](例:CCSprite)が非推奨になりました。
新しくなった命令を知りたい際には、
古い命令の上で、commandキーを押しながらクリックすると、
このように新くなった命令を教えてくれます。この場合だとCCSprite→Spriteになりました。
このあたりは、まとめて正規表現付きのGREPなどで置き換えてもいいかもしれません。
ちなみに、なんでCCが消えたの?ということですが、
cocos2d::CCSprite だと、「cocos2dのCCSprite」という意味になってしますためと思われます。
それよりかは、
cocos2d::Sprite で、「cocos2dのSprite」という方が理にかなっているからではないかなと。
その他、
cocos2d-x ver2系では無を代入するときに[NULL]を使いましたが、
ver3系では[nullptr]を使います。
例:
testObjcet = nullptr;
schedule関連関連ですが、こちらはCCがついていないにもかかわらず、エラーが発生します。
なぜかというと、スケジュール本体メソッドに、引数(float dt)が必要になりました。
旧 .h:
//スケジュール本体
virtual void schedule_example();
新 .h:
//スケジュール本体
virtual void schedule_example(float dt);
ヘッダファイル(.h)だけでなく、.cppのメソッドも同じく直しましょう。
これに関しては、そんなに時間かからなそうですね。
CCArrayに関しては、そのままArrayという風に直しても動かないようです。
Vectorという形式で書き直しました。
旧:(CCArrayの定義と、オブジェクトの追加)
CCArray *mokemokeArray;
CCSprite *spriteObject= CCSprite::create("mokemoke.png");
objectArray->addObject(spriteObject);
新:(Vector Arrayの定義と、オブジェクトの追加)
Vector objectArray;
cocos2d::Sprite *spriteObject = cocos2d::Sprite::create("mokemoke.png");
objectArray.pushBack(spriteObject);
続いて、便利な「オブジェクトの走査」を使うときは、
旧:(CCArrayの走査)
//Arrayを定義
CCArray *children = this->getChildren();
//オブジェクト格納用
CCObject *target_obj;
//キャスト用オブジェクト
CastClass *cast_targetNode;
//走査開始
CCARRAY_FOREACH(children, target_obj)
{
//オブジェクトをキャストする
cast_targetNode = (FlyingPacker*)enemy_obj;
//オブジェクトになにか命令する
cast_targetNode->honyarara();
}//:CCARRAY_FOREACH
新:(Vectorにて書き直し)
//キャスト用オブジェクト
CastClass *cast_targetNode;
for (auto targetObject : this->getChildren())
{
//オブジェクトをキャストする
cast_targetNode = (CastClass*)targetObject;
//オブジェクトになにか命令する
cast_targetNode->honyarara();
}//:for
こんなかんじでよろしいかと。
CCCallFuncにも大きな変更が行われました。
これまで
cocos2d-x Ver2系で困ったのは、CCCallBlockが無いことではないでしょうか。C++にはブロック構文がないですものね。
C++11にはObjective-Cのブロック構文の代わりになるラムダ式というのがあります。
CCCallFuncは、そのラムダ式の記述になるようです。
旧:
CCCallFunc *func01 =CCCallFunc::create(this, callfunc_selector(Player::action));
this->runAction(func01);
新:
cocos2d::CallFunc *func01 = CallFunc::create([this]()
{
this->action();
});//:CallFunc
this->runAction(func01);
これができるようになったことで、CCcallFuncNDの出番は減りそうですね;
タッチイベントにも変化があります。
おそらくそのままタッチイベントをもってくると、
[Layer#ccTouchBegan override me]
というエラーが出ているのではないでしょうか。
これはそのままの意味で、「オーバーライドしてちょうだい!」ということです。
では、書き換えていきましょう。ちなみに以下はマルチタッチの場合です。
※以下はcocos2d::Layerを継承したクラス[TouchLayer]に実装しています。
旧:(.h)
//[タッチイベント]
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);
新:(.h)
//[タッチイベント]
virtual void onTouchesBegan(const std::vector& touches, Event *unused_event);
virtual void onTouchesMoved(const std::vector& touches, Event *unused_event);
virtual void onTouchesEnded(const std::vector& touches, Event *unused_event);
virtual void onTouchesCancelled(const std::vector& touches, Event *unused_event);
続いて.cppの記述です。こちらは、新のみ記載します。
新:(.cpp)
//[タッチイベント]
void TouchLayer::onTouchesBegan(const std::vector& touches, Event *unused_event)
{
//タッチの分だけ繰り返す
for (auto touchObject : touches)
{
//タッチの内容がある場合のみ実行
if(touchObject != nullptr)
{
//タッチされた場所を取得
cocos2d::Point touchLocation = touchObject->getLocationInView();
touchLocation = Director::getInstance()->convertToGL(touchLocation);
CCLOG("タッチロケーション[x:%f][y:%f]" ,touchLocation.x, touchLocation.y);
//処理を実行(ついでに引数でタッチ場所を送りました)
this->touchEvent(touchLocation);
}//:if_else
}//:for
}
void TouchLayer::onTouchesMoved(const std::vector& touches, Event *unused_event){}
void TouchLayer::onTouchesEnded(const std::vector& touches, Event *unused_event){}
void TouchLayer::onTouchesCancelled(const std::vector& touches, Event *unused_event){}
続いて、タッチのON OFF用メソッドです。こちらも新のみ記載します。
ver2.2.2では、setTouchEnabledを使っていましたね。
新:(.h)
virtual void touchON(); //タッチ入力感知ON
virtual void touchOFF(); //タッチ入力感知OFF
新:(.cpp)
//タッチ入力感知ON
void TouchLayer::touchON()
{
CCLOG("タッチ感知をONにします。");
auto dispatcher = Director::getInstance()->getEventDispatcher();
this->touchListener->onTouchesBegan = CC_CALLBACK_2(TouchLayer::onTouchesBegan, this);
this->touchListener->onTouchesMoved = CC_CALLBACK_2(TouchLayer::onTouchesMoved, this);
this->touchListener->onTouchesEnded = CC_CALLBACK_2(TouchLayer::onTouchesEnded, this);
this->touchListener->onTouchesCancelled = CC_CALLBACK_2(TouchLayer::onTouchesCancelled, this);
dispatcher->addEventListenerWithSceneGraphPriority(this->touchListener, this);
}
//タッチ入力感知OFF
void TouchLayer::touchOFF()
{
CCLOG("タッチ感知をOFFにします。");
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->removeEventListener(this->touchListener);
}
BGM再生関連です。
旧:(.cpp)
//BGMプリロード
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic("bgm_main01.mp3");
//BGM再生
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("bgm_main01.mp3", true);
//BGM停止
CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
新:(.cpp)
//音量初期設定
CocosDenshion::SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(0.5f);
//BGMプリロード
CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("bgm_main01.mp3");
//BGM再生
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("bgm_main01.mp3", true);
//BGM停止
CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();
待望の?音量、ピッチ、パン設定機能が追加されました。
旧:(.cpp)
//SEプリロード
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("se_button_push.mp3");
//SE再生
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("se_button_push.mp3");
新:(.cpp)
//音量初期設定
CocosDenshion::SimpleAudioEngine::getInstance()->setEffectsVolume(0.5f);
//SEプリロード
CocosDenshion::SimpleAudioEngine::getInstance()->preloadEffect("se_button_push.mp3");
//SE再生
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("se_button_push.mp3", //ファイルネーム
false, //ループするか否か
1.0f, //再生ピッチ
0.0f, //パン(-1.0f~1.0f。0.0fが中心)
1.0f //音量
);
というような感じでした。
他にも気づいたら、追記していこうと思います。