2024-09-27 13:40:14 +00:00
|
|
|
import 'dart:math';
|
|
|
|
|
2024-08-05 08:04:54 +00:00
|
|
|
import 'package:flame/components.dart';
|
|
|
|
import 'package:flame/effects.dart';
|
|
|
|
import 'package:flame/events.dart';
|
2024-09-27 13:40:14 +00:00
|
|
|
import 'package:flame/flame.dart';
|
2024-08-05 08:04:54 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2024-08-16 16:09:24 +00:00
|
|
|
import 'board.dart';
|
2024-08-05 08:04:54 +00:00
|
|
|
|
2024-08-08 20:50:55 +00:00
|
|
|
class Tile extends SpriteComponent with TapCallbacks, DragCallbacks {
|
2024-08-05 08:04:54 +00:00
|
|
|
int row;
|
|
|
|
int col;
|
|
|
|
int spriteIndex;
|
2024-08-29 13:44:44 +00:00
|
|
|
// final void Function(Tile) onTileTap;
|
2024-08-08 20:50:55 +00:00
|
|
|
final void Function(Tile, Vector2) onSwipe;
|
2024-08-06 18:00:51 +00:00
|
|
|
bool isSelected = false;
|
2024-08-16 16:09:24 +00:00
|
|
|
bool isBomb = false;
|
|
|
|
bool isMagicCube = false;
|
2024-08-08 20:50:55 +00:00
|
|
|
Vector2? startDragPosition;
|
2024-08-05 08:04:54 +00:00
|
|
|
|
2024-08-29 13:44:44 +00:00
|
|
|
bool isAnimating = false;
|
|
|
|
|
2024-08-05 08:04:54 +00:00
|
|
|
Tile({
|
|
|
|
required Sprite sprite,
|
|
|
|
required this.spriteIndex,
|
|
|
|
required Vector2 size,
|
|
|
|
required Vector2 position,
|
|
|
|
required this.row,
|
|
|
|
required this.col,
|
2024-08-29 13:44:44 +00:00
|
|
|
// required this.onTileTap,
|
2024-08-08 20:50:55 +00:00
|
|
|
required this.onSwipe,
|
2024-09-27 13:40:14 +00:00
|
|
|
}) : super(
|
|
|
|
sprite: sprite,
|
|
|
|
size: size,
|
|
|
|
position: position,
|
|
|
|
) {
|
|
|
|
// final randomSpriteIndex = _random.nextInt(crystals.length);
|
|
|
|
// tile = isMagicCube ? crystals[randomSpriteIndex] : magicCube();
|
|
|
|
}
|
2024-08-05 08:04:54 +00:00
|
|
|
|
2024-09-27 13:40:14 +00:00
|
|
|
// static final Random _random = Random();
|
|
|
|
late Sprite tile;
|
2024-08-29 13:44:44 +00:00
|
|
|
// @override
|
|
|
|
// bool onTapDown(TapDownEvent event) {
|
|
|
|
// if (isAnimating || (parent is Board && (parent as Board).animating)) {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// onTileTap(this);
|
|
|
|
// return true;
|
|
|
|
// }
|
2024-08-05 08:04:54 +00:00
|
|
|
|
2024-09-27 13:40:14 +00:00
|
|
|
static List<Sprite> crystals = [
|
|
|
|
crystal1(),
|
|
|
|
crystal2(),
|
|
|
|
crystal3(),
|
|
|
|
crystal4(),
|
|
|
|
crystal5(),
|
|
|
|
crystal6(),
|
|
|
|
crystal7(),
|
|
|
|
];
|
|
|
|
|
|
|
|
static Sprite magicCubeSprite = magicCube();
|
|
|
|
|
2024-08-08 20:50:55 +00:00
|
|
|
@override
|
|
|
|
bool onDragStart(DragStartEvent event) {
|
2024-08-29 13:44:44 +00:00
|
|
|
if (isAnimating || (parent as Board).animating) {
|
2024-08-16 16:09:24 +00:00
|
|
|
return false;
|
|
|
|
}
|
2024-08-29 13:44:44 +00:00
|
|
|
super.onDragStart(event);
|
2024-08-08 20:50:55 +00:00
|
|
|
startDragPosition = event.localPosition;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
bool onDragEnd(DragEndEvent event) {
|
2024-08-29 13:44:44 +00:00
|
|
|
if (isAnimating || (parent as Board).animating) {
|
|
|
|
return false;
|
|
|
|
}
|
2024-08-16 16:09:24 +00:00
|
|
|
super.onDragEnd(event);
|
2024-08-08 20:50:55 +00:00
|
|
|
if (startDragPosition != null) {
|
|
|
|
final delta = event.velocity;
|
|
|
|
onSwipe(this, delta);
|
|
|
|
}
|
|
|
|
startDragPosition = null;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-09-04 12:11:40 +00:00
|
|
|
// void select() {
|
|
|
|
// isSelected = true;
|
|
|
|
// updateBorder();
|
|
|
|
// }
|
|
|
|
|
2024-08-06 18:00:51 +00:00
|
|
|
void select() {
|
2024-09-04 12:11:40 +00:00
|
|
|
final effectController = EffectController(
|
|
|
|
duration: 0.3,
|
|
|
|
repeatCount: 2,
|
|
|
|
reverseDuration: 0.3,
|
|
|
|
);
|
|
|
|
|
|
|
|
final blinkEffect = OpacityEffect.to(
|
|
|
|
0.0,
|
|
|
|
effectController,
|
|
|
|
);
|
|
|
|
|
|
|
|
add(blinkEffect);
|
2024-08-06 18:00:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void deselect() {
|
|
|
|
isSelected = false;
|
|
|
|
updateBorder();
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateBorder() {
|
|
|
|
if (isSelected) {
|
|
|
|
add(RectangleComponent(
|
|
|
|
size: size,
|
|
|
|
paint: Paint()
|
|
|
|
..color = Colors.yellow
|
|
|
|
..style = PaintingStyle.stroke
|
|
|
|
..strokeWidth = 3,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
children.removeWhere((child) => child is RectangleComponent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-05 08:04:54 +00:00
|
|
|
void animateMoveTo(Vector2 newPosition, VoidCallback onComplete) {
|
2024-08-29 13:44:44 +00:00
|
|
|
isAnimating = true;
|
2024-08-05 08:04:54 +00:00
|
|
|
add(MoveEffect.to(
|
|
|
|
newPosition,
|
2024-08-06 18:00:51 +00:00
|
|
|
EffectController(duration: 0.3),
|
2024-08-29 13:44:44 +00:00
|
|
|
onComplete: () {
|
|
|
|
isAnimating = false;
|
|
|
|
onComplete();
|
|
|
|
},
|
2024-08-06 18:00:51 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2024-08-29 13:44:44 +00:00
|
|
|
// void animateRemove(VoidCallback onComplete) {
|
|
|
|
// isAnimating = true;
|
|
|
|
// add(RemoveEffect(
|
|
|
|
// delay: 0.5,
|
|
|
|
// onComplete: () {
|
|
|
|
// isAnimating = false;
|
|
|
|
// onComplete();
|
|
|
|
// },
|
|
|
|
// ));
|
|
|
|
// }
|
2024-08-05 08:04:54 +00:00
|
|
|
}
|
2024-09-27 13:40:14 +00:00
|
|
|
|
|
|
|
Sprite crystal1() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal1.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal2() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal2.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal3() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal3.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal4() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal4.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal5() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal5.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal6() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal6.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite crystal7() {
|
|
|
|
return Sprite(Flame.images.fromCache('crystal7.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite magicCube() {
|
|
|
|
return Sprite(Flame.images.fromCache('magic_cube.png'));
|
|
|
|
}
|