Cocos2d-x c++ - 在继续之前等待操作完成

Cocos2d-x c++ - Wait for action finish before continuing

我在做一个滑块拼图,这个函数应该移动一个方块,然后 return 回到主函数,这样我就可以继续玩了,我也在开始的时候使用这个函数来打乱方块游戏的一部分,但是当我调用它时,所有的方块一起移动并进入错误的位置或离开屏幕,这是因为而不是 运行 移动动作 moveTo 需要 0.2 秒,然后在 0.2 秒后,returning,它开始动作并且 returns 马上,所以当它再次被调用时,磁贴仍在移动,把一切都搞砸了。

有什么方法可以阻止代码在操作完成之前继续执行吗?谢谢 ;)

bool GameScene::updateTile(Sprite* tile, int newPos)
{
    auto moveTo = MoveTo::create(0.2, Vec2(widthArray[newPos], heightArray[newPos]));
    auto whatever = CallFunc::create([]() {
        CCLOG("hi");
    });
    auto seq = Sequence::create(moveTo, whatever, nullptr);
    tile->runAction(seq);
    CCLOG("running");
    return true;
}

//编辑

此代码打印: "running" 0.2 秒后(运行 动作 moveTo 所需的时间) "hi"(来自任何动作)

我的目标是让它等待 0.2 秒然后打印 "hi" 并且仅在此之后打印 "running" 但是如果我尝试使用任何类型的延迟或循环来停止代码 喜欢:

 bool GameScene::updateTile(Sprite* tile, int newPos)
    {
        auto moveTo = MoveTo::create(0.2, Vec2(widthArray[newPos], heightArray[newPos]));
        auto whatever = CallFunc::create([]() {
            CCLOG("hi");
        });
        auto seq = Sequence::create(moveTo, whatever, nullptr);
        tile->runAction(seq);
        while (tile->getNumberOfRunningActions != 0)
              { //delay 
              }
        CCLOG("running");
        return true;
    }

它没有运行任何动作,只是卡住了,有什么想法吗?

您可以使用 tag 检查一个动作是否已经完成:

bool GameScene::updateTile(Sprite* tile, int newPos)
{
    static const int MY_MOVE_SEQ = 3333;
    if (tile->getActionByTag(MY_MOVE_SEQ) && !tile->getActionByTag(MY_MOVE_SEQ)->isDone()) {
        return;
        //or you can stop the last action sequence and then run new action
        //tile->stopActionByTag(MY_MOVE_SEQ);
    }

    auto moveTo = MoveTo::create(0.2, Vec2(widthArray[newPos], heightArray[newPos]));
    auto whatever = CallFunc::create([]() {
        CCLOG("hi");
    });
    auto seq = Sequence::create(moveTo, whatever, nullptr);
    //set tag here!
    seq->setTag(MY_MOVE_SEQ);

    tile->runAction(seq);
    CCLOG("running");
    return true;
}

//编辑

    bool anyActionRunning = false;
    tile->getParent()->enumerateChildren("//Tile", [&anyActionRunning](Node* child) {
        if (child->getActionByTag(MY_MOVE_SEQ) && !child->getActionByTag(MY_MOVE_SEQ)->isDone()) {
            anyActionRunning = true;
            return true;
        }
        return false;
    });

//编辑2:

static const string funcName = "CheckAction";
tile->schedule([tile](float dt) {
    if (tile->getNumberOfRunningActions == 0) {
        CCLOG("running");
        tile->unschedule(funcName);
    }
}, funcName);