ゲームを作っていると一定時間後に特定の処理を入れたい場合がある。
cocos2d-x 3.0ではC++11でラムダ式が使えるのだが、Nodeが実装しているscheduleやscheduleOnceメソッドを使うと、schedule_selectorというマクロを使ってクラスに実装したメソッドをコールバックに指定しなくてはいけない。
たとえば、3秒後に変数_flagにfalseを代入したいときはこんなことになる。
SomeClass.h
class SomeClass
{
private:
void someMethod();
void disableFlag(float d);
bool _flag = false;
}
SomeClass.cpp
void SomeClass::someMethod()
{
// 3秒後に_flagという変数にfalseを代入したい
this->scheduleOnce(schedule_selector(SomeClass::disableFlag), 3);
}
void SomeClass::disableFlag(float d)
{
this->setFlag(false);
_flag = n;
}
まぁこれ一回だけとかなら許せなくはないですが、頻繁に起こることなので私の怒りが有頂天に達しました。
DelayTimeとCallFuncを使う
そこでなにかいい方法はないかと考えた結果、同じくNodeが実装しているrunActionを使う方法を思いつきました。runActionは色々なアクションを簡単に実行できるので重宝しますが、その中でも時間を遅らせるDelayTimeと引数なしstd::function型のコールバックを実行するCallFuncを使えばいいのです。こんな風に。
SomeClass.cpp
void SomeClass::someMethod()
{
// 3秒後にラムダ式を実行
this->runAction(Sequence::create(DelayTime::create(3),CallFunc::create([this](){
this->_flag = false;
}), NULL));
}
せっかくなのでこんなマクロを作りました
#define call_after(callback, delay) \
runAction(Sequence::create(DelayTime::create(delay), CallFunc::create(callback), NULL))
void SomeClass::someMethod()
{
call_after([this](){ this->_flag = false; }, 3);
}
めっちゃ気持ちいいです。