diff --git a/assets/images/components/flipper.png b/assets/images/components/flipper.png new file mode 100644 index 00000000..f63974c4 Binary files /dev/null and b/assets/images/components/flipper.png differ diff --git a/lib/game/components/flipper.dart b/lib/game/components/flipper.dart index 9c577350..7015af47 100644 --- a/lib/game/components/flipper.dart +++ b/lib/game/components/flipper.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'dart:math' as math; +import 'package:flame/components.dart' show SpriteComponent; import 'package:flame/input.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pinball/game/game.dart'; @@ -12,19 +12,15 @@ import 'package:pinball/game/game.dart'; /// /// [Flipper] can be controlled by the player in an arc motion. /// {@endtemplate flipper} -class Flipper extends BodyComponent with KeyboardHandler { +class Flipper extends PositionBodyComponent with KeyboardHandler { /// {@macro flipper} Flipper._({ required Vector2 position, required this.side, required List keys, }) : _position = position, - _keys = keys { - // TODO(alestiago): Use sprite instead of color when provided. - paint = Paint() - ..color = const Color(0xFF00FF00) - ..style = PaintingStyle.fill; - } + _keys = keys, + super(size: Vector2(width, height)); /// A left positioned [Flipper]. Flipper.left({ @@ -50,6 +46,8 @@ class Flipper extends BodyComponent with KeyboardHandler { ], ); + static const spritePath = 'components/flipper.png'; + /// The width of the [Flipper]. static const width = 12.0; @@ -75,6 +73,20 @@ class Flipper extends BodyComponent with KeyboardHandler { /// [onKeyEvent] method listens to when one of these keys is pressed. final List _keys; + @override + Future onLoad() async { + await super.onLoad(); + final sprite = await gameRef.loadSprite(spritePath); + positionComponent = SpriteComponent( + sprite: sprite, + size: Vector2(width, height), + ); + + if (side == BoardSide.right) { + positionComponent?.flipHorizontally(); + } + } + /// Applies downward linear velocity to the [Flipper], moving it to its /// resting position. void _moveDown() { diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 964aeda1..778e2bc2 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -6,6 +6,7 @@ extension PinballGameAssetsX on PinballGame { Future preLoadAssets() async { await Future.wait([ images.load(Ball.spritePath), + images.load(Flipper.spritePath), ]); } } diff --git a/test/game/components/anchor_test.dart b/test/game/components/anchor_test.dart index 5cc37eca..a5aa7d2d 100644 --- a/test/game/components/anchor_test.dart +++ b/test/game/components/anchor_test.dart @@ -15,6 +15,7 @@ void main() { 'loads correctly', (game) async { final anchor = Anchor(position: Vector2.zero()); + await game.ready(); await game.ensureAdd(anchor); expect(game.contains(anchor), isTrue); @@ -25,6 +26,7 @@ void main() { flameTester.test( 'positions correctly', (game) async { + await game.ready(); final position = Vector2.all(10); final anchor = Anchor(position: position); await game.ensureAdd(anchor); @@ -37,6 +39,7 @@ void main() { flameTester.test( 'is static', (game) async { + await game.ready(); final anchor = Anchor(position: Vector2.zero()); await game.ensureAdd(anchor); diff --git a/test/game/components/pathway_test.dart b/test/game/components/pathway_test.dart index d3b82e96..036309b1 100644 --- a/test/game/components/pathway_test.dart +++ b/test/game/components/pathway_test.dart @@ -18,6 +18,7 @@ void main() { flameTester.test( 'has transparent color by default when no color is specified', (game) async { + await game.ready(); final pathway = Pathway.straight( position: Vector2.zero(), start: Vector2(10, 10), @@ -38,6 +39,7 @@ void main() { flameTester.test( 'has a color when is specified', (game) async { + await game.ready(); const defaultColor = Colors.blue; final pathway = Pathway.straight( @@ -59,6 +61,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { + await game.ready(); final pathway = Pathway.straight( position: Vector2.zero(), start: Vector2(10, 10), @@ -75,6 +78,7 @@ void main() { flameTester.test( 'positions correctly', (game) async { + await game.ready(); final position = Vector2.all(10); final pathway = Pathway.straight( position: position, @@ -92,6 +96,7 @@ void main() { flameTester.test( 'is static', (game) async { + await game.ready(); final pathway = Pathway.straight( position: Vector2.zero(), start: Vector2(10, 10), @@ -109,6 +114,7 @@ void main() { flameTester.test( 'has only one ChainShape when singleWall is true', (game) async { + await game.ready(); final pathway = Pathway.straight( position: Vector2.zero(), start: Vector2(10, 10), @@ -128,6 +134,7 @@ void main() { flameTester.test( 'has two ChainShape when singleWall is false (default)', (game) async { + await game.ready(); final pathway = Pathway.straight( position: Vector2.zero(), start: Vector2(10, 10), @@ -150,6 +157,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { + await game.ready(); final pathway = Pathway.arc( position: Vector2.zero(), width: width, @@ -166,6 +174,7 @@ void main() { flameTester.test( 'positions correctly', (game) async { + await game.ready(); final position = Vector2.all(10); final pathway = Pathway.arc( position: position, @@ -183,6 +192,7 @@ void main() { flameTester.test( 'is static', (game) async { + await game.ready(); final pathway = Pathway.arc( position: Vector2.zero(), width: width, @@ -208,6 +218,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { + await game.ready(); final pathway = Pathway.bezierCurve( position: Vector2.zero(), controlPoints: controlPoints, @@ -223,6 +234,7 @@ void main() { flameTester.test( 'positions correctly', (game) async { + await game.ready(); final position = Vector2.all(10); final pathway = Pathway.bezierCurve( position: position, @@ -239,6 +251,7 @@ void main() { flameTester.test( 'is static', (game) async { + await game.ready(); final pathway = Pathway.bezierCurve( position: Vector2.zero(), controlPoints: controlPoints, diff --git a/test/game/components/plunger_test.dart b/test/game/components/plunger_test.dart index 67e215fd..835bbc65 100644 --- a/test/game/components/plunger_test.dart +++ b/test/game/components/plunger_test.dart @@ -16,6 +16,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { + await game.ready(); final plunger = Plunger(position: Vector2.zero()); await game.ensureAdd(plunger); diff --git a/test/game/components/wall_test.dart b/test/game/components/wall_test.dart index 8151055e..7f3c1c9c 100644 --- a/test/game/components/wall_test.dart +++ b/test/game/components/wall_test.dart @@ -37,6 +37,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { + await game.ready(); final wall = Wall( start: Vector2.zero(), end: Vector2(100, 0),