From 9d2e9dd24327d5c72fa706929d142f4629c3f36e Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Thu, 7 Apr 2022 10:51:17 -0500 Subject: [PATCH 1/3] chore: trace all bodies in sandbox (#157) * feat: add traceAllBodies method * chore: update tracing stories * refactor: use for each * refactor: convert to mixin * refactor: simplify mixin --- .../sandbox/lib/common/trace.dart | 15 ++++++ .../big_dash_nest_bumper_game.dart | 10 ++-- .../lib/stories/dash_nest_bumper/stories.dart | 5 +- .../lib/stories/flipper/flipper_game.dart | 13 ++--- .../sandbox/lib/stories/flipper/stories.dart | 4 +- .../lib/stories/kicker/kicker_game.dart | 13 ++--- .../sandbox/lib/stories/kicker/stories.dart | 4 +- .../lib/stories/slingshot/slingshot_game.dart | 53 ++----------------- .../lib/stories/slingshot/stories.dart | 4 +- .../sparky_bumper/sparky_bumper_game.dart | 14 ++--- .../lib/stories/sparky_bumper/stories.dart | 4 +- 11 files changed, 38 insertions(+), 101 deletions(-) diff --git a/packages/pinball_components/sandbox/lib/common/trace.dart b/packages/pinball_components/sandbox/lib/common/trace.dart index 2018b942..8585169e 100644 --- a/packages/pinball_components/sandbox/lib/common/trace.dart +++ b/packages/pinball_components/sandbox/lib/common/trace.dart @@ -24,3 +24,18 @@ extension BodyTrace on BodyComponent { ); } } + +mixin Traceable on Forge2DGame { + late final bool trace; + + Future traceAllBodies({ + Color color = const Color(0xFFFF0000), + }) async { + if (trace) { + await ready(); + children + .whereType() + .forEach((bodyComponent) => bodyComponent.trace()); + } + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart index 9638c36d..649256d8 100644 --- a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart @@ -5,10 +5,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class BigDashNestBumperGame extends BasicBallGame { - BigDashNestBumperGame({ - required this.trace, - }) : super(color: const Color(0xFF0000FF)); +class BigDashNestBumperGame extends BasicBallGame with Traceable { + BigDashNestBumperGame() : super(color: const Color(0xFF0000FF)); static const info = ''' Shows how a BigDashNestBumper is rendered. @@ -16,8 +14,6 @@ class BigDashNestBumperGame extends BasicBallGame { Activate the "trace" parameter to overlay the body. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -28,6 +24,6 @@ class BigDashNestBumperGame extends BasicBallGame { ..priority = 1; await add(bigDashNestBumper); - if (trace) bigDashNestBumper.trace(); + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart index 95f3cd2a..22f792bc 100644 --- a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart @@ -8,9 +8,8 @@ void addDashNestBumperStories(Dashbook dashbook) { dashbook.storiesOf('Dash Nest Bumpers').add( 'Big', (context) => GameWidget( - game: BigDashNestBumperGame( - trace: context.boolProperty('Trace', true), - ), + game: BigDashNestBumperGame() + ..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('dash_nest_bumper/big.dart'), info: BasicBallGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart b/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart index d7f776e3..5a9e1787 100644 --- a/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart @@ -6,10 +6,8 @@ import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class FlipperGame extends BasicBallGame with KeyboardEvents { - FlipperGame({ - required this.trace, - }) : super(color: Colors.blue); +class FlipperGame extends BasicBallGame with KeyboardEvents, Traceable { + FlipperGame() : super(color: Colors.blue); static const info = ''' Shows how Flippers are rendered. @@ -30,8 +28,6 @@ class FlipperGame extends BasicBallGame with KeyboardEvents { LogicalKeyboardKey.keyD, ]; - final bool trace; - late Flipper leftFlipper; late Flipper rightFlipper; @@ -51,10 +47,7 @@ class FlipperGame extends BasicBallGame with KeyboardEvents { rightFlipper, ]); - if (trace) { - leftFlipper.trace(); - rightFlipper.trace(); - } + await traceAllBodies(); } @override diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart b/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart index 3f802451..f8aa0075 100644 --- a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart @@ -7,9 +7,7 @@ void addFlipperStories(Dashbook dashbook) { dashbook.storiesOf('Flipper').add( 'Basic', (context) => GameWidget( - game: FlipperGame( - trace: context.boolProperty('Trace', true), - ), + game: FlipperGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('flipper/basic.dart'), info: FlipperGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart b/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart index 21c0cfb8..1b29c3f9 100644 --- a/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart @@ -3,10 +3,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class KickerGame extends BasicBallGame { - KickerGame({ - required this.trace, - }) : super(color: const Color(0xFFFF0000)); +class KickerGame extends BasicBallGame with Traceable { + KickerGame() : super(color: const Color(0xFFFF0000)); static const info = ''' Shows how Kickers are rendered. @@ -15,8 +13,6 @@ class KickerGame extends BasicBallGame { - Tap anywhere on the screen to spawn a ball into the game. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -31,9 +27,6 @@ class KickerGame extends BasicBallGame { ..initialPosition = Vector2(center.x + (Kicker.size.x * 2), center.y); await add(rightKicker); - if (trace) { - leftKicker.trace(); - rightKicker.trace(); - } + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart b/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart index f4a6bf91..77d6ff29 100644 --- a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart @@ -7,9 +7,7 @@ void addKickerStories(Dashbook dashbook) { dashbook.storiesOf('Kickers').add( 'Basic', (context) => GameWidget( - game: KickerGame( - trace: context.boolProperty('Trace', true), - ), + game: KickerGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('kicker_game/basic.dart'), info: KickerGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart index c02689ca..8d54f391 100644 --- a/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart @@ -1,14 +1,10 @@ -import 'dart:math' as math; - import 'package:flame/extensions.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class SlingshotGame extends BasicBallGame { - SlingshotGame({ - required this.trace, - }) : super(color: const Color(0xFFFF0000)); +class SlingshotGame extends BasicBallGame with Traceable { + SlingshotGame() : super(color: const Color(0xFFFF0000)); static const info = ''' Shows how Slingshots are rendered. @@ -17,50 +13,11 @@ class SlingshotGame extends BasicBallGame { - Tap anywhere on the screen to spawn a ball into the game. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); - - final center = screenToWorld(camera.viewport.canvasSize! / 2); - - final leftUpperSlingshot = Slingshot( - length: 5.66, - angle: -1.5 * (math.pi / 180), - spritePath: Assets.images.slingshot.leftUpper.keyName, - )..initialPosition = center + Vector2(-29, 1.5); - - final leftLowerSlingshot = Slingshot( - length: 3.54, - angle: -29.1 * (math.pi / 180), - spritePath: Assets.images.slingshot.leftLower.keyName, - )..initialPosition = center + Vector2(-31, -6.2); - - final rightUpperSlingshot = Slingshot( - length: 5.64, - angle: 1 * (math.pi / 180), - spritePath: Assets.images.slingshot.rightUpper.keyName, - )..initialPosition = center + Vector2(22.3, 1.58); - - final rightLowerSlingshot = Slingshot( - length: 3.46, - angle: 26.8 * (math.pi / 180), - spritePath: Assets.images.slingshot.rightLower.keyName, - )..initialPosition = center + Vector2(24.7, -6.2); - - await addAll([ - leftUpperSlingshot, - leftLowerSlingshot, - rightUpperSlingshot, - rightLowerSlingshot, - ]); - - if (trace) { - leftUpperSlingshot.trace(); - leftLowerSlingshot.trace(); - rightUpperSlingshot.trace(); - rightLowerSlingshot.trace(); - } + await addFromBlueprint(Slingshots()); + camera.followVector2(Vector2.zero()); + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart index 6e985d32..70dfa021 100644 --- a/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart @@ -7,9 +7,7 @@ void addSlingshotStories(Dashbook dashbook) { dashbook.storiesOf('Slingshots').add( 'Basic', (context) => GameWidget( - game: SlingshotGame( - trace: context.boolProperty('Trace', true), - ), + game: SlingshotGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('slingshot_game/basic.dart'), info: SlingshotGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart index a0ad661a..a57beb8d 100644 --- a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart @@ -5,10 +5,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class SparkyBumperGame extends BasicBallGame { - SparkyBumperGame({ - required this.trace, - }) : super(color: const Color(0xFF0000FF)); +class SparkyBumperGame extends BasicBallGame with Traceable { + SparkyBumperGame() : super(color: const Color(0xFF0000FF)); static const info = ''' Shows how a SparkyBumper is rendered. @@ -16,8 +14,6 @@ class SparkyBumperGame extends BasicBallGame { Activate the "trace" parameter to overlay the body. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -38,10 +34,6 @@ class SparkyBumperGame extends BasicBallGame { sparkyBumperC, ]); - if (trace) { - sparkyBumperA.trace(); - sparkyBumperB.trace(); - sparkyBumperC.trace(); - } + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart index d0933b67..1a5f8801 100644 --- a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart @@ -7,9 +7,7 @@ void addSparkyBumperStories(Dashbook dashbook) { dashbook.storiesOf('Sparky Bumpers').add( 'Basic', (context) => GameWidget( - game: SparkyBumperGame( - trace: context.boolProperty('Trace', true), - ), + game: SparkyBumperGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('sparky_bumper/basic.dart'), info: SparkyBumperGame.info, From 4744f552f0ddfc19a965224c95599beb6a8bf6c5 Mon Sep 17 00:00:00 2001 From: Rui Miguel Alonso Date: Thu, 7 Apr 2022 19:54:13 +0200 Subject: [PATCH 2/3] fix: removed ghost PlungerAnchor shape (#162) --- lib/game/components/plunger.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/game/components/plunger.dart b/lib/game/components/plunger.dart index 1911be02..b8c079b5 100644 --- a/lib/game/components/plunger.dart +++ b/lib/game/components/plunger.dart @@ -136,12 +136,10 @@ class PlungerAnchor extends JointAnchor { @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); + return world.createBody(bodyDef); } } From fdc3039f72713fe4acfc23f30b589637c23e927a Mon Sep 17 00:00:00 2001 From: Rui Miguel Alonso Date: Fri, 8 Apr 2022 11:22:33 +0200 Subject: [PATCH 3/3] feat: sparky bumpers game logic (#154) * feat: added event for sparky bumpers hit * test: test sparky bumper bloc event * refactor: added sparky bumpers actives to GameState * refactor: removed active sparky bumper from game bloc logic * refactor: moved sparky bumpers logic to SparkyBumperController * test: tests for SparkyBumperController * chore: removed unused import * refactor: changed sparky fire zone * refactor: changed sparky fire zone * chore: analysis errors * chore: analysis error * Update test/game/bloc/game_bloc_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/sparky_fire_zone.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * chore: formatting file Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> --- lib/game/components/components.dart | 1 + lib/game/components/sparky_fire_zone.dart | 44 ++++++++++++++++++ lib/gen/assets.gen.dart | 3 ++ .../components/sparky_fire_zone_test.dart | 45 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 lib/game/components/sparky_fire_zone.dart create mode 100644 test/game/components/sparky_fire_zone_test.dart diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 61d0f3ca..9dd7eed4 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -5,4 +5,5 @@ export 'controlled_flipper.dart'; export 'flutter_forest.dart'; export 'plunger.dart'; export 'score_points.dart'; +export 'sparky_fire_zone.dart'; export 'wall.dart'; diff --git a/lib/game/components/sparky_fire_zone.dart b/lib/game/components/sparky_fire_zone.dart new file mode 100644 index 00000000..9d88f0f5 --- /dev/null +++ b/lib/game/components/sparky_fire_zone.dart @@ -0,0 +1,44 @@ +// ignore_for_file: avoid_renaming_method_parameters + +import 'package:flame/components.dart'; +import 'package:pinball/flame/flame.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_components/pinball_components.dart'; + +// TODO(ruimiguel): create and add SparkyFireZone component here in other PR. + +// TODO(ruimiguel): make private and remove ignore once SparkyFireZone is done +// ignore: public_member_api_docs +class ControlledSparkyBumper extends SparkyBumper + with Controls<_SparkyBumperController> { + // TODO(ruimiguel): make private and remove ignore once SparkyFireZone is done + // ignore: public_member_api_docs + ControlledSparkyBumper() : super.a() { + controller = _SparkyBumperController(this); + } +} + +/// {@template sparky_bumper_controller} +/// Controls a [SparkyBumper]. +/// {@endtemplate} +class _SparkyBumperController extends ComponentController + with HasGameRef { + /// {@macro sparky_bumper_controller} + _SparkyBumperController(ControlledSparkyBumper controlledSparkyBumper) + : super(controlledSparkyBumper); + + /// Flag for activated state of the [SparkyBumper]. + /// + /// Used to toggle [SparkyBumper]s' state between activated and deactivated. + bool isActivated = false; + + /// Registers when a [SparkyBumper] is hit by a [Ball]. + void hit() { + if (isActivated) { + component.deactivate(); + } else { + component.activate(); + } + isActivated = !isActivated; + } +} diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index 5c2a87c2..90013646 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -3,6 +3,8 @@ /// FlutterGen /// ***************************************************** +// ignore_for_file: directives_ordering,unnecessary_import + import 'package:flutter/widgets.dart'; class $AssetsImagesGen { @@ -15,6 +17,7 @@ class $AssetsImagesGen { class $AssetsImagesComponentsGen { const $AssetsImagesComponentsGen(); + /// File path: assets/images/components/background.png AssetGenImage get background => const AssetGenImage('assets/images/components/background.png'); diff --git a/test/game/components/sparky_fire_zone_test.dart b/test/game/components/sparky_fire_zone_test.dart new file mode 100644 index 00000000..dceaa9cc --- /dev/null +++ b/test/game/components/sparky_fire_zone_test.dart @@ -0,0 +1,45 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/game/game.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(EmptyPinballGameTest.new); + + group('SparkyFireZone', () { + group('bumpers', () { + late ControlledSparkyBumper controlledSparkyBumper; + + flameTester.testGameWidget( + 'activate when deactivated bumper is hit', + setUp: (game, tester) async { + controlledSparkyBumper = ControlledSparkyBumper(); + await game.ensureAdd(controlledSparkyBumper); + + controlledSparkyBumper.controller.hit(); + }, + verify: (game, tester) async { + expect(controlledSparkyBumper.controller.isActivated, isTrue); + }, + ); + + flameTester.testGameWidget( + 'deactivate when activated bumper is hit', + setUp: (game, tester) async { + controlledSparkyBumper = ControlledSparkyBumper(); + await game.ensureAdd(controlledSparkyBumper); + + controlledSparkyBumper.controller.hit(); + controlledSparkyBumper.controller.hit(); + }, + verify: (game, tester) async { + expect(controlledSparkyBumper.controller.isActivated, isFalse); + }, + ); + }); + }); +}