Leave without saving?

Your editor changes will be lost.

Match-3-2 changes the immediate tile swap from Match-3-1 into a short animation. The board still permits any two tiles to be swapped; this lesson focuses on tweening their drawing positions before committing the grid swap.

The Timer Service

Game creates one Timer and exposes it through injected GameServices as this.game.timer. The game loop advances that timer every frame after it updates the active state, so tweened values change over time without PlayState manually calling a global timer.

A tween receives an object, the properties to animate, a duration in seconds, and optionally an easing curve. tweenAsync() returns a promise that resolves when its tween finishes.

this.game.timer.tweenAsync(
highlightedTile,
{ x: temporaryTile.x, y: temporaryTile.y },
0.2,
Easing.easeInQuad
);

Animated swaps

Board.swapTilesAnimated() starts the two tile tweens at the same time. It waits for the selected tile’s tween; since both tweens have the same duration and begin together, both visual moves have completed when the await finishes.

this.isSwapping = true;
this.game.timer.tweenAsync(
highlightedTile,
{ x: temporaryTile.x, y: temporaryTile.y },
0.2,
Easing.easeInQuad
);
await this.game.timer.tweenAsync(
selectedTile,
{ x: highlightedTile.x, y: highlightedTile.y },
0.2,
Easing.easeInQuad
);
this.isSwapping = false;
this.swapTiles(selectedTile, highlightedTile);

The tween changes only x and y, the tile’s drawing position. After the animation, swapTiles() updates boardX, boardY, and the two tiles[row][column] slots so the board data agrees with what the player sees.

Blocking input during the animation

A second selection during an in-progress swap would start another animation with inconsistent positions. Board.isSwapping is set before the tweens begin and reset only after they finish.

PlayState.update() checks the flag before processing Enter or Space:

if (
this.board &&
!this.board.isSwapping &&
(input.isKeyPressed(Input.KEYS.ENTER) || input.isKeyPressed(Input.KEYS.SPACE))
) {
this.selectTile(this.board);
}

This is a common asynchronous-gameplay pattern: store whether an action is in progress, then prevent conflicting input until that action completes.

Powered by WebContainers
Files
Preparing Environment