import 'package:flame/components.dart'; import 'package:flame/events.dart'; import 'package:flame/flame.dart'; import 'package:flame/game.dart'; import 'package:match_magic/models/game_state.dart'; import 'package:flutter/material.dart'; import 'dart:ui'; class MatchMagicGame extends FlameGame with TapDetector { final GameState gameState; MatchMagicGame(this.gameState); late double tileSize; late double gridWidth; late double gridHeight; late double gridOffsetX; late double gridOffsetY; final Map sprites = {}; late SpriteComponent selectedTile; bool hasSelectedTile = false; final selectedPaint = Paint()..color = Colors.white.withOpacity(0.5); @override Future onLoad() async { await super.onLoad(); await loadImages(); loadGrid(); } Future loadImages() async { final imageNames = [ 'crystal1.png', 'crystal2.png', 'crystal3.png', 'crystal4.png', 'crystal5.png', 'crystal6.png', 'crystal0.png', ]; for (var name in imageNames) { final sprite = Sprite(await Flame.images.load(name)); sprites[name] = sprite; } } void loadGrid() { tileSize = size.x / gameState.cols; gridWidth = tileSize * gameState.cols; gridHeight = tileSize * gameState.rows; gridOffsetX = (size.x - gridWidth) / 2; gridOffsetY = (size.y - gridHeight) / 2; addGrid(); } void addGrid() { children .whereType() .forEach((component) => component.removeFromParent()); for (var row = 0; row < gameState.rows; row++) { for (var col = 0; col < gameState.cols; col++) { final value = gameState.grid[row][col]; final spriteName = 'crystal$value.png'; final sprite = sprites[spriteName]; final spriteComponent = SpriteComponent() ..sprite = sprite ..width = tileSize ..height = tileSize ..x = gridOffsetX + col * tileSize ..y = gridOffsetY + row * tileSize; add(spriteComponent); } } } @override void render(Canvas canvas) { super.render(canvas); if (hasSelectedTile) { canvas.drawRect( Rect.fromLTWH( selectedTile.x, selectedTile.y, tileSize, tileSize, ), selectedPaint, ); } } @override void onTapDown(TapDownInfo info) { final x = info.eventPosition.global.x; final y = info.eventPosition.global.y; final col = ((x - gridOffsetX) / tileSize).floor(); final row = ((y - gridOffsetY) / tileSize).floor(); if (col >= 0 && col < gameState.cols && row >= 0 && row < gameState.rows) { if (hasSelectedTile) { gameState.selectElement(row, col); hasSelectedTile = false; addGrid(); } else { selectedTile = SpriteComponent() ..x = gridOffsetX + col * tileSize ..y = gridOffsetY + row * tileSize ..width = tileSize ..height = tileSize; hasSelectedTile = true; } } } }