cocos2d-xのページが一新してたんで、記念にキャプチャ。
今巷はiOS7の話題でもちきりで、ぼくもその波に乗ってうぇーいってしようとしたけど、iOS7のシミュレータとかってAppleDeveloperにならないと貰えないぽいし、まだ登録してなかったことを思い出したし、急いで登録したけど土日祝とかぶっちゃってAppleから登録完了のメールこないし(´・ω・`)ってことで無事乗れなかったんで、切ないからマイペースに今できること続けます。。
そもそも、ひとつiPhoneアプリを作ってからじゃないと乗るも何もないですよねぇ(´・ω・`)
で、本題ですけどCCActionって時間とか気にしないような簡単なものならCCActionInstantを実装すればすぐ自作できるみたいだから、してみました。
以前CCActionの種類についてまとめたけど、欲張り屋さんのぼくはあれだけじゃちょっと物足りない。
ほとんどはCCCallFuncなどをつかったらできることが多いけど、それもちょい面倒。
というわけで、自作してみます。
大まかな流れ
クラスに以下のメソッドを作成してCCActionInstantを実装すれば作れるみたい。
補足:時間に応じて状態が変わるものを作る場合は、CCActionIntervalを実装したりまた別のものを作成したりとこれよりもうちょっと面倒です。今回はCCActionInstantのだけ。
class MyAction : public CCActionInstant{
public:
//コンストラクタとデストラクタ。
MyAction();
~MyAction();
//絶対必要じゃないけど、autoreleaseする為にね
static MyAction* create();
//ここに処理を記述
virtual void update(float time);
//コピーする際に必要
virtual CCObject* copyWithZone(CCZone* pZone);
//reverseされる際に必要
virtual CCFiniteTimeAction* reverse();
}
これらを実装すれば、他のと同じように使えるようになるみたいです。
コンストラクタとデストラクタは必ずしも必要じゃないけど、怖いからつくっときます。
postNotificationするアクションを作ってみる
では、実際に作ってみます。
cocos2d-xにはCCNotificationCenter::postNotificationというオブザーバーを管理する仕組みがあるらしく、それがとっても使えるんで、それをアニメーション中のタイミングで呼び出すだけのクラスCCCallObseverクラスを作成します。
ちなみにCCNotificationCenterの詳しい説明は下記のサイトにあります。ぼくも参考にしました。
cocos2d-xでObserverパターンを利用する -チラ裏開発メモ
//CCCallObserver.h
class CCCallObserver : public CCActionInstant{
const std::string m_observer;
CCObject* m_obj;
public:
CCCallObserver(const std::string &$call , CCObject* $obj): m_observer($call) , m_obj($obj){};
virtual ~CCCallObserver();
static CCCallObserver* create(const std::string &$call , CCObject* $obj);
virtual void update(float $time);
virtual CCObject* copyWithZone(CCZone* $zone);
virtual CCFiniteTimeAction* reverse();
};
//CCCallObserver.cpp
CCCallObserver::~CCCallObserver(){
if(m_obj){
m_obj->release();
}
}
CCCallObserver* CCCallObserver::create(const std::string &$call , CCObject* $obj){
if($obj){
$obj->retain();
}
CCCallObserver* obj = new CCCallObserver($call , $obj);
if(obj){
obj->autorelease();
}
return obj;
}
void CCCallObserver::update(float $time){
CC_UNUSED_PARAM($time);
CCNotificationCenter::sharedNotificationCenter()->postNotification(m_observer.c_str() , m_obj);
}
CCObject* CCCallObserver::copyWithZone(CCZone* pZone){
CCZone* newZone = NULL;
CCCallObserver* pRet = NULL;
if(pZone && pZone->m_pCopyObject){
pRet = (CCCallObserver*)(pZone->m_pCopyObject);
}else{
pRet = new CCCallObserver(m_observer , m_obj);
pZone = newZone = new CCZone(pRet);
}
CCActionInstant::copyWithZone(pZone);
CC_SAFE_DELETE(newZone);
return pRet;
}
CCFiniteTimeAction* CCCallObserver::reverse(){
return (CCFiniteTimeAction*)(CCCallObserver::create(m_observer , m_obj));
}
コードの補足
上にも書きましたが、update()の所に処理したいものを記載します。CCActionInstantの場合、特に時間によって状態が変わるというのもないので、引数のtimeは使用しません。ということで「いらん」とCC_UNUSED_PARAM()で明示します。
reverse()に関しても、巻き戻しても処理は結局同じなので、同じものを作成して返してあげます。
copyWithZone()に関しては、だいたいこれをひな形にして、あとはクラス名を変えたりセットする必要がある引数があるならセットしてあげるってだけでいいみたいです。保証はできませんけど、cocos2d-xフォルダにあるCCActionInstant内のもだいたいこんな感じだから多分大丈夫!
使ってみる
使ってみるといっても、他のと同じようにrunAction()内で使えばいいだけです。
pSprite->runAction(CCCallObserver::create(“jump”));
みたいな。当然CCSequenceやCCSpawnなどといったものの中にも入れることができます。
他にもアクションのタイミングで効果音を鳴らすとか、Spriteの画像を入れ替えるとかそのポイントで新たにCCSpriteを作成するとか他にも色んなものが簡単に作成できるし、便利です。
これらは全部CCCallFuncを使っても簡単に実装できますが(面倒だけど)。

楽しみにしています。
金魚ファンがいっぱいいます。
ありがとうございます、がんばります!
ピンバック: cocos2d-xでCCActionIntervalを自作してみる | たそがれブランチ