diff --git a/lib/game/components/android_acres.dart b/lib/game/components/android_acres.dart index 489dc2e5..e7330c1f 100644 --- a/lib/game/components/android_acres.dart +++ b/lib/game/components/android_acres.dart @@ -18,17 +18,17 @@ class AndroidAcres extends Component { AndroidSpaceship(position: Vector2(-26.5, -28.5)), AndroidBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-25, 1.3), AndroidBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-32.8, -9.2), AndroidBumper.cow( children: [ - ScoringBehavior(points: 20), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-20.5, -13.8), ], diff --git a/lib/game/components/bottom_group.dart b/lib/game/components/bottom_group.dart index b4a888f4..c13f21be 100644 --- a/lib/game/components/bottom_group.dart +++ b/lib/game/components/bottom_group.dart @@ -51,7 +51,7 @@ class _BottomGroupSide extends Component { final kicker = Kicker( side: _side, children: [ - ScoringBehavior(points: 5000)..applyTo(['bouncy_edge']), + ScoringBehavior(points: Points.fiveThousand)..applyTo(['bouncy_edge']), ], )..initialPosition = Vector2( (22.64 * direction) + centerXAdjustment, diff --git a/lib/game/components/dino_desert.dart b/lib/game/components/dino_desert.dart index fc601791..b3ae4ab9 100644 --- a/lib/game/components/dino_desert.dart +++ b/lib/game/components/dino_desert.dart @@ -14,7 +14,8 @@ class DinoDesert extends Component { children: [ ChromeDino( children: [ - ScoringBehavior(points: 200000)..applyTo(['inside_mouth']), + ScoringBehavior(points: Points.twoHundredThousand) + ..applyTo(['inside_mouth']), ], )..initialPosition = Vector2(12.6, -6.9), _BarrierBehindDino(), diff --git a/lib/game/components/flutter_forest/flutter_forest.dart b/lib/game/components/flutter_forest/flutter_forest.dart index 42e5415d..1fb8907b 100644 --- a/lib/game/components/flutter_forest/flutter_forest.dart +++ b/lib/game/components/flutter_forest/flutter_forest.dart @@ -18,22 +18,22 @@ class FlutterForest extends Component with ZIndex { children: [ Signpost( children: [ - ScoringBehavior(points: 20), + ScoringBehavior(points: Points.fiveThousand), ], )..initialPosition = Vector2(8.35, -58.3), DashNestBumper.main( children: [ - ScoringBehavior(points: 200000), + ScoringBehavior(points: Points.twoHundredThousand), ], )..initialPosition = Vector2(18.55, -59.35), DashNestBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(8.95, -51.95), DashNestBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(22.3, -46.75), DashAnimatronic()..position = Vector2(20, -66), diff --git a/lib/game/components/google_word/google_word.dart b/lib/game/components/google_word/google_word.dart index 2ce68263..af1faea9 100644 --- a/lib/game/components/google_word/google_word.dart +++ b/lib/game/components/google_word/google_word.dart @@ -16,27 +16,27 @@ class GoogleWord extends Component with ZIndex { children: [ GoogleLetter( 0, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-13.1, 1.72), GoogleLetter( 1, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-8.33, -0.75), GoogleLetter( 2, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-2.88, -1.85), GoogleLetter( 3, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(2.88, -1.85), GoogleLetter( 4, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(8.33, -0.75), GoogleLetter( 5, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(13.1, 1.72), GoogleWordBonusBehavior(), ], diff --git a/lib/game/components/scoring_behavior.dart b/lib/game/components/scoring_behavior.dart index 3e757eab..e8f51e90 100644 --- a/lib/game/components/scoring_behavior.dart +++ b/lib/game/components/scoring_behavior.dart @@ -12,21 +12,21 @@ import 'package:pinball_flame/pinball_flame.dart'; class ScoringBehavior extends ContactBehavior with HasGameRef { /// {@macro scoring_behavior} ScoringBehavior({ - required int points, + required Points points, }) : _points = points; - final int _points; + final Points _points; @override void beginContact(Object other, Contact contact) { super.beginContact(other, contact); if (other is! Ball) return; - gameRef.read().add(Scored(points: _points)); + gameRef.read().add(Scored(points: _points.value)); gameRef.audio.score(); gameRef.firstChild()!.add( - ScoreText( - text: _points.toString(), + ScoreComponent( + points: _points, position: other.body.position, ), ); diff --git a/lib/game/components/sparky_scorch.dart b/lib/game/components/sparky_scorch.dart index d461f95f..434e9479 100644 --- a/lib/game/components/sparky_scorch.dart +++ b/lib/game/components/sparky_scorch.dart @@ -16,17 +16,17 @@ class SparkyScorch extends Component { children: [ SparkyBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-22.9, -41.65), SparkyBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-21.25, -57.9), SparkyBumper.c( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-3.3, -52.55), SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9), @@ -47,7 +47,7 @@ class SparkyComputerSensor extends BodyComponent : super( renderBody: false, children: [ - ScoringBehavior(points: 200000), + ScoringBehavior(points: Points.twentyThousand), ], ); diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 1b8ae0f6..d8532c50 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -124,6 +124,10 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.multiplier.x5.dimmed.keyName), images.load(components.Assets.images.multiplier.x6.lit.keyName), images.load(components.Assets.images.multiplier.x6.dimmed.keyName), + images.load(components.Assets.images.score.fiveThousand.keyName), + images.load(components.Assets.images.score.twentyThousand.keyName), + images.load(components.Assets.images.score.twoHundredThousand.keyName), + images.load(components.Assets.images.score.oneMillion.keyName), images.load(dashTheme.leaderboardIcon.keyName), images.load(sparkyTheme.leaderboardIcon.keyName), images.load(androidTheme.leaderboardIcon.keyName), diff --git a/packages/pinball_components/assets/images/score/five-thousand.png b/packages/pinball_components/assets/images/score/five-thousand.png new file mode 100644 index 00000000..d373e2e1 Binary files /dev/null and b/packages/pinball_components/assets/images/score/five-thousand.png differ diff --git a/packages/pinball_components/assets/images/score/one-million.png b/packages/pinball_components/assets/images/score/one-million.png new file mode 100644 index 00000000..5c7ec15b Binary files /dev/null and b/packages/pinball_components/assets/images/score/one-million.png differ diff --git a/packages/pinball_components/assets/images/score/twenty-thousand.png b/packages/pinball_components/assets/images/score/twenty-thousand.png new file mode 100644 index 00000000..2f9bfd57 Binary files /dev/null and b/packages/pinball_components/assets/images/score/twenty-thousand.png differ diff --git a/packages/pinball_components/assets/images/score/two-hundred-thousand.png b/packages/pinball_components/assets/images/score/two-hundred-thousand.png new file mode 100644 index 00000000..a6f19db4 Binary files /dev/null and b/packages/pinball_components/assets/images/score/two-hundred-thousand.png differ diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index 4388ced6..d526909e 100644 --- a/packages/pinball_components/lib/gen/assets.gen.dart +++ b/packages/pinball_components/lib/gen/assets.gen.dart @@ -31,6 +31,7 @@ class $AssetsImagesGen { $AssetsImagesMultiplierGen get multiplier => const $AssetsImagesMultiplierGen(); $AssetsImagesPlungerGen get plunger => const $AssetsImagesPlungerGen(); + $AssetsImagesScoreGen get score => const $AssetsImagesScoreGen(); $AssetsImagesSignpostGen get signpost => const $AssetsImagesSignpostGen(); $AssetsImagesSlingshotGen get slingshot => const $AssetsImagesSlingshotGen(); $AssetsImagesSparkyGen get sparky => const $AssetsImagesSparkyGen(); @@ -201,6 +202,26 @@ class $AssetsImagesPlungerGen { const AssetGenImage('assets/images/plunger/rocket.png'); } +class $AssetsImagesScoreGen { + const $AssetsImagesScoreGen(); + + /// File path: assets/images/score/five-thousand.png + AssetGenImage get fiveThousand => + const AssetGenImage('assets/images/score/five-thousand.png'); + + /// File path: assets/images/score/one-million.png + AssetGenImage get oneMillion => + const AssetGenImage('assets/images/score/one-million.png'); + + /// File path: assets/images/score/twenty-thousand.png + AssetGenImage get twentyThousand => + const AssetGenImage('assets/images/score/twenty-thousand.png'); + + /// File path: assets/images/score/two-hundred-thousand.png + AssetGenImage get twoHundredThousand => + const AssetGenImage('assets/images/score/two-hundred-thousand.png'); +} + class $AssetsImagesSignpostGen { const $AssetsImagesSignpostGen(); diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 43ba302f..394f32ed 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -24,7 +24,7 @@ export 'layer_sensor.dart'; export 'multiplier/multiplier.dart'; export 'plunger.dart'; export 'rocket.dart'; -export 'score_text.dart'; +export 'score_component.dart'; export 'shapes/shapes.dart'; export 'signpost.dart'; export 'slingshot.dart'; diff --git a/packages/pinball_components/lib/src/components/score_component.dart b/packages/pinball_components/lib/src/components/score_component.dart new file mode 100644 index 00000000..12d198cb --- /dev/null +++ b/packages/pinball_components/lib/src/components/score_component.dart @@ -0,0 +1,92 @@ +// ignore_for_file: public_member_api_docs + +import 'dart:async'; + +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +enum Points { + fiveThousand, + twentyThousand, + twoHundredThousand, + oneMillion, +} + +/// {@template score_component} +/// A [ScoreComponent] that spawns at a given [position] with a moving +/// animation. +/// {@endtemplate} +class ScoreComponent extends SpriteComponent with HasGameRef, ZIndex { + /// {@macro score_component} + ScoreComponent({ + required this.points, + required Vector2 position, + }) : super( + position: position, + anchor: Anchor.center, + ) { + zIndex = ZIndexes.score; + } + + late final Effect _effect; + + late Points points; + + @override + Future onLoad() async { + await super.onLoad(); + final sprite = Sprite( + gameRef.images.fromCache(points.asset), + ); + this.sprite = sprite; + size = sprite.originalSize / 55; + + await add( + _effect = MoveEffect.by( + Vector2(0, -5), + EffectController(duration: 1), + ), + ); + } + + @override + void update(double dt) { + super.update(dt); + + if (_effect.controller.completed) { + removeFromParent(); + } + } +} + +extension PointsX on Points { + int get value { + switch (this) { + case Points.fiveThousand: + return 5000; + case Points.twentyThousand: + return 20000; + case Points.twoHundredThousand: + return 200000; + case Points.oneMillion: + return 1000000; + } + } +} + +extension on Points { + String get asset { + switch (this) { + case Points.fiveThousand: + return Assets.images.score.fiveThousand.keyName; + case Points.twentyThousand: + return Assets.images.score.twentyThousand.keyName; + case Points.twoHundredThousand: + return Assets.images.score.twoHundredThousand.keyName; + case Points.oneMillion: + return Assets.images.score.oneMillion.keyName; + } + } +} diff --git a/packages/pinball_components/lib/src/components/score_text.dart b/packages/pinball_components/lib/src/components/score_text.dart deleted file mode 100644 index 6dcba4b1..00000000 --- a/packages/pinball_components/lib/src/components/score_text.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'dart:async'; - -import 'package:flame/components.dart'; -import 'package:flame/effects.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart'; -import 'package:pinball_flame/pinball_flame.dart'; - -/// {@template score_text} -/// A [TextComponent] that spawns at a given [position] with a moving animation. -/// {@endtemplate} -class ScoreText extends TextComponent with ZIndex { - /// {@macro score_text} - ScoreText({ - required String text, - required Vector2 position, - this.color = Colors.black, - }) : super( - text: text, - position: position, - anchor: Anchor.center, - ) { - zIndex = ZIndexes.scoreText; - } - - late final Effect _effect; - - /// The [text]'s [Color]. - final Color color; - - @override - Future onLoad() async { - textRenderer = TextPaint( - style: TextStyle( - fontFamily: PinballFonts.pixeloidMono, - color: color, - fontSize: 4, - ), - ); - - await add( - _effect = MoveEffect.by( - Vector2(0, -5), - EffectController(duration: 1), - ), - ); - } - - @override - void update(double dt) { - super.update(dt); - - if (_effect.controller.completed) { - removeFromParent(); - } - } -} diff --git a/packages/pinball_components/lib/src/components/z_indexes.dart b/packages/pinball_components/lib/src/components/z_indexes.dart index 04dd02c7..440bd1fe 100644 --- a/packages/pinball_components/lib/src/components/z_indexes.dart +++ b/packages/pinball_components/lib/src/components/z_indexes.dart @@ -101,10 +101,10 @@ abstract class ZIndexes { static const androidBumper = _above + ballOnBoard; - // Score Text + // Score - static const scoreText = _above + spaceshipRampForegroundRailing; + static const score = _above + spaceshipRampForegroundRailing; // Debug information - static const debugInfo = _above + scoreText; + static const debugInfo = _above + score; } diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 4ca7f28e..1d2232e0 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -86,6 +86,7 @@ flutter: - assets/images/multiplier/x4/ - assets/images/multiplier/x5/ - assets/images/multiplier/x6/ + - assets/images/score/ flutter_gen: line_length: 80 diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index c123c2d9..25473f02 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -24,7 +24,7 @@ void main() { addBoundariesStories(dashbook); addGoogleWordStories(dashbook); addLaunchRampStories(dashbook); - addScoreTextStories(dashbook); + addScoreStories(dashbook); addBackboardStories(dashbook); addDinoWallStories(dashbook); addMultipliersStories(dashbook); diff --git a/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart b/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart index 639a4b57..ce14d7b6 100644 --- a/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart @@ -1,6 +1,5 @@ import 'package:flame/input.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart' hide Assets; +import 'package:pinball_components/pinball_components.dart' as components; import 'package:pinball_theme/pinball_theme.dart'; import 'package:sandbox/common/common.dart'; @@ -8,7 +7,13 @@ class BackboardGameOverGame extends AssetsGame with HasKeyboardHandlerComponents { BackboardGameOverGame(this.score, this.character) : super( - imagesFileNames: characterIconPaths.values.toList(), + imagesFileNames: [ + components.Assets.images.score.fiveThousand.keyName, + components.Assets.images.score.twentyThousand.keyName, + components.Assets.images.score.twoHundredThousand.keyName, + components.Assets.images.score.oneMillion.keyName, + ...characterIconPaths.values.toList(), + ], ); static const description = ''' @@ -30,21 +35,23 @@ class BackboardGameOverGame extends AssetsGame @override Future onLoad() async { + await super.onLoad(); + camera ..followVector2(Vector2.zero()) ..zoom = 5; await add( - Backboard.gameOver( + components.Backboard.gameOver( position: Vector2(0, 20), score: score, characterIconPath: characterIconPaths[character]!, onSubmit: (initials) { add( - ScoreText( - text: 'User $initials made $score', + components.ScoreComponent( + points: components.Points.values + .firstWhere((element) => element.value == score), position: Vector2(0, 50), - color: Colors.pink, ), ); }, diff --git a/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart b/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart index b8c85d10..9e83c7c4 100644 --- a/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart @@ -1,4 +1,5 @@ import 'package:dashbook/dashbook.dart'; +import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/backboard/backboard_game_over_game.dart'; import 'package:sandbox/stories/backboard/backboard_waiting_game.dart'; @@ -14,7 +15,11 @@ void addBackboardStories(Dashbook dashbook) { title: 'Game over', description: BackboardGameOverGame.description, gameBuilder: (context) => BackboardGameOverGame( - context.numberProperty('Score', 9000000000).toInt(), + context.listProperty( + 'Score', + Points.values.first.value, + Points.values.map((score) => score.value).toList(), + ), context.listProperty( 'Character', BackboardGameOverGame.characterIconPaths.keys.first, diff --git a/packages/pinball_components/sandbox/lib/stories/score/score_game.dart b/packages/pinball_components/sandbox/lib/stories/score/score_game.dart new file mode 100644 index 00000000..4bde5018 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/score/score_game.dart @@ -0,0 +1,44 @@ +import 'dart:math'; + +import 'package:flame/input.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; + +class ScoreGame extends AssetsGame with TapDetector { + ScoreGame() + : super( + imagesFileNames: [ + Assets.images.score.fiveThousand.keyName, + Assets.images.score.twentyThousand.keyName, + Assets.images.score.twoHundredThousand.keyName, + Assets.images.score.oneMillion.keyName, + ], + ); + + static const description = ''' + Simple game to show how score component works, + + - Tap anywhere on the screen to spawn an image on the given location. +'''; + + final random = Random(); + + @override + Future onLoad() async { + await super.onLoad(); + camera.followVector2(Vector2.zero()); + } + + @override + void onTapUp(TapUpInfo info) { + final index = random.nextInt(Points.values.length); + final score = Points.values[index]; + + add( + ScoreComponent( + points: score, + position: info.eventPosition.game..multiply(Vector2(1, -1)), + ), + ); + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/score/stories.dart b/packages/pinball_components/sandbox/lib/stories/score/stories.dart new file mode 100644 index 00000000..9c1d3c62 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/score/stories.dart @@ -0,0 +1,11 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/score/score_game.dart'; + +void addScoreStories(Dashbook dashbook) { + dashbook.storiesOf('Score').addGame( + title: 'Basic', + description: ScoreGame.description, + gameBuilder: (_) => ScoreGame(), + ); +} diff --git a/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart b/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart deleted file mode 100644 index aa776405..00000000 --- a/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'dart:math'; - -import 'package:flame/input.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart'; -import 'package:sandbox/common/common.dart'; - -class ScoreTextGame extends AssetsGame with TapDetector { - static const description = ''' - Simple game to show how score text works, - - - Tap anywhere on the screen to spawn an text on the given location. -'''; - - final random = Random(); - - @override - Future onLoad() async { - camera.followVector2(Vector2.zero()); - } - - @override - void onTapUp(TapUpInfo info) { - add( - ScoreText( - text: random.nextInt(100000).toString(), - color: Colors.white, - position: info.eventPosition.game..multiply(Vector2(1, -1)), - ), - ); - } -} diff --git a/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart b/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart deleted file mode 100644 index c4899a27..00000000 --- a/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:dashbook/dashbook.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/score_text/score_text_game.dart'; - -void addScoreTextStories(Dashbook dashbook) { - dashbook.storiesOf('ScoreText').addGame( - title: 'Basic', - description: ScoreTextGame.description, - gameBuilder: (_) => ScoreTextGame(), - ); -} diff --git a/packages/pinball_components/sandbox/lib/stories/stories.dart b/packages/pinball_components/sandbox/lib/stories/stories.dart index d8641b9c..89bf5d96 100644 --- a/packages/pinball_components/sandbox/lib/stories/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/stories.dart @@ -12,6 +12,6 @@ export 'launch_ramp/stories.dart'; export 'layer/stories.dart'; export 'multipliers/stories.dart'; export 'plunger/stories.dart'; -export 'score_text/stories.dart'; +export 'score/stories.dart'; export 'slingshot/stories.dart'; export 'sparky_scorch/stories.dart'; diff --git a/packages/pinball_components/test/src/components/golden/score/1m.png b/packages/pinball_components/test/src/components/golden/score/1m.png new file mode 100644 index 00000000..bb2f5631 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/score/1m.png differ diff --git a/packages/pinball_components/test/src/components/golden/score/200k.png b/packages/pinball_components/test/src/components/golden/score/200k.png new file mode 100644 index 00000000..c25d116b Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/score/200k.png differ diff --git a/packages/pinball_components/test/src/components/golden/score/20k.png b/packages/pinball_components/test/src/components/golden/score/20k.png new file mode 100644 index 00000000..2a4446c3 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/score/20k.png differ diff --git a/packages/pinball_components/test/src/components/golden/score/5k.png b/packages/pinball_components/test/src/components/golden/score/5k.png new file mode 100644 index 00000000..8f2a7973 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/score/5k.png differ diff --git a/packages/pinball_components/test/src/components/score_component_test.dart b/packages/pinball_components/test/src/components/score_component_test.dart new file mode 100644 index 00000000..69688874 --- /dev/null +++ b/packages/pinball_components/test/src/components/score_component_test.dart @@ -0,0 +1,202 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball_components/pinball_components.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final assets = [ + Assets.images.score.fiveThousand.keyName, + Assets.images.score.twentyThousand.keyName, + Assets.images.score.twoHundredThousand.keyName, + Assets.images.score.oneMillion.keyName, + ]; + final flameTester = FlameTester(() => TestGame(assets)); + + group('ScoreComponent', () { + flameTester.testGameWidget( + 'loads correctly', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + }, + verify: (game, tester) async { + final texts = game.descendants().whereType().length; + expect(texts, equals(1)); + }, + ); + + flameTester.testGameWidget( + 'has a movement effect', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.update(0.5); + await tester.pump(); + }, + verify: (game, tester) async { + final text = game.descendants().whereType().first; + expect(text.firstChild(), isNotNull); + }, + ); + + flameTester.testGameWidget( + 'is removed once finished', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.update(1); + game.update(0); // Ensure all component removals + await tester.pump(); + }, + verify: (game, tester) async { + expect(game.children.length, equals(0)); + }, + ); + + group('renders correctly', () { + flameTester.testGameWidget( + '5000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.fiveThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/5k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '20000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.twentyThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/20k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '200000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.twoHundredThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/200k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '1000000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/1m.png'), + ); + }, + ); + }); + }); + + group('PointsX', () { + test('5k value return 5000', () { + expect(Points.fiveThousand.value, 5000); + }); + + test('20k value return 20000', () { + expect(Points.twentyThousand.value, 20000); + }); + + test('200k value return 200000', () { + expect(Points.twoHundredThousand.value, 200000); + }); + + test('1m value return 1000000', () { + expect(Points.oneMillion.value, 1000000); + }); + }); +} diff --git a/packages/pinball_components/test/src/components/score_text_effects_test.dart b/packages/pinball_components/test/src/components/score_text_effects_test.dart deleted file mode 100644 index 7f828f1d..00000000 --- a/packages/pinball_components/test/src/components/score_text_effects_test.dart +++ /dev/null @@ -1,75 +0,0 @@ -// ignore_for_file: cascade_invocations - -import 'package:flame/components.dart'; -import 'package:flame/effects.dart'; -import 'package:flame_test/flame_test.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:pinball_components/pinball_components.dart'; - -import '../../helpers/helpers.dart'; - -void main() { - group('ScoreText', () { - final flameTester = FlameTester(TestGame.new); - - flameTester.testGameWidget( - 'renders correctly', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - }, - verify: (game, tester) async { - final texts = game.descendants().whereType().length; - expect(texts, equals(1)); - }, - ); - - flameTester.testGameWidget( - 'has a movement effect', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - - game.update(0.5); - await tester.pump(); - }, - verify: (game, tester) async { - final text = game.descendants().whereType().first; - expect(text.firstChild(), isNotNull); - }, - ); - - flameTester.testGameWidget( - 'is removed once finished', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - - game.update(1); - game.update(0); // Ensure all component removals - }, - verify: (game, tester) async { - expect(game.children.length, equals(0)); - }, - ); - }); -} diff --git a/test/game/components/scoring_behavior_test.dart b/test/game/components/scoring_behavior_test.dart index 731bb481..2afa862d 100644 --- a/test/game/components/scoring_behavior_test.dart +++ b/test/game/components/scoring_behavior_test.dart @@ -18,6 +18,14 @@ class _TestBodyComponent extends BodyComponent { } void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final assets = [ + Assets.images.score.fiveThousand.keyName, + Assets.images.score.twentyThousand.keyName, + Assets.images.score.twoHundredThousand.keyName, + Assets.images.score.oneMillion.keyName, + ]; + group('ScoringBehavior', () { group('beginContact', () { late GameBloc bloc; @@ -51,12 +59,13 @@ void main() { whenListen(bloc, Stream.value(state), initialState: state); return bloc; }, + assets: assets, ); flameBlocTester.testGameWidget( 'emits Scored event with points', setUp: (game, tester) async { - const points = 20; + const points = Points.oneMillion; final scoringBehavior = ScoringBehavior(points: points); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); @@ -66,7 +75,7 @@ void main() { verify( () => bloc.add( - const Scored(points: points), + Scored(points: points.value), ), ).called(1); }, @@ -75,8 +84,7 @@ void main() { flameBlocTester.testGameWidget( 'plays score sound', setUp: (game, tester) async { - const points = 20; - final scoringBehavior = ScoringBehavior(points: points); + final scoringBehavior = ScoringBehavior(points: Points.oneMillion); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); await game.ensureAdd(canvas); @@ -88,9 +96,9 @@ void main() { ); flameBlocTester.testGameWidget( - "adds a ScoreText component at Ball's position with points", + "adds a ScoreComponent at Ball's position with points", setUp: (game, tester) async { - const points = 20; + const points = Points.oneMillion; final scoringBehavior = ScoringBehavior(points: points); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); @@ -99,11 +107,11 @@ void main() { scoringBehavior.beginContact(ball, MockContact()); await game.ready(); - final scoreText = game.descendants().whereType(); + final scoreText = game.descendants().whereType(); expect(scoreText.length, equals(1)); expect( - scoreText.first.text, - equals(points.toString()), + scoreText.first.points, + equals(points), ); expect( scoreText.first.position,