boardgames_app/lib/games/checkers.dart
2025-06-14 14:28:16 +02:00

121 lines
3.7 KiB
Dart

import 'dart:async';
import 'dart:math';
import 'package:boardgames_app/components/checker_board.dart';
import 'package:boardgames_app/components/checker_comp.dart';
import 'package:boardgames_app/components/empty_cell.dart';
import 'package:boardgames_app/network/channel.dart';
import 'package:boardgames_app/utils/commons.dart';
import 'package:boardgames_core/core.dart';
import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/extensions.dart';
import 'package:flame/game.dart';
import 'package:boardgames_core/commons.dart';
import 'package:boardgames_core/games.dart';
import 'package:flame/palette.dart';
import 'package:flutter/widgets.dart';
final style = TextStyle(color: BasicPalette.white.color, fontSize: 34);
final regular = TextPaint(style: style);
class CheckersGame extends FlameGame with HasTappables {
final Checkers boardGame;
bool finished = false;
Player? winner;
CheckersGame(Checkers thegame) : boardGame = thegame;
Future<void> makeMove(Checker? checker, CellPosition? position) async {
if (checker != null && position != null) {
checker.moveTo(position);
await Channel.send({
"event": "move",
"game_id": boardGame.id,
"player": boardGame.currentPlayer?.id,
"checker": checker.id,
"from": checker.position.toJSON(),
"to": position.toJSON(),
});
}
await boardGame.endTurn();
removeAll(children);
var gameSize = size.toSize();
var maxSide = max(gameSize.width, gameSize.height);
if (boardGame.hasGameFinished()) {
finished = true;
winner = boardGame.getWinners().first;
add(TextComponent(
text: 'Player ${winner!.id} won!', textRenderer: regular)
..anchor = Anchor.center
..x = maxSide / 2
..y = maxSide / 2);
return;
}
final board = boardGame.board;
final rows = board.geometry.rows;
final cols = board.geometry.columns;
var checkerSize = maxSide / 8;
add(
CheckerBoard(board.geometry.columns, board.geometry.columns)
..position = Offset.zero.toVector2()
..size = Size(checkerSize * board.geometry.columns,
checkerSize * board.geometry.columns)
.toVector2(),
);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
final els = board.getElementsAtPosition(CellPosition(col, row));
add(EmptyCell(board, CellPosition(col, row))
..position = Vector2(checkerSize * col, checkerSize * row)
..size = Vector2(checkerSize, checkerSize));
if (els.isNotEmpty) {
// Only one element in checkers
final el = els.first;
add(CheckerComp(el)
..anchor = Anchor.topLeft
..position = Vector2(checkerSize * col, checkerSize * row)
..size = Vector2(checkerSize, checkerSize));
}
}
boardGame.beginTurn();
}
await boardGame.beginTurn();
}
CheckerComp? getSelectedChecker() {
return findWhere(children.toList(),
(element) => element is CheckerComp && element.selected)
as CheckerComp?;
}
@override
void onTapDown(int pointerId, TapDownInfo info) {
super.onTapDown(pointerId, info);
final selected = getSelectedChecker();
for (var element in children) {
if (element is EmptyCell) {
element.checkHightlight(selected?.checker);
}
}
}
@override
Future<void> onLoad() async {
// Dimenstions
var gameSize = size.toSize();
var maxSide = max(gameSize.width, gameSize.height);
// TODO: Start usign world
camera.viewport = FixedResolutionViewport(Vector2.all(maxSide));
// TODO: Add Game menu
// overlays.add("${GameOverlay.gameMenu}");
await makeMove(null, null);
}
}