OBAKESAN.net FUNNY and HAPPY App
  • cocos2dx
    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)が非推奨になりました。
    新しくなった命令を知りたい際には、

    非推奨命令を消していく01


    古い命令の上で、commandキーを押しながらクリックすると、

    非推奨命令を消していく02


    このように新くなった命令を教えてくれます。この場合だとCCSprite→Spriteになりました。
    このあたりは、まとめて正規表現付きのGREPなどで置き換えてもいいかもしれません。

    ちなみに、なんでCCが消えたの?ということですが、
    cocos2d::CCSprite だと、「cocos2dのCCSprite」という意味になってしますためと思われます。
    それよりかは、
    cocos2d::Sprite で、「cocos2dのSprite」という方が理にかなっているからではないかなと。

    その他、cocos2d-x ver2系では無を代入するときに[NULL]を使いましたが、
    ver3系では[nullptr]を使います。

    例:
    testObjcet = nullptr;



    ・schedule



    schedule関連関連ですが、こちらはCCがついていないにもかかわらず、エラーが発生します。
    なぜかというと、スケジュール本体メソッドに、引数(float dt)が必要になりました。

    旧 .h:

    //スケジュール本体
    virtual void schedule_example();


    新 .h:

    //スケジュール本体
    virtual void schedule_example(float dt);


    ヘッダファイル(.h)だけでなく、.cppのメソッドも同じく直しましょう。
    これに関しては、そんなに時間かからなそうですね。


    ・CCArray→Vector



    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→CallFunc(さらに新たにラムダ式に)



    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の出番は減りそうですね;

    ・タッチイベント(ccTouch→onTouch)



    タッチイベントにも変化があります。
    おそらくそのままタッチイベントをもってくると、
    [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関連(sharedEngine→getInstance)




    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();


    ・SE関連(sharedEngine→getInstance)




    待望の?音量、ピッチ、パン設定機能が追加されました。

    旧:(.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 //音量
    );



    というような感じでした。
    他にも気づいたら、追記していこうと思います。
    この記事へのコメント:
    Name:お名前

    HomePageURL:ホームページ(あれば)
    http://
    Comment:コメント本文

ごあいさつ
もっさん
こんにちは。OBAKESAN.netへようこそ。アプリを作っていこうと思います。ご連絡などはお気軽にどうぞですよー。

・Twitterはこちら
・GitHubはこちら
Twitterタイムライン