diff --git a/lib/game/board.dart b/lib/game/board.dart index 85d003a..a2bb60e 100644 --- a/lib/game/board.dart +++ b/lib/game/board.dart @@ -236,7 +236,8 @@ class Board extends FlameGame { int _removeMatchedElements(int row, int col) { int score = 0; final int? value = tiles[row][col]?.spriteIndex; - bool transformToBomb = false; + bool bombTriggered = false; + Tile? tileToTransformIntoBomb = lastMovedTile; int left = col; while (left > 0 && tiles[row][left - 1]?.spriteIndex == value) left--; @@ -245,21 +246,22 @@ class Board extends FlameGame { right++; if (right - left + 1 >= 3) { - int matchLength = right - left + 1; - score += _calculateScore(matchLength); + score += _calculateScore(right - left + 1); - if (matchLength == 4 && - lastMovedTile != null && - lastMovedTile!.row == row && - lastMovedTile!.col == col) { - transformToBomb = true; + if (right - left + 1 >= 4) { + tileToTransformIntoBomb = tiles[row][col]; } for (int i = left; i <= right; i++) { - if (tiles[row][i] != null && - (!transformToBomb || tiles[row][i] != lastMovedTile)) { - _animateRemoveTile(tiles[row][i]!); - tiles[row][i] = null; + if (tiles[row][i] != null) { + if (tiles[row][i]!.isBomb) { + bombTriggered = true; + _triggerBomb(row, i); + } + if (tiles[row][i] != tileToTransformIntoBomb) { + _animateRemoveTile(tiles[row][i]!); + tiles[row][i] = null; + } } } } @@ -271,37 +273,81 @@ class Board extends FlameGame { bottom++; if (bottom - top + 1 >= 3) { - int matchLength = bottom - top + 1; - score += _calculateScore(matchLength); + score += _calculateScore(bottom - top + 1); - if (matchLength == 4 && - lastMovedTile != null && - lastMovedTile!.row == row && - lastMovedTile!.col == col) { - transformToBomb = true; + if (bottom - top + 1 >= 4) { + tileToTransformIntoBomb = tiles[row][col]; } for (int i = top; i <= bottom; i++) { - if (tiles[i][col] != null && - (!transformToBomb || tiles[i][col] != lastMovedTile)) { - _animateRemoveTile(tiles[i][col]!); - tiles[i][col] = null; + if (tiles[i][col] != null) { + if (tiles[i][col]!.isBomb) { + bombTriggered = true; + _triggerBomb(i, col); + } + if (tiles[i][col] != tileToTransformIntoBomb) { + _animateRemoveTile(tiles[i][col]!); + tiles[i][col] = null; + } } } } - if (transformToBomb && lastMovedTile != null) { - _createBomb(lastMovedTile!.row, lastMovedTile!.col); - } else { - if (tiles[row][col] != null) { - _animateRemoveTile(tiles[row][col]!); - tiles[row][col] = null; - } + if (bombTriggered) { + _triggerBomb(row, col); + } + + if (tileToTransformIntoBomb != null) { + _createBomb(tileToTransformIntoBomb.row, tileToTransformIntoBomb.col); } return score; } + void _triggerBomb(int row, int col) { + final tile = tiles[row][col]; + if (tile == null || !tile.isBomb) return; + + final bombPosition = tile.position.clone(); + + for (int i = max(0, row - 1); i <= min(rows - 1, row + 1); i++) { + for (int j = max(0, col - 1); j <= min(cols - 1, col + 1); j++) { + if (tiles[i][j] != null) { + if (tiles[i][j]!.isBomb && !(i == row && j == col)) { + tiles[i][j]!.isBomb = false; + _triggerBomb(i, j); + } else { + _animateRemoveTile(tiles[i][j]!); + tiles[i][j] = null; + } + } + } + } + + _animateBombExplosion(bombPosition); + + _animateRemoveTile(tile); + tiles[row][col] = null; + } + + void _animateBombExplosion(Vector2 position) { + final explosion = CircleComponent( + radius: tileSize / 2, + paint: Paint()..color = Colors.orange.withOpacity(0.7), + position: position - Vector2.all(tileSize / 2), + ); + + add(explosion); + + explosion.add( + ScaleEffect.to( + Vector2.all(3), + EffectController(duration: 0.5), + onComplete: () => explosion.removeFromParent(), + ), + ); + } + int _calculateScore(int matchLength) { if (matchLength == 3) { return 50; @@ -314,38 +360,41 @@ class Board extends FlameGame { } void _animateRemoveTile(Tile tile) { - tile.animateRemove(() { - remove(tile); - }); + tile.add(RemoveEffect( + delay: 0.5, + onComplete: () => remove(tile), + )); } void _createBomb(int row, int col) { - final tile = tiles[row][col]!; - tile.isBomb = true; + final tile = tiles[row][col]; + if (tile != null) { + tile.isBomb = true; - tile.add( - OpacityEffect.to( - 0.5, - EffectController( - duration: 0.5, - infinite: true, - reverseDuration: 0.5, + tile.add( + OpacityEffect.to( + 0.5, + EffectController( + duration: 0.5, + infinite: true, + reverseDuration: 0.5, + ), ), - ), - ); + ); - tile.add( - ColorEffect( - Colors.orange, - EffectController( - duration: 0.5, - infinite: true, - reverseDuration: 0.5, + tile.add( + ColorEffect( + Colors.orange, + EffectController( + duration: 0.5, + infinite: true, + reverseDuration: 0.5, + ), + opacityFrom: 0.5, + opacityTo: 1.0, ), - opacityFrom: 0.5, - opacityTo: 1.0, - ), - ); + ); + } } void _createMagicCube(int row, int col) { diff --git a/lib/game/tile.dart b/lib/game/tile.dart index 27b5b99..5634237 100644 --- a/lib/game/tile.dart +++ b/lib/game/tile.dart @@ -31,11 +31,7 @@ class Tile extends SpriteComponent with TapCallbacks, DragCallbacks { if (parent is Board && (parent as Board).animating) { return false; } - if (isBomb) { - (parent as Board).explodeBomb(this); - } else { - onTileTap(this); - } + onTileTap(this); return true; }