[Cocos2d-x]CCCallFunc系の使い方

cocos2d-x

CCCallFunc系の使い方を忘れてハマる事が多いのでメモする。以下のコードはメモリリークとか全く考えてないので真面目に読む方はご注意を…


基本的なサンプルコード

下のコードを CCLayerのonEnterメソッド(オーバーライド)で実行した場合は

  class Caller : public CCNode {
  public:
    void execute(void) {
      CCLOG("execute called.");
    };
    void executeO(CCObject *pObject) {
      CCLOG((const char *)((CCNode *)pObject)->getUserData());
    }
    void executeN(CCNode *pSender) {
      CCLOG((const char *)pSender->getUserData());
    }
    void executeND(CCNode *pSender, void *d) {
      CCLOG((const char *)d);
    }
  };

  CCActionManager *pManager = CCDirector::sharedDirector()->getActionManager();
  Caller *pCaller = new Caller();
  addChild(pCaller);

  // CallFuncの実験
  CCCallFunc *pFunc = CCCallFunc::create(pCaller, callfunc_selector(Caller::execute));
  pCaller->runAction(pFunc);

  // CallFuncOの実験
  CCNode *pObject = new CCNode();
  pObject->setUserData((void *)"executeO called.");
  CCCallFuncO *pFuncO = CCCallFuncO::create(pCaller, callfuncO_selector(Caller::executeO), pObject);
  pCaller->runAction(pFuncO);

  // CallFuncNの実験
  pCaller->setUserData((void *)"executeN called.");
  CCCallFuncN *pFuncN = CCCallFuncN::create(pCaller, callfuncN_selector(Caller::executeN));
  pManager->addAction(pFuncN, pCaller, false);

  // CallFuncNDの実験
  CCCallFuncND *pFuncND = CCCallFuncND::create(pCaller, callfuncND_selector(Caller::executeND), (void*)"executeND called.");
  pFuncND->retain();
  pManager->addAction(pFuncND, pCaller, false);

結果以下のようにコンソールに表示される。

結果

Cocos2d: execute called.
Cocos2d: executeO called.
Cocos2d: executeN called.
Cocos2d: callfuncND called.

基本はこんだけ。簡単だね。

ハマリどころ

ちゃんと分かってないと動かなくてハマることになるかも。

ターゲットがルートノードから認識できない場合はアクションが実行されない

  class Caller : public CCNode {
  public:
    void execute(void) { CCLOG("execute called."); }
  };

  Caller *pCaller = new Caller();
  CCCallFunc *pFunc = CCCallFunc::create(pCaller, callfunc_selector(Caller::execute));

  pCaller->runAction(pFunc);

上のコードのCCCallFuncは実行されない。addChildして親レイヤーなどに載せてやらないと CCNode#runAction, CCActionManager#addAction で動かない。動かない上に、エラーも出ない。

メモリリーク

CallFuncND::create(target, selector, data) …で渡したdataをアクションによるcallfunc実行時にリリースしたいということは結構あると思う。でもこれをメモリリークを気にせずにやろうとするとメモリリークの原因となりうる。

たとえば CCSequence で CCDelayTime -> CCCallFuncND というような順番で実行する場合、CCCallFuncのアクションが実行される前にシーンを切り替えてしまうと、CCCallFuncND が実行されないままになってしまう。そうすると CCCallFuncND の呼び出しで実行するつもりだったメモリ解放が実行されなくてメモリリークしてしまう。

そうゆうことでまぁ注意しよう…。SceneのレイヤーにCCArrayでも作っておいて、それに持たせて、レイヤー開放時に CCArray に持たせたオブジェクトも開放するなりすることで回避できる。もちろんCCCallFuncND実行時にCCArrayに持たせたオブジェクトを開放すること。

  1. コメントはまだありません。

  1. トラックバックはまだありません。

*


Advertisement