diff --git a/lib/game/board.dart b/lib/game/board.dart index b32df44..8163a01 100644 --- a/lib/game/board.dart +++ b/lib/game/board.dart @@ -39,6 +39,7 @@ class Board extends FlameGame { row: row, col: col, onTileTap: handleTileTap, + onSwipe: handleTileSwipe, ); rowTiles.add(tile); add(tile); @@ -83,7 +84,7 @@ class Board extends FlameGame { if (_isAdjacent(selectedRow!, selectedCol!, row, col)) { swapTiles(tiles[selectedRow!]![selectedCol!]!, tiles[row]![col]!, true); Future.delayed(const Duration(milliseconds: 300), () { - if (!_checkMatches()) { + if (!checkMatches()) { swapTiles( tiles[row]![col]!, tiles[selectedRow!]![selectedCol!]!, true); } @@ -99,36 +100,71 @@ class Board extends FlameGame { } } + Future handleTileSwipe(Tile tile, Vector2 delta) async { + if (animating) return; // Блокируем свайп во время анимации + + int row = tile.row; + int col = tile.col; + Tile? targetTile; + + if (delta.x.abs() > delta.y.abs()) { + if (delta.x > 0 && col < cols - 1) { + targetTile = tiles[row][col + 1]; + } else if (delta.x < 0 && col > 0) { + targetTile = tiles[row][col - 1]; + } + } else { + if (delta.y > 0 && row < rows - 1) { + targetTile = tiles[row + 1][col]; + } else if (delta.y < 0 && row > 0) { + targetTile = tiles[row - 1][col]; + } + } + + if (targetTile != null) { + animating = true; // Устанавливаем флаг анимации + swapTiles(tile, targetTile, true); + + await Future.delayed(const Duration(milliseconds: 300)); + + if (!checkMatches()) { + swapTiles(tile, targetTile!, true); + } + + animating = false; // Сбрасываем флаг анимации + } + } + bool _isAdjacent(int row1, int col1, int row2, int col2) { return (row1 == row2 && (col1 - col2).abs() == 1) || (col1 == col2 && (row1 - row2).abs() == 1); } void swapTiles(Tile tile1, Tile tile2, bool animate) { - final tempPosition = tile1.position; - final tempRow = tile1.row; - final tempCol = tile1.col; + final tempPosition1 = tile1.position.clone(); + final tempPosition2 = tile2.position.clone(); + final tempRow1 = tile1.row; + final tempCol1 = tile1.col; + final tempRow2 = tile2.row; + final tempCol2 = tile2.col; - tile1.position = tile2.position; - tile1.row = tile2.row; - tile1.col = tile2.col; - - tile2.position = tempPosition; - tile2.row = tempRow; - tile2.col = tempCol; + tile1.row = tempRow2; + tile1.col = tempCol2; + tile2.row = tempRow1; + tile2.col = tempCol1; tiles[tile1.row][tile1.col] = tile1; tiles[tile2.row][tile2.col] = tile2; if (animate) { - tile1.animateMoveTo(tile1.position, () {}); - tile2.animateMoveTo(tile2.position, () {}); + tile1.animateMoveTo(tempPosition2, () {}); + tile2.animateMoveTo(tempPosition1, () {}); } } - bool _checkMatches() { - if (animating) return false; - animating = true; + bool checkMatches() { + if (animating) return false; // Не проверяем совпадения, пока идет анимация + animating = true; // Устанавливаем флаг анимации final matches = >[]; for (int row = 0; row < rows; row++) { @@ -148,14 +184,14 @@ class Board extends FlameGame { Future.delayed(const Duration(milliseconds: 300), () { _fillEmptySpaces(); Future.delayed(const Duration(milliseconds: 300), () { - animating = false; - _checkMatches(); + animating = false; // Сбрасываем флаг анимации после всех анимаций + checkMatches(); }); }); }); return true; } - animating = false; + animating = false; // Сбрасываем флаг анимации, если нет совпадений return false; } @@ -247,6 +283,7 @@ class Board extends FlameGame { row: row, col: col, onTileTap: handleTileTap, + onSwipe: handleTileSwipe, // Добавлен обработчик свайпов ); tiles[row][col] = tile; add(tile); diff --git a/lib/game/swap_notifier.dart b/lib/game/swap_notifier.dart index 7fcff33..9233387 100644 --- a/lib/game/swap_notifier.dart +++ b/lib/game/swap_notifier.dart @@ -12,7 +12,12 @@ class SwapNotifier extends ChangeNotifier { } else { if (_isNeighbor(selectedTile!, tile)) { board.swapTiles(selectedTile!, tile, true); - selectedTile = null; + Future.delayed(const Duration(milliseconds: 300), () { + if (!board.checkMatches()) { + board.swapTiles(tile, selectedTile!, true); + } + selectedTile = null; + }); } else { selectedTile?.deselect(); selectedTile = tile; diff --git a/lib/game/tile.dart b/lib/game/tile.dart index 837a760..89de470 100644 --- a/lib/game/tile.dart +++ b/lib/game/tile.dart @@ -3,12 +3,14 @@ import 'package:flame/effects.dart'; import 'package:flame/events.dart'; import 'package:flutter/material.dart'; -class Tile extends SpriteComponent with TapCallbacks { +class Tile extends SpriteComponent with TapCallbacks, DragCallbacks { int row; int col; int spriteIndex; final void Function(Tile) onTileTap; + final void Function(Tile, Vector2) onSwipe; bool isSelected = false; + Vector2? startDragPosition; Tile({ required Sprite sprite, @@ -18,6 +20,7 @@ class Tile extends SpriteComponent with TapCallbacks { required this.row, required this.col, required this.onTileTap, + required this.onSwipe, }) : super(sprite: sprite, size: size, position: position); @override @@ -26,6 +29,22 @@ class Tile extends SpriteComponent with TapCallbacks { return true; } + @override + bool onDragStart(DragStartEvent event) { + startDragPosition = event.localPosition; + return true; + } + + @override + bool onDragEnd(DragEndEvent event) { + if (startDragPosition != null) { + final delta = event.velocity; + onSwipe(this, delta); + } + startDragPosition = null; + return true; + } + void select() { isSelected = true; updateBorder();