import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flame/events.dart'; import 'package:flutter/material.dart'; import '../models/gem.dart'; import '../systems/physics_system.dart'; import 'grid_component.dart'; import 'particle_system.dart'; import '../../utils/constants.dart'; class GemComponent extends RectangleComponent with TapCallbacks { final Gem gem; final GridComponent gridComponent; bool isSelected = false; static const List gemColors = [ Colors.red, Colors.blue, Colors.green, Colors.yellow, Colors.purple, Colors.orange, ]; GemComponent({required this.gem, required this.gridComponent}) : super( size: Vector2.all(GameConstants.gemSize - 4), paint: Paint()..color = gemColors[gem.type % gemColors.length], ); @override bool onTapDown(TapDownEvent event) { if (!gridComponent.canInterract) return false; gridComponent.onGemTapped(gem); _animateSelection(); PhysicsSystem.animatePop(this); return true; } void _animateSelection() { isSelected = !isSelected; final scaleEffect = ScaleEffect.to( Vector2.all(isSelected ? 1.1 : 1.0), EffectController(duration: 0.2), ); add(scaleEffect); } animateMatch() async { // Add particle explosion final explosion = ParticleSystem.createMatchExplosion( position + size / 2, gemColors[gem.type % gemColors.length], ); parent?.add(explosion); // Animate gem destruction PhysicsSystem.animateMatch(this); // Remove after animation await Future.delayed( Duration(milliseconds: (GameConstants.matchDuration * 1000).round()), () { removeFromParent(); }); } animateFall(Vector2 targetPosition) async { await PhysicsSystem.animateFall(this, targetPosition); } animateCombo() { final comboEffect = ParticleSystem.createComboEffect(position + size / 2); parent?.add(comboEffect); } @override void render(Canvas canvas) { super.render(canvas); // Add gradient effect final gradient = RadialGradient( colors: [ gemColors[gem.type % gemColors.length].withOpacity(0.9), gemColors[gem.type % gemColors.length], ], ); final gradientPaint = Paint() ..shader = gradient.createShader(size.toRect()); canvas.drawRRect( RRect.fromRectAndRadius( size.toRect(), const Radius.circular(8), ), gradientPaint, ); // Add border and glow effect final borderColor = isSelected ? Colors.white : Colors.black26; final borderWidth = isSelected ? 3.0 : 1.0; canvas.drawRRect( RRect.fromRectAndRadius( size.toRect(), const Radius.circular(8), ), Paint() ..color = borderColor ..style = PaintingStyle.stroke ..strokeWidth = borderWidth, ); if (isSelected) { canvas.drawRRect( RRect.fromRectAndRadius( size.toRect().inflate(2), const Radius.circular(10), ), Paint() ..color = Colors.white.withOpacity(0.3) ..style = PaintingStyle.stroke ..strokeWidth = 2, ); } // Add shine effect final shinePaint = Paint() ..color = Colors.white.withOpacity(0.3) ..style = PaintingStyle.fill; canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(size.x * 0.2, size.y * 0.1, size.x * 0.3, size.y * 0.2), const Radius.circular(4), ), shinePaint, ); } }