読者です 読者をやめる 読者になる 読者になる

とあるプログラマの備忘録

都内某所に住むプログラマが自分用に備忘録を残すという趣旨のブログです。はてなダイアリーから移動しました!

cocos2d-x onTouchMoved内でのAction競合について

さてさてひたすらC++との戦いを繰り返しているわけですが、
一朝一夕でC++をマスターできる訳でもないので地道に行きたいと思います。

さて今回はonTouchMovedハンドラ内で
CCActionを起こすとどうなるのかという話です。

とりあえずタッチイベントを有効にして適当に書いてみます。

//タッチ移動イベント
void HelloWorld::onTouchMoved(Touch* touch, Event* even t)
{
    //0,0のオブジェクトを召還
    auto obj = arrTotal[0][0];
    
    //動かしてみる
    auto moveStartObj = MoveTo::create(1.0f, Point(obj->getPositionX(), obj->getPositionY() - 10));
    obj->getBlock()->runAction(moveStartObj);

そうすると

f:id:raharu0425:20140303112911p:plain

わかりにくい画像ですが、
onTouchMovedで毎フレームで呼び出されたアクションは競合して
1秒かけてy軸を-10しろという命令をが重複してかかります。

なので予想を超えた動きになってしまうのです。

そんじゃロックかけちゃえばいいじゃないという事でロックかけてみます。

//タッチ移動イベント
void HelloWorld::onTouchMoved(Touch* touch, Event* event)
{
    //0,0のオブジェクトを召還
    auto obj = arrTotal[0][0];
    
    if( !is_lock ){
        
        is_lock = true;
        
        //動かしてみる
        auto moveStartObj = MoveTo::create(1.0f, Point(obj->getPositionX(), obj->getPositionY() - 10));
        //obj->getBlock()->runAction(moveStartObj);
        auto unlock = CallFunc::create(this, callfunc_selector(HelloWorld::unLock));
        auto seq = Sequence::create(moveStartObj, unlock, NULL);
        obj->getBlock()->runAction(seq);
    }

ようは
・1秒かけてY軸を-10する
・ロック解除
を直列処理にしてあげれば問題解決?

f:id:raharu0425:20140303115107p:plain

ほむほむ確かに予定どおりの動きになりました。
だた毎回こんな面倒なロックを繰り返さないといけないんですか?いやですね。

CCMoveTo, CCMoveByなどのCCAction系の競合対策 - 黒白猫の開発日記

こちらの記事によれば
CC_ENABLE_STACKABLE_ACTIONSを0
にする事で合算を回避できるとの事ですが、v3.0 beta2ではエラーが発生してしまうようです。

またonTouchMoved内でのMoveTo処理もあまりいい感じとはいえないようですね。
もう少しやり方を考えていきたいと思います。