How can I delay game/code during an action?

I am writing a checkers program. There is no need for a scheduler (no need to continuously keep time), but after some actions I want a delay. After the player moves I want a delay before the AI moves. If a piece can possibly double jump, I need to set a delay between when the first jump happens, and the second jump can occur, as the piece moves over time with animation.

For example: I have this code below that calls the move function.

if (move(currpiece, pos) == true)
            {
                //**I WANT TO PAUSE HERE
                // now opponent moves
                Position place;
                GameBoard::piece* pp;
                place = Game->getOppMove(pp);
                while (move(pp,place) == false); //**ALSO NEED TO PAUSE HERE
            }

The move function uses a Cocos action::

Action* moveToTargetPosition = MoveTo::create(piece_move_speed, posToLoc(pos));
    sprite->runAction(moveToTargetPosition);
    
    return Game->move(pce,pos);

in this example, I want to pause before the opponent piece moves. Also, if the AI can double jump, then the while loop calls two move functions with the same sprite (the second move function is called before the first action is finished), and there is an error.

How do I go about adding delaying my code until the move action is complete?

Thank you

You want to use DelayTime to pause and put that and the MoveTo actions into a Sequence. For instance, if you want to pause, move, pause, move2, where each step takes 0.5 seconds, you could do something like this:

DelayTime *pause = DelayTime::create(0.5);
MoveTo *move1 = MoveTo::create(0.5, pos1);
MoveTo *move2 = MoveTo::create(0.5, pos2);

currpiece->runAction(Sequence::create(pause, move1, pause->clone(), move2, NULL));

NOTE that if you want to use the same delay, you have to clone it the second time, or it won’t work.

1 Like

Thank you. I am trying to implement this using a runAction Sequence that is conditional. It will only run depending upon the previous run Sequence. I tried to implement this with a recursive CallFunc. It makes sense to me, but I have a bad access error for my sequence, and it won’t compile.
Here’s the code: can anybody help?

                Position place;
                GameBoard::piece* pp;
                bool stillhasmove;
                
                
                DelayTime* movedelay = DelayTime::create(between_turn_delay);
                DelayTime* piecedelay = DelayTime::create(piece_move_speed);
                
                CallFunc* oppmove = CallFunc::create([&] ()
                {
                    //  RECURSIVE LAMBDA FUNCTION
                    place = Game->getOppMove(pp);
                    
                    move2(pp,place,stillhasmove);
                  
                    if (stillhasmove==true)
                    {
                        this->runAction(Sequence::create(piecedelay->clone(),oppmove->clone(),nullptr));
                    }
                });

                this->runAction(Sequence::create(movedelay,oppmove,nullptr));

stillhasmove should be eventually set to false by the move2 function

Your call to move2 is passing stillhasmove by value. That means it’s actually making a copy of it locally for the function. If the value changes in the function, it won’t change here. This means stillhasmove will always be true.

I would suggest having move2 return a bool value that you copy into stillhasmove like this:

stillhasmove = move2(pp, place, stillhasmove);

nope it is being passed by reference. That’s not the problem. There is a bad access error on the Sequence

Ok, sorry… bad assumption. So I’m wondering if the oppmove->clone() is causing issues. Have you tried breaking this out into a regular function instead of a lambda function? Something like:

void MyScene::moveOpponent()
{
    Position place;
    GameBoard::piece *pp;
    bool stillhasmove;

    place = Game->getOppMove(pp);

    move2(pp, place, stillhasmove);

    if (stillhasmove)
    {
        DelayTime *piecedelay = DelayTime::create(piece_move_speed);
        CallFunc *oppmove =  CallFunc::create(CC_CALLBACK_0(MyScene::moveOpponent, this));
        this->runAction(Sequence::create(piecedelay, oppmove, NULL));
    }
}

well, for some reason that worked. Idk why, but it works. Thanks so much.

My best guess is that oppmove doesn’t exist yet to be able to clone it?