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;
}
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.