Search code examples
actionscript-3flashanimationflash-cs5

Slow down method execution so animation appears in flash


I have a method to swap two pieces in Bejeweled, but the animated swap doesn't appear to the user when they make a swap with no matches.

I.e. When the user tries to swap a jewel and no matches occur, the jewel stays stationary. What should happen is the jewel swaps positions, realises there isn't a match and swaps back.

I believe the issue is that the swaps are happening almost instantly if there isn't a match and there is no animation for the user.

How can I slow down the execution time of the second swap (i.e. the swap back) so the animation of the swap occurs?

// start animated swap of two pieces

public function makeSwap(piece1,piece2:Piece)
{
    swapPieces(piece1,piece2);

    //check to see if move works

    if (lookForMatches().length == 0)
    {
        swapPieces(piece1,piece2); //Swap the piece back
    } 
    else 
    {
        isSwapping = true;
    }
}

// swap two pieces

public function swapPieces(piece1,piece2:Piece) 
{
    // swap row and col values

    var tempCol:uint = piece1.col;
    var tempRow:uint = piece1.row;
    piece1.col = piece2.col;
    piece1.row = piece2.row;
    piece2.col = tempCol;
    piece2.row = tempRow;

    // swap grid positions

    grid[piece1.col][piece1.row] = piece1;
    grid[piece2.col][piece2.row] = piece2;

}

Solution

  • It's not too clear from your code how the animation itself is happening (clearly there are rendering functions elsewhere), but to add a delay to the execution of a function in AS3, you could use either the setTimeout function or the Timer class.

    Here's setTimeout:

    import flash.utils.setTimeout; //To be added with your other imports
    
    // start animated swap of two pieces
    
    public function makeSwap(piece1:Piece,piece2:Piece):void
    {
        swapPieces(piece1,piece2);
    
        //check to see if move works
    
        if (lookForMatches().length == 0)
        {
            setTimeout(swapPieces, 500, piece1, piece2); //Swap the piece back, after delay of 500 milliseconds
        } 
        else 
        {
            isSwapping = true;
        }
    }
    
    // swap two pieces
    
    public function swapPieces(piece1:Piece,piece2:Piece):void
    {
        // swap row and col values
    
        var tempCol:uint = piece1.col;
        var tempRow:uint = piece1.row;
        piece1.col = piece2.col;
        piece1.row = piece2.row;
        piece2.col = tempCol;
        piece2.row = tempRow;
    
        // swap grid positions
    
        grid[piece1.col][piece1.row] = piece1;
        grid[piece2.col][piece2.row] = piece2;
    
    }
    

    And here's Timer:

    import flash.utils.Timer; //To be added with your other imports
    import flash.events.TimerEvent; //To be added with your other imports
    
    private var _swapBackTimer:Timer = new Timer(500, 1); //Delay of 500 milliseconds, timer running 1 time
    private var _delaySwapPiece1:Piece;
    private var _delaySwapPiece2:Piece;
    
    // start animated swap of two pieces
    
    public function makeSwap(piece1:Piece,piece2:Piece):void
    {
        swapPieces(piece1,piece2);
    
        //check to see if move works
    
        if (lookForMatches().length == 0)
        {
            _swapBackTimer.reset();
            _swapBackTimer.addEventListener(TimerEvent.TIMER, swapBackTimer_complete);
            _swapPiece1 = piece1;
            _swapPiece2 = piece2;
            _swapBackTimer.start();
        } 
        else 
        {
            isSwapping = true;
        }
    }
    
    private function swapBackTimer_complete(evt:TimerEvent):void
    {
        _swapBackTimer.removeEventListener(TimerEvent.TIMER, swapBackTimer_complete);
        swapPieces(_delaySwapPiece1, _delaySwapPiece2);
    }
    
    // swap two pieces
    
    public function swapPieces(piece1:Piece,piece2:Piece):void
    {
        // swap row and col values
    
        var tempCol:uint = piece1.col;
        var tempRow:uint = piece1.row;
        piece1.col = piece2.col;
        piece1.row = piece2.row;
        piece2.col = tempCol;
        piece2.row = tempRow;
    
        // swap grid positions
    
        grid[piece1.col][piece1.row] = piece1;
        grid[piece2.col][piece2.row] = piece2;
    
    }
    

    One thing to keep in mind with this is the risk of the user changing the game state during the delay period, invalidating delayed actions and introducing bugs. You're maybe managing this already, but just in case, one approach would be to set a flag during any delayed actions, and then ignore any subsequent input during that time. Another method would be to cancel the delayed action, have it execute immediately, then process the new user action from that point.