import 'dart:math'; import 'dart:ui'; import 'package:flame/components.dart'; import '../klondike_game.dart'; import '../rank.dart'; import '../suit.dart'; class Card extends PositionComponent { Card(int intRank, int intSuit) : rank = Rank.fromInt(intRank), suit = Suit.fromInt(intSuit), _faceUp = false, super(size: KlondikeGame.cardSize); final Rank rank; final Suit suit; bool _faceUp; bool get isFaceUp => _faceUp; void flip() => _faceUp = !_faceUp; @override String toString() => rank.label + suit.label; // e.g. "Q♠" or "10♦" @override void render(Canvas canvas) { if (_faceUp) { _renderFront(canvas); } else { _renderBack(canvas); } } static final Paint backBackgroundPaint = Paint() ..color = const Color(0xff380c02); static final Paint backBorderPaint1 = Paint() ..color = const Color(0xffdbaf58) ..style = PaintingStyle.stroke ..strokeWidth = 10; static final Paint backBorderPaint2 = Paint() ..color = const Color(0x5CEF971B) ..style = PaintingStyle.stroke ..strokeWidth = 35; static final RRect cardRRect = RRect.fromRectAndRadius( KlondikeGame.cardSize.toRect(), const Radius.circular(KlondikeGame.cardRadius), ); static final RRect backRRectInner = cardRRect.deflate(40); static final Sprite flameSprite = klondikeSprite(1367, 6, 357, 501); void _renderBack(Canvas canvas) { canvas.drawRRect(cardRRect, backBackgroundPaint); canvas.drawRRect(cardRRect, backBorderPaint1); canvas.drawRRect(backRRectInner, backBorderPaint2); flameSprite.render(canvas, position: size / 2, anchor: Anchor.center); } static final Paint frontBackgroundPaint = Paint() ..color = const Color(0xff000000); static final Paint redBorderPaint = Paint() ..color = const Color(0xffece8a3) ..style = PaintingStyle.stroke ..strokeWidth = 10; static final Paint blackBorderPaint = Paint() ..color = const Color(0xff7ab2e8) ..style = PaintingStyle.stroke ..strokeWidth = 10; static final blueFilter = Paint() ..colorFilter = const ColorFilter.mode( Color(0x880d8bff), BlendMode.srcATop, ); static final Sprite redJack = klondikeSprite(81, 565, 562, 488); static final Sprite redQueen = klondikeSprite(717, 541, 486, 515); static final Sprite redKing = klondikeSprite(1305, 532, 407, 549); static final Sprite blackJack = klondikeSprite(81, 565, 562, 488) ..paint = blueFilter; static final Sprite blackQueen = klondikeSprite(717, 541, 486, 515) ..paint = blueFilter; static final Sprite blackKing = klondikeSprite(1305, 532, 407, 549) ..paint = blueFilter; void _renderFront(Canvas canvas) { canvas.drawRRect(cardRRect, frontBackgroundPaint); canvas.drawRRect( cardRRect, suit.isRed ? redBorderPaint : blackBorderPaint, ); final rankSprite = suit.isBlack ? rank.blackSprite : rank.redSprite; final suitSprite = suit.sprite; _drawSprite(canvas, rankSprite, 0.1, 0.08); _drawSprite(canvas, suitSprite, 0.1, 0.18, scale: 0.5); _drawSprite(canvas, rankSprite, 0.1, 0.08, rotate: true); _drawSprite(canvas, suitSprite, 0.1, 0.18, scale: 0.5, rotate: true); switch (rank.value) { case 1: _drawSprite(canvas, suitSprite, 0.5, 0.5, scale: 2.5); case 2: _drawSprite(canvas, suitSprite, 0.5, 0.25); _drawSprite(canvas, suitSprite, 0.5, 0.25, rotate: true); case 3: _drawSprite(canvas, suitSprite, 0.5, 0.2); _drawSprite(canvas, suitSprite, 0.5, 0.5); _drawSprite(canvas, suitSprite, 0.5, 0.2, rotate: true); case 4: _drawSprite(canvas, suitSprite, 0.3, 0.25); _drawSprite(canvas, suitSprite, 0.7, 0.25); _drawSprite(canvas, suitSprite, 0.3, 0.25, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.25, rotate: true); case 5: _drawSprite(canvas, suitSprite, 0.3, 0.25); _drawSprite(canvas, suitSprite, 0.7, 0.25); _drawSprite(canvas, suitSprite, 0.3, 0.25, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.25, rotate: true); _drawSprite(canvas, suitSprite, 0.5, 0.5); case 6: _drawSprite(canvas, suitSprite, 0.3, 0.25); _drawSprite(canvas, suitSprite, 0.7, 0.25); _drawSprite(canvas, suitSprite, 0.3, 0.5); _drawSprite(canvas, suitSprite, 0.7, 0.5); _drawSprite(canvas, suitSprite, 0.3, 0.25, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.25, rotate: true); case 7: _drawSprite(canvas, suitSprite, 0.3, 0.2); _drawSprite(canvas, suitSprite, 0.7, 0.2); _drawSprite(canvas, suitSprite, 0.5, 0.35); _drawSprite(canvas, suitSprite, 0.3, 0.5); _drawSprite(canvas, suitSprite, 0.7, 0.5); _drawSprite(canvas, suitSprite, 0.3, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.2, rotate: true); case 8: _drawSprite(canvas, suitSprite, 0.3, 0.2); _drawSprite(canvas, suitSprite, 0.7, 0.2); _drawSprite(canvas, suitSprite, 0.5, 0.35); _drawSprite(canvas, suitSprite, 0.3, 0.5); _drawSprite(canvas, suitSprite, 0.7, 0.5); _drawSprite(canvas, suitSprite, 0.3, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.5, 0.35, rotate: true); case 9: _drawSprite(canvas, suitSprite, 0.3, 0.2); _drawSprite(canvas, suitSprite, 0.7, 0.2); _drawSprite(canvas, suitSprite, 0.5, 0.3); _drawSprite(canvas, suitSprite, 0.3, 0.4); _drawSprite(canvas, suitSprite, 0.7, 0.4); _drawSprite(canvas, suitSprite, 0.3, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.3, 0.4, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.4, rotate: true); case 10: _drawSprite(canvas, suitSprite, 0.3, 0.2); _drawSprite(canvas, suitSprite, 0.7, 0.2); _drawSprite(canvas, suitSprite, 0.5, 0.3); _drawSprite(canvas, suitSprite, 0.3, 0.4); _drawSprite(canvas, suitSprite, 0.7, 0.4); _drawSprite(canvas, suitSprite, 0.3, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.2, rotate: true); _drawSprite(canvas, suitSprite, 0.5, 0.3, rotate: true); _drawSprite(canvas, suitSprite, 0.3, 0.4, rotate: true); _drawSprite(canvas, suitSprite, 0.7, 0.4, rotate: true); case 11: _drawSprite(canvas, suit.isRed ? redJack : blackJack, 0.5, 0.5); case 12: _drawSprite(canvas, suit.isRed ? redQueen : blackQueen, 0.5, 0.5); case 13: _drawSprite(canvas, suit.isRed ? redKing : blackKing, 0.5, 0.5); } } void _drawSprite( Canvas canvas, Sprite sprite, double relativeX, double relativeY, { double scale = 1, bool rotate = false, }) { if (rotate) { canvas.save(); canvas.translate(size.x / 2, size.y / 2); canvas.rotate(pi); canvas.translate(-size.x / 2, -size.y / 2); } sprite.render( canvas, position: Vector2(relativeX * size.x, relativeY * size.y), anchor: Anchor.center, size: sprite.srcSize.scaled(scale), ); if (rotate) { canvas.restore(); } } }