- Add proper validation for null gems during swap operations - Implement swap-back animation for invalid moves (no matches) - Restructure swap flow to emit animation states before match detection - Add move limit validation before processing matches - Improve error handling and logging for edge cases
87 lines
2.2 KiB
Dart
87 lines
2.2 KiB
Dart
import 'dart:ui';
|
|
|
|
import 'package:flame/game.dart';
|
|
import 'package:match_three/game/components/gem_component.dart';
|
|
import 'package:match_three/game/systems/match_detector.dart';
|
|
import 'components/grid_component.dart';
|
|
import 'components/background_component.dart';
|
|
import 'models/gem.dart';
|
|
import '../bloc/game_bloc.dart';
|
|
|
|
const gridSize = 8 * 64.0 + 32.0; // 8 gems * 64px + padding
|
|
|
|
class MatchThreeGame extends FlameGame {
|
|
late BackgroundComponent backgroundComponent;
|
|
late GameBloc gameBloc;
|
|
final int levelId;
|
|
final int gridHeight;
|
|
final int gridWidth;
|
|
GridComponent? gridComponent;
|
|
Gem? selectedGem;
|
|
|
|
MatchThreeGame(
|
|
{required this.levelId,
|
|
required this.gridHeight,
|
|
required this.gridWidth})
|
|
: super();
|
|
|
|
@override
|
|
Future<void> onLoad() async {
|
|
backgroundComponent = BackgroundComponent();
|
|
add(backgroundComponent);
|
|
|
|
gridComponent = GridComponent(this, levelId, gridHeight, gridWidth);
|
|
add(gridComponent!);
|
|
}
|
|
|
|
@override
|
|
void onGameResize(Vector2 size) {
|
|
super.onGameResize(size);
|
|
// Center the grid on screen
|
|
if (gridComponent != null && hasLayout) {
|
|
gridComponent!.position = Vector2(
|
|
(size.x - gridSize) / 2,
|
|
(size.y - gridSize) / 2,
|
|
);
|
|
}
|
|
}
|
|
|
|
void selectGem(Gem gem) {
|
|
print(">>> Selecting gem ${gem.name}(${gem.type}) ${gem.row}, ${gem.col}");
|
|
if (selectedGem == null) {
|
|
selectedGem = gem;
|
|
return;
|
|
}
|
|
var theGem = selectedGem;
|
|
selectedGem = null;
|
|
if (MatchDetector.isValidSwap(
|
|
gridComponent!.gameGrid, theGem!.row, theGem.col, gem.row, gem.col)) {
|
|
// Attempt swap
|
|
print(
|
|
")) Valid swapping ${theGem.row}, ${theGem.col} with ${gem.row}, ${gem.col}");
|
|
|
|
gameBloc.add(SwapGems(
|
|
theGem.row,
|
|
theGem.col,
|
|
gem.row,
|
|
gem.col,
|
|
));
|
|
} else {
|
|
print(
|
|
"(( Invalid swapping ${theGem.row}, ${theGem.col} with ${gem.row}, ${gem.col}");
|
|
}
|
|
if (gridComponent == null) {
|
|
return;
|
|
}
|
|
for (var comp in gridComponent!.children) {
|
|
if (comp is GemComponent && comp.gem != gem) {
|
|
comp.isSelected = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void setGameBloc(GameBloc bloc) {
|
|
gameBloc = bloc;
|
|
}
|
|
}
|