mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-31 08:56:01 +08:00 
			
		
		
		
	 b283b82f6c
			
		
	
	b283b82f6c
	
	
	
		
			
			Replaces the switch cases that can be replaces with switch expressions and removes `break;` where it isn't needed. https://dart.dev/language/branches#switch-statements
		
			
				
	
	
		
			267 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'dart:math';
 | |
| import 'dart:ui';
 | |
| 
 | |
| import 'package:flame/components.dart';
 | |
| import 'package:flame/events.dart';
 | |
| import '../klondike_game.dart';
 | |
| import '../pile.dart';
 | |
| import '../rank.dart';
 | |
| import '../suit.dart';
 | |
| import 'tableau_pile.dart';
 | |
| 
 | |
| class Card extends PositionComponent with DragCallbacks {
 | |
|   Card(int intRank, int intSuit)
 | |
|       : rank = Rank.fromInt(intRank),
 | |
|         suit = Suit.fromInt(intSuit),
 | |
|         super(size: KlondikeGame.cardSize);
 | |
| 
 | |
|   final Rank rank;
 | |
|   final Suit suit;
 | |
|   Pile? pile;
 | |
|   bool _faceUp = false;
 | |
|   bool _isDragging = false;
 | |
|   final List<Card> attachedCards = [];
 | |
| 
 | |
|   bool get isFaceUp => _faceUp;
 | |
|   bool get isFaceDown => !_faceUp;
 | |
|   void flip() => _faceUp = !_faceUp;
 | |
| 
 | |
|   @override
 | |
|   String toString() => rank.label + suit.label; // e.g. "Q♠" or "10♦"
 | |
| 
 | |
|   //#region Rendering
 | |
| 
 | |
|   @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();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //#endregion
 | |
| 
 | |
|   //#region Dragging
 | |
| 
 | |
|   @override
 | |
|   void onDragStart(DragStartEvent event) {
 | |
|     super.onDragStart(event);
 | |
|     if (pile?.canMoveCard(this) ?? false) {
 | |
|       _isDragging = true;
 | |
|       priority = 100;
 | |
|       if (pile is TableauPile) {
 | |
|         attachedCards.clear();
 | |
|         final extraCards = (pile! as TableauPile).cardsOnTop(this);
 | |
|         for (final card in extraCards) {
 | |
|           card.priority = attachedCards.length + 101;
 | |
|           attachedCards.add(card);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onDragUpdate(DragUpdateEvent event) {
 | |
|     if (!_isDragging) {
 | |
|       return;
 | |
|     }
 | |
|     final delta = event.localDelta;
 | |
|     position.add(delta);
 | |
|     attachedCards.forEach((card) => card.position.add(delta));
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onDragEnd(DragEndEvent event) {
 | |
|     super.onDragEnd(event);
 | |
|     if (!_isDragging) {
 | |
|       return;
 | |
|     }
 | |
|     _isDragging = false;
 | |
|     final dropPiles = parent!
 | |
|         .componentsAtPoint(position + size / 2)
 | |
|         .whereType<Pile>()
 | |
|         .toList();
 | |
|     if (dropPiles.isNotEmpty) {
 | |
|       if (dropPiles.first.canAcceptCard(this)) {
 | |
|         pile!.removeCard(this);
 | |
|         dropPiles.first.acquireCard(this);
 | |
|         if (attachedCards.isNotEmpty) {
 | |
|           attachedCards.forEach((card) => dropPiles.first.acquireCard(card));
 | |
|           attachedCards.clear();
 | |
|         }
 | |
|         return;
 | |
|       }
 | |
|     }
 | |
|     pile!.returnCard(this);
 | |
|     if (attachedCards.isNotEmpty) {
 | |
|       attachedCards.forEach((card) => pile!.returnCard(card));
 | |
|       attachedCards.clear();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //#endregion
 | |
| }
 |