I'm creating the game Snakes And Ladders. I use a game mode that allows you to play against the computer.
When the human player rolls the dice the rollTheDiceAndMove
method is called. We wait 1 second (dice is rolling...). Then we call the move
function that actually moves the pieces to the specified tile. If a snake or a ladder is hit, I want to wait another 1 second before going to the final tile. Eg. I wait 1 second and I roll 5, I go my_current_pos + dice_roll
tiles in front, then I move the piece. If snake or ladder hit: another delay and move again recursively.
Finally, if the "Against Computer" mode is selected, when the human player moves, I want to wait another second before computer automatically rolls the dice. As you see below, I'm using Timer
and TimerTask
classes but it's very complicated because whatever is inside the Timer
scope executes after some period, but code outside the timer is executed without delay and this is causing me many bugs and asynchronization.
What do you suggest using to create this delay?
public void rollTheDiceAndMove() {
int diceRoll = gameBoard.rollDice();
// delay for dice roll.
new Timer().schedule(
new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
////////////////////////////////////////////////////////////////////////////
gameGUI.indicateDiceRoll(diceRoll);
int newIndex = getPlayerIndexAfterRoll(diceRoll);
move(newIndex);
System.out.println("change turns");
swapTurns();
System.out.println(isComputerTurn());
gameGUI.updateCurrentTurnLabel();
if (newIndex == GameBoard.WIN_POINT) {
boolean restartGame = gameBoard.playAgainOrExit();
if (restartGame) {
Player winner = gameBoard.getCurrentPlayer();
gameGUI.updateScore(winner);
gameGUI.playAgain();
} else {
System.exit(0);
}
}
////////////////////////////////////////////////////////////////////////////
}
});
}
}, GameBoard.DICE_ROLL_DELAY
);
// try to recursively call this method again for computer turn.
}
public void move(int currentIndex) {
int[] newCoordinates = gameBoard.getBoardCoordinates(GameBoard.NUMBER_OF_TILES - currentIndex);
gameBoard.getCurrentPlayer().getPlayerPiece().setPosition(currentIndex);
gameGUI.movePieceImages(newCoordinates[0], newCoordinates[1]);
if (gameBoard.getTile(currentIndex).containsLadderOrSnake()) {
// delay for moving to second tile.
new Timer().schedule(
new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
int updatedIndex = gameBoard.getUpdatedPosition(currentIndex);
move(updatedIndex);
}
});
}
}, GameBoard.SECOND_MOVE_DELAY *2
);
return; // we need to return 'cause of recursion. Swap turns will be executed twice, one time for the initial call and the other time on above line.
}
}