118 lines
3.0 KiB
Dart
118 lines
3.0 KiB
Dart
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<String, Sprite> sprites = {};
|
|
late SpriteComponent selectedTile;
|
|
bool hasSelectedTile = false;
|
|
final selectedPaint = Paint()..color = Colors.white.withOpacity(0.5);
|
|
|
|
@override
|
|
Future<void> onLoad() async {
|
|
await super.onLoad();
|
|
await loadImages();
|
|
loadGrid();
|
|
}
|
|
|
|
Future<void> 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<SpriteComponent>()
|
|
.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;
|
|
}
|
|
}
|
|
}
|
|
}
|