diff --git a/assets/images/components/plunger.png b/assets/images/components/plunger.png new file mode 100644 index 00000000..f3cbdf0f Binary files /dev/null and b/assets/images/components/plunger.png differ diff --git a/lib/game/components/plunger.dart b/lib/game/components/plunger.dart index 9b7eec39..b319af80 100644 --- a/lib/game/components/plunger.dart +++ b/lib/game/components/plunger.dart @@ -1,8 +1,8 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball/gen/assets.gen.dart'; +import 'package:pinball_components/pinball_components.dart' hide Assets; /// {@template plunger} /// [Plunger] serves as a spring, that shoots the ball on the right side of the @@ -14,10 +14,9 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { /// {@macro plunger} Plunger({ required this.compressionDistance, - }) : super( - // TODO(allisonryan0002): remove paint after asset is added. - paint: Paint()..color = const Color.fromARGB(255, 241, 8, 8), - ); + // TODO(ruimiguel): set to priority +1 over LaunchRamp once all priorities + // are fixed. + }) : super(priority: 0); /// Distance the plunger can lower. final double compressionDistance; @@ -88,13 +87,36 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { plunger: this, anchor: anchor, ); - world.createJoint(PrismaticJoint(jointDef)); + + world.createJoint( + PrismaticJoint(jointDef)..setLimits(-compressionDistance, 0), + ); } @override Future onLoad() async { await super.onLoad(); await _anchorToJoint(); + + renderBody = false; + + await _loadSprite(); + } + + Future _loadSprite() async { + final sprite = await gameRef.loadSprite( + Assets.images.components.plunger.path, + ); + + await add( + SpriteComponent( + sprite: sprite, + size: Vector2(5.5, 40), + anchor: Anchor.center, + position: Vector2(2, 19), + angle: -0.033, + ), + ); } } @@ -111,6 +133,16 @@ class PlungerAnchor extends JointAnchor { plunger.body.position.y - plunger.compressionDistance, ); } + + @override + Body createBody() { + final shape = CircleShape()..radius = 0.5; + final fixtureDef = FixtureDef(shape); + final bodyDef = BodyDef() + ..position = initialPosition + ..type = BodyType.static; + return world.createBody(bodyDef)..createFixture(fixtureDef); + } } /// {@template plunger_anchor_prismatic_joint_def} diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 3c99fbca..a6eb0884 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flame/components.dart'; -import 'package:flame/extensions.dart'; import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; @@ -72,8 +71,7 @@ class PinballGame extends Forge2DGame Future _addPlunger() async { final plunger = Plunger(compressionDistance: 29) - ..initialPosition = - BoardDimensions.bounds.center.toVector2() + Vector2(41.5, -49); + ..initialPosition = Vector2(38, -19); await add(plunger); } @@ -90,17 +88,9 @@ class PinballGame extends Forge2DGame Future spawnBall() async { // TODO(alestiago): Remove once this logic is moved to controller. - var plunger = firstChild(); - if (plunger == null) { - await add(plunger = Plunger(compressionDistance: 1)); - } - final ball = ControlledBall.launch( theme: theme, - )..initialPosition = Vector2( - plunger.body.position.x, - plunger.body.position.y + Ball.size.y, - ); + )..initialPosition = Vector2(38, -19 + Ball.size.y); await add(ball); } } diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index 370d8fcf..5c2a87c2 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -17,6 +17,10 @@ class $AssetsImagesComponentsGen { AssetGenImage get background => const AssetGenImage('assets/images/components/background.png'); + + /// File path: assets/images/components/plunger.png + AssetGenImage get plunger => + const AssetGenImage('assets/images/components/plunger.png'); } class Assets { diff --git a/test/game/components/plunger_test.dart b/test/game/components/plunger_test.dart index 2a49ae2d..65789ae0 100644 --- a/test/game/components/plunger_test.dart +++ b/test/game/components/plunger_test.dart @@ -12,11 +12,32 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(Forge2DGame.new); + final flameTester = FlameTester(TestGame.new); group('Plunger', () { const compressionDistance = 0.0; + flameTester.testGameWidget( + 'renders correctly', + setUp: (game, tester) async { + await game.add( + Plunger( + compressionDistance: compressionDistance, + ), + ); + await game.ready(); + game.camera.followVector2(Vector2.zero()); + game.camera.zoom = 4.1; + }, + // TODO(ruimiguel): enable test when workflows are fixed. + // verify: (game, tester) async { + // await expectLater( + // find.byGame(), + // matchesGoldenFile('golden/plunger.png'), + // ); + // }, + ); + flameTester.test( 'loads correctly', (game) async {