Added element animation and swipe movement.
This commit is contained in:
parent
5d08e84407
commit
a440fd1545
@ -39,6 +39,7 @@ class Board extends FlameGame {
|
|||||||
row: row,
|
row: row,
|
||||||
col: col,
|
col: col,
|
||||||
onTileTap: handleTileTap,
|
onTileTap: handleTileTap,
|
||||||
|
onSwipe: handleTileSwipe,
|
||||||
);
|
);
|
||||||
rowTiles.add(tile);
|
rowTiles.add(tile);
|
||||||
add(tile);
|
add(tile);
|
||||||
@ -83,7 +84,7 @@ class Board extends FlameGame {
|
|||||||
if (_isAdjacent(selectedRow!, selectedCol!, row, col)) {
|
if (_isAdjacent(selectedRow!, selectedCol!, row, col)) {
|
||||||
swapTiles(tiles[selectedRow!]![selectedCol!]!, tiles[row]![col]!, true);
|
swapTiles(tiles[selectedRow!]![selectedCol!]!, tiles[row]![col]!, true);
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
Future.delayed(const Duration(milliseconds: 300), () {
|
||||||
if (!_checkMatches()) {
|
if (!checkMatches()) {
|
||||||
swapTiles(
|
swapTiles(
|
||||||
tiles[row]![col]!, tiles[selectedRow!]![selectedCol!]!, true);
|
tiles[row]![col]!, tiles[selectedRow!]![selectedCol!]!, true);
|
||||||
}
|
}
|
||||||
@ -99,36 +100,71 @@ class Board extends FlameGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> 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) {
|
bool _isAdjacent(int row1, int col1, int row2, int col2) {
|
||||||
return (row1 == row2 && (col1 - col2).abs() == 1) ||
|
return (row1 == row2 && (col1 - col2).abs() == 1) ||
|
||||||
(col1 == col2 && (row1 - row2).abs() == 1);
|
(col1 == col2 && (row1 - row2).abs() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapTiles(Tile tile1, Tile tile2, bool animate) {
|
void swapTiles(Tile tile1, Tile tile2, bool animate) {
|
||||||
final tempPosition = tile1.position;
|
final tempPosition1 = tile1.position.clone();
|
||||||
final tempRow = tile1.row;
|
final tempPosition2 = tile2.position.clone();
|
||||||
final tempCol = tile1.col;
|
final tempRow1 = tile1.row;
|
||||||
|
final tempCol1 = tile1.col;
|
||||||
|
final tempRow2 = tile2.row;
|
||||||
|
final tempCol2 = tile2.col;
|
||||||
|
|
||||||
tile1.position = tile2.position;
|
tile1.row = tempRow2;
|
||||||
tile1.row = tile2.row;
|
tile1.col = tempCol2;
|
||||||
tile1.col = tile2.col;
|
tile2.row = tempRow1;
|
||||||
|
tile2.col = tempCol1;
|
||||||
tile2.position = tempPosition;
|
|
||||||
tile2.row = tempRow;
|
|
||||||
tile2.col = tempCol;
|
|
||||||
|
|
||||||
tiles[tile1.row][tile1.col] = tile1;
|
tiles[tile1.row][tile1.col] = tile1;
|
||||||
tiles[tile2.row][tile2.col] = tile2;
|
tiles[tile2.row][tile2.col] = tile2;
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
tile1.animateMoveTo(tile1.position, () {});
|
tile1.animateMoveTo(tempPosition2, () {});
|
||||||
tile2.animateMoveTo(tile2.position, () {});
|
tile2.animateMoveTo(tempPosition1, () {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _checkMatches() {
|
bool checkMatches() {
|
||||||
if (animating) return false;
|
if (animating) return false; // Не проверяем совпадения, пока идет анимация
|
||||||
animating = true;
|
animating = true; // Устанавливаем флаг анимации
|
||||||
|
|
||||||
final matches = <List<int>>[];
|
final matches = <List<int>>[];
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = 0; row < rows; row++) {
|
||||||
@ -148,14 +184,14 @@ class Board extends FlameGame {
|
|||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
Future.delayed(const Duration(milliseconds: 300), () {
|
||||||
_fillEmptySpaces();
|
_fillEmptySpaces();
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
Future.delayed(const Duration(milliseconds: 300), () {
|
||||||
animating = false;
|
animating = false; // Сбрасываем флаг анимации после всех анимаций
|
||||||
_checkMatches();
|
checkMatches();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
animating = false;
|
animating = false; // Сбрасываем флаг анимации, если нет совпадений
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,6 +283,7 @@ class Board extends FlameGame {
|
|||||||
row: row,
|
row: row,
|
||||||
col: col,
|
col: col,
|
||||||
onTileTap: handleTileTap,
|
onTileTap: handleTileTap,
|
||||||
|
onSwipe: handleTileSwipe, // Добавлен обработчик свайпов
|
||||||
);
|
);
|
||||||
tiles[row][col] = tile;
|
tiles[row][col] = tile;
|
||||||
add(tile);
|
add(tile);
|
||||||
|
@ -12,7 +12,12 @@ class SwapNotifier extends ChangeNotifier {
|
|||||||
} else {
|
} else {
|
||||||
if (_isNeighbor(selectedTile!, tile)) {
|
if (_isNeighbor(selectedTile!, tile)) {
|
||||||
board.swapTiles(selectedTile!, tile, true);
|
board.swapTiles(selectedTile!, tile, true);
|
||||||
|
Future.delayed(const Duration(milliseconds: 300), () {
|
||||||
|
if (!board.checkMatches()) {
|
||||||
|
board.swapTiles(tile, selectedTile!, true);
|
||||||
|
}
|
||||||
selectedTile = null;
|
selectedTile = null;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
selectedTile?.deselect();
|
selectedTile?.deselect();
|
||||||
selectedTile = tile;
|
selectedTile = tile;
|
||||||
|
@ -3,12 +3,14 @@ import 'package:flame/effects.dart';
|
|||||||
import 'package:flame/events.dart';
|
import 'package:flame/events.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Tile extends SpriteComponent with TapCallbacks {
|
class Tile extends SpriteComponent with TapCallbacks, DragCallbacks {
|
||||||
int row;
|
int row;
|
||||||
int col;
|
int col;
|
||||||
int spriteIndex;
|
int spriteIndex;
|
||||||
final void Function(Tile) onTileTap;
|
final void Function(Tile) onTileTap;
|
||||||
|
final void Function(Tile, Vector2) onSwipe;
|
||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
|
Vector2? startDragPosition;
|
||||||
|
|
||||||
Tile({
|
Tile({
|
||||||
required Sprite sprite,
|
required Sprite sprite,
|
||||||
@ -18,6 +20,7 @@ class Tile extends SpriteComponent with TapCallbacks {
|
|||||||
required this.row,
|
required this.row,
|
||||||
required this.col,
|
required this.col,
|
||||||
required this.onTileTap,
|
required this.onTileTap,
|
||||||
|
required this.onSwipe,
|
||||||
}) : super(sprite: sprite, size: size, position: position);
|
}) : super(sprite: sprite, size: size, position: position);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -26,6 +29,22 @@ class Tile extends SpriteComponent with TapCallbacks {
|
|||||||
return true;
|
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() {
|
void select() {
|
||||||
isSelected = true;
|
isSelected = true;
|
||||||
updateBorder();
|
updateBorder();
|
||||||
|
Loading…
Reference in New Issue
Block a user