diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart deleted file mode 100644 index 666cec5b..00000000 --- a/lib/game/components/board.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flame/components.dart'; -import 'package:pinball/game/game.dart'; -import 'package:pinball_components/pinball_components.dart'; - -/// {@template board} -/// The main flat surface of the [PinballGame]. -/// {endtemplate} -class Board extends Component { - /// {@macro board} - // TODO(alestiago): Make Board a Blueprint and sort out priorities. - Board() : super(priority: 1); - - @override - Future onLoad() async { - // TODO(allisonryan0002): add bottom group and flutter forest to pinball - // game directly. Then remove board. - final bottomGroup = _BottomGroup(); - - final flutterForest = FlutterForest(); - - await addAll([ - bottomGroup, - flutterForest, - ]); - } -} - -/// {@template bottom_group} -/// Grouping of the board's bottom [Component]s. -/// -/// The [_BottomGroup] consists of[Flipper]s, [Baseboard]s and [Kicker]s. -/// {@endtemplate} -// TODO(alestiago): Consider renaming once entire Board is defined. -class _BottomGroup extends Component { - /// {@macro bottom_group} - _BottomGroup() : super(priority: RenderPriority.bottomGroup); - - @override - Future onLoad() async { - final rightSide = _BottomGroupSide( - side: BoardSide.right, - ); - final leftSide = _BottomGroupSide( - side: BoardSide.left, - ); - - await addAll([rightSide, leftSide]); - } -} - -/// {@template bottom_group_side} -/// Group with one side of [_BottomGroup]'s symmetric [Component]s. -/// -/// For example, [Flipper]s are symmetric components. -/// {@endtemplate} -class _BottomGroupSide extends Component { - /// {@macro bottom_group_side} - _BottomGroupSide({ - required BoardSide side, - }) : _side = side; - - final BoardSide _side; - - @override - Future onLoad() async { - final direction = _side.direction; - final centerXAdjustment = _side.isLeft ? 0 : -6.5; - - final flipper = ControlledFlipper( - side: _side, - )..initialPosition = Vector2((11.8 * direction) + centerXAdjustment, 43.6); - final baseboard = Baseboard(side: _side) - ..initialPosition = Vector2( - (25.58 * direction) + centerXAdjustment, - 28.69, - ); - final kicker = Kicker( - side: _side, - )..initialPosition = Vector2( - (22.4 * direction) + centerXAdjustment, - 25, - ); - - await addAll([flipper, baseboard, kicker]); - } -} diff --git a/lib/game/components/bottom_group.dart b/lib/game/components/bottom_group.dart new file mode 100644 index 00000000..d0184d33 --- /dev/null +++ b/lib/game/components/bottom_group.dart @@ -0,0 +1,58 @@ +import 'package:flame/components.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_components/pinball_components.dart'; + +/// {@template bottom_group} +/// Grouping of the board's symmetrical bottom [Component]s. +/// +/// The [BottomGroup] consists of [Flipper]s, [Baseboard]s and [Kicker]s. +/// {@endtemplate} +// TODO(allisonryan0002): Consider renaming. +class BottomGroup extends Component { + /// {@macro bottom_group} + BottomGroup() + : super( + children: [ + _BottomGroupSide(side: BoardSide.right), + _BottomGroupSide(side: BoardSide.left), + ], + ); +} + +/// {@template bottom_group_side} +/// Group with one side of [BottomGroup]'s symmetric [Component]s. +/// +/// For example, [Flipper]s are symmetric components. +/// {@endtemplate} +class _BottomGroupSide extends Component { + /// {@macro bottom_group_side} + _BottomGroupSide({ + required BoardSide side, + }) : _side = side, + super(priority: RenderPriority.bottomGroup); + + final BoardSide _side; + + @override + Future onLoad() async { + final direction = _side.direction; + final centerXAdjustment = _side.isLeft ? 0 : -6.5; + + final flipper = ControlledFlipper( + side: _side, + )..initialPosition = Vector2((11.8 * direction) + centerXAdjustment, 43.6); + final baseboard = Baseboard(side: _side) + ..initialPosition = Vector2( + (25.58 * direction) + centerXAdjustment, + 28.69, + ); + final kicker = Kicker( + side: _side, + )..initialPosition = Vector2( + (22.4 * direction) + centerXAdjustment, + 25, + ); + + await addAll([flipper, baseboard, kicker]); + } +} diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 37de1948..3fae6abd 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -1,13 +1,14 @@ export 'android_acres.dart'; -export 'board.dart'; +export 'bottom_group.dart'; export 'camera_controller.dart'; export 'controlled_ball.dart'; export 'controlled_flipper.dart'; export 'controlled_plunger.dart'; +export 'dino_desert.dart'; +export 'drain.dart'; export 'flutter_forest/flutter_forest.dart'; export 'game_flow_controller.dart'; export 'google_word/google_word.dart'; export 'launcher.dart'; export 'scoring_behavior.dart'; export 'sparky_fire_zone.dart'; -export 'wall.dart'; diff --git a/lib/game/components/controlled_ball.dart b/lib/game/components/controlled_ball.dart index e76aabe1..ff05ad62 100644 --- a/lib/game/components/controlled_ball.dart +++ b/lib/game/components/controlled_ball.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_renaming_method_parameters + import 'package:flame/components.dart'; import 'package:flutter/material.dart'; import 'package:pinball/game/game.dart'; diff --git a/lib/game/components/dino_desert.dart b/lib/game/components/dino_desert.dart new file mode 100644 index 00000000..9e912575 --- /dev/null +++ b/lib/game/components/dino_desert.dart @@ -0,0 +1,23 @@ +import 'package:flame/components.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +/// {@template dino_desert} +/// Area located next to the [Launcher] containing the [ChromeDino] and +/// [DinoWalls]. +/// {@endtemplate} +// TODO(allisonryan0002): use a controller to initiate dino bonus when dino is +// fully implemented. +class DinoDesert extends Blueprint { + /// {@macro dino_desert} + DinoDesert() + : super( + components: [ + ChromeDino()..initialPosition = Vector2(12.3, -6.9), + ], + blueprints: [ + DinoWalls(), + ], + ); +} diff --git a/lib/game/components/drain.dart b/lib/game/components/drain.dart new file mode 100644 index 00000000..1dc3e211 --- /dev/null +++ b/lib/game/components/drain.dart @@ -0,0 +1,34 @@ +import 'package:flame/extensions.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_components/pinball_components.dart'; + +/// {@template drain} +/// Area located at the bottom of the board to detect when a [Ball] is lost. +/// {@endtemplate} +// TODO(allisonryan0002): move to components package when possible. +class Drain extends BodyComponent with ContactCallbacks { + /// {@macro drain} + Drain() : super(renderBody: false); + + @override + Body createBody() { + final shape = EdgeShape() + ..set( + BoardDimensions.bounds.bottomLeft.toVector2(), + BoardDimensions.bounds.bottomRight.toVector2(), + ); + final fixtureDef = FixtureDef(shape, isSensor: true); + final bodyDef = BodyDef(userData: this); + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } + +// TODO(allisonryan0002): move this to ball.dart when BallLost is removed. + @override + void beginContact(Object other, Contact contact) { + super.beginContact(other, contact); + if (other is! ControlledBall) return; + other.controller.lost(); + } +} diff --git a/lib/game/components/flutter_forest/flutter_forest.dart b/lib/game/components/flutter_forest/flutter_forest.dart index 02483159..d7447543 100644 --- a/lib/game/components/flutter_forest/flutter_forest.dart +++ b/lib/game/components/flutter_forest/flutter_forest.dart @@ -7,7 +7,7 @@ import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template flutter_forest} -/// Area positioned at the top right of the [Board] where the [Ball] can bounce +/// Area positioned at the top right of the board where the [Ball] can bounce /// off [DashNestBumper]s. /// {@endtemplate} class FlutterForest extends Component { diff --git a/lib/game/components/sparky_fire_zone.dart b/lib/game/components/sparky_fire_zone.dart index a23a4fbc..5c00e5c9 100644 --- a/lib/game/components/sparky_fire_zone.dart +++ b/lib/game/components/sparky_fire_zone.dart @@ -6,7 +6,7 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; /// {@template sparky_fire_zone} -/// Area positioned at the top left of the [Board] where the [Ball] +/// Area positioned at the top left of the board where the [Ball] /// can bounce off [SparkyBumper]s. /// /// When a [Ball] hits [SparkyBumper]s, the bumper animates. diff --git a/lib/game/components/wall.dart b/lib/game/components/wall.dart deleted file mode 100644 index 2f180d61..00000000 --- a/lib/game/components/wall.dart +++ /dev/null @@ -1,60 +0,0 @@ -// ignore_for_file: avoid_renaming_method_parameters - -import 'package:flame/extensions.dart'; -import 'package:flame_forge2d/flame_forge2d.dart'; -import 'package:pinball/game/game.dart'; -import 'package:pinball_components/pinball_components.dart' hide Assets; - -/// {@template wall} -/// A continuous generic and [BodyType.static] barrier that divides a game area. -/// {@endtemplate} -// TODO(alestiago): Remove [Wall] for [Pathway.straight]. -class Wall extends BodyComponent { - /// {@macro wall} - Wall({ - required this.start, - required this.end, - }); - - /// The [start] of the [Wall]. - final Vector2 start; - - /// The [end] of the [Wall]. - final Vector2 end; - - @override - Body createBody() { - final shape = EdgeShape()..set(start, end); - - final fixtureDef = FixtureDef(shape) - ..restitution = 0.1 - ..friction = 0; - - final bodyDef = BodyDef() - ..userData = this - ..position = Vector2.zero() - ..type = BodyType.static; - - return world.createBody(bodyDef)..createFixture(fixtureDef); - } -} - -/// {@template bottom_wall} -/// [Wall] located at the bottom of the board. -/// -/// {@endtemplate} -class BottomWall extends Wall with ContactCallbacks { - /// {@macro bottom_wall} - BottomWall() - : super( - start: BoardDimensions.bounds.bottomLeft.toVector2(), - end: BoardDimensions.bounds.bottomRight.toVector2(), - ); - - @override - void beginContact(Object other, Contact contact) { - super.beginContact(other, contact); - if (other is! ControlledBall) return; - other.controller.lost(); - } -} diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 2736a07a..a4b740fb 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -46,20 +46,18 @@ class PinballGame extends Forge2DGame unawaited(add(gameFlowController = GameFlowController(this))); unawaited(add(CameraController(this))); unawaited(add(Backboard.waiting(position: Vector2(0, -88)))); - - // TODO(allisonryan0002): banish Wall and Board classes in later PR. - await add(BottomWall()); + await add(Drain()); + await add(BottomGroup()); unawaited(addFromBlueprint(Boundaries())); unawaited(addFromBlueprint(LaunchRamp())); final launcher = Launcher(); unawaited(addFromBlueprint(launcher)); - unawaited(add(Board())); + await add(FlutterForest()); await addFromBlueprint(SparkyFireZone()); await addFromBlueprint(AndroidAcres()); + await addFromBlueprint(DinoDesert()); unawaited(addFromBlueprint(Slingshots())); - unawaited(addFromBlueprint(DinoWalls())); - await add(ChromeDino()..initialPosition = Vector2(12.3, -6.9)); await add( GoogleWord( position: Vector2( diff --git a/packages/pinball_components/lib/src/components/render_priority.dart b/packages/pinball_components/lib/src/components/render_priority.dart index 395ca49c..0f530b64 100644 --- a/packages/pinball_components/lib/src/components/render_priority.dart +++ b/packages/pinball_components/lib/src/components/render_priority.dart @@ -27,7 +27,7 @@ abstract class RenderPriority { static const int ballOnSpaceshipRail = _above + spaceshipRail; /// Render priority for the [Ball] while it's on the [LaunchRamp]. - static const int ballOnLaunchRamp = _above + launchRamp; + static const int ballOnLaunchRamp = launchRamp; // Background @@ -51,7 +51,7 @@ abstract class RenderPriority { static const int launchRamp = _above + outerBoundary; - static const int launchRampForegroundRailing = _below + ballOnBoard; + static const int launchRampForegroundRailing = ballOnBoard; static const int plunger = _above + launchRamp; diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index 40396b88..96083717 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -6,7 +6,6 @@ // https://opensource.org/licenses/MIT. import 'package:dashbook/dashbook.dart'; import 'package:flutter/material.dart'; -import 'package:sandbox/stories/kicker/stories.dart'; import 'package:sandbox/stories/stories.dart'; void main() { @@ -15,11 +14,9 @@ void main() { addBallStories(dashbook); addLayerStories(dashbook); addEffectsStories(dashbook); - addFlipperStories(dashbook); - addBaseboardStories(dashbook); addChromeDinoStories(dashbook); - addDashNestBumperStories(dashbook); - addKickerStories(dashbook); + addFlutterForestStories(dashbook); + addBottomGroupStories(dashbook); addPlungerStories(dashbook); addSlingshotStories(dashbook); addSparkyBumperStories(dashbook); diff --git a/packages/pinball_components/sandbox/lib/stories/baseboard/stories.dart b/packages/pinball_components/sandbox/lib/stories/baseboard/stories.dart deleted file mode 100644 index b07e3a73..00000000 --- a/packages/pinball_components/sandbox/lib/stories/baseboard/stories.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:dashbook/dashbook.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/baseboard/baseboard_game.dart'; - -void addBaseboardStories(Dashbook dashbook) { - dashbook.storiesOf('Baseboard').addGame( - title: 'Traced', - description: BaseboardGame.description, - gameBuilder: (_) => BaseboardGame(), - ); -} diff --git a/packages/pinball_components/sandbox/lib/stories/baseboard/baseboard_game.dart b/packages/pinball_components/sandbox/lib/stories/bottom_group/baseboard_game.dart similarity index 100% rename from packages/pinball_components/sandbox/lib/stories/baseboard/baseboard_game.dart rename to packages/pinball_components/sandbox/lib/stories/bottom_group/baseboard_game.dart diff --git a/packages/pinball_components/sandbox/lib/stories/bottom_group/bottom_group.dart b/packages/pinball_components/sandbox/lib/stories/bottom_group/bottom_group.dart new file mode 100644 index 00000000..d0cc7322 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/bottom_group/bottom_group.dart @@ -0,0 +1 @@ +export 'stories.dart'; diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart b/packages/pinball_components/sandbox/lib/stories/bottom_group/flipper_game.dart similarity index 100% rename from packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart rename to packages/pinball_components/sandbox/lib/stories/bottom_group/flipper_game.dart diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart b/packages/pinball_components/sandbox/lib/stories/bottom_group/kicker_game.dart similarity index 100% rename from packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart rename to packages/pinball_components/sandbox/lib/stories/bottom_group/kicker_game.dart diff --git a/packages/pinball_components/sandbox/lib/stories/bottom_group/stories.dart b/packages/pinball_components/sandbox/lib/stories/bottom_group/stories.dart new file mode 100644 index 00000000..7712ca79 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/bottom_group/stories.dart @@ -0,0 +1,24 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/bottom_group/baseboard_game.dart'; +import 'package:sandbox/stories/bottom_group/flipper_game.dart'; +import 'package:sandbox/stories/bottom_group/kicker_game.dart'; + +void addBottomGroupStories(Dashbook dashbook) { + dashbook.storiesOf('Bottom Group') + ..addGame( + title: 'Flipper', + description: FlipperGame.description, + gameBuilder: (_) => FlipperGame(), + ) + ..addGame( + title: 'Kicker', + description: KickerGame.description, + gameBuilder: (_) => KickerGame(), + ) + ..addGame( + title: 'Baseboard', + description: BaseboardGame.description, + gameBuilder: (_) => BaseboardGame(), + ); +} diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart b/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart deleted file mode 100644 index 2ef2a4b6..00000000 --- a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:dashbook/dashbook.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/flipper/flipper_game.dart'; - -void addFlipperStories(Dashbook dashbook) { - dashbook.storiesOf('Flipper').addGame( - title: 'Traced', - description: FlipperGame.description, - gameBuilder: (_) => FlipperGame(), - ); -} diff --git a/packages/pinball_components/sandbox/lib/stories/flutter_forest/stories.dart b/packages/pinball_components/sandbox/lib/stories/flutter_forest/stories.dart index ef9c1ffb..dd557a27 100644 --- a/packages/pinball_components/sandbox/lib/stories/flutter_forest/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/flutter_forest/stories.dart @@ -5,7 +5,7 @@ import 'package:sandbox/stories/flutter_forest/signpost_game.dart'; import 'package:sandbox/stories/flutter_forest/small_dash_nest_bumper_a_game.dart'; import 'package:sandbox/stories/flutter_forest/small_dash_nest_bumper_b_game.dart'; -void addDashNestBumperStories(Dashbook dashbook) { +void addFlutterForestStories(Dashbook dashbook) { dashbook.storiesOf('Flutter Forest') ..addGame( title: 'Signpost', diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart b/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart deleted file mode 100644 index cfebb7e4..00000000 --- a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:dashbook/dashbook.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/kicker/kicker_game.dart'; - -void addKickerStories(Dashbook dashbook) { - dashbook.storiesOf('Kickers').addGame( - title: 'Traced', - description: KickerGame.description, - gameBuilder: (_) => KickerGame(), - ); -} diff --git a/packages/pinball_components/sandbox/lib/stories/stories.dart b/packages/pinball_components/sandbox/lib/stories/stories.dart index df51fc0f..9e1d44d8 100644 --- a/packages/pinball_components/sandbox/lib/stories/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/stories.dart @@ -1,12 +1,11 @@ export 'android_acres/stories.dart'; export 'backboard/stories.dart'; export 'ball/stories.dart'; -export 'baseboard/stories.dart'; +export 'bottom_group/stories.dart'; export 'boundaries/stories.dart'; export 'chrome_dino/stories.dart'; export 'dino_wall/stories.dart'; export 'effects/stories.dart'; -export 'flipper/stories.dart'; export 'flutter_forest/stories.dart'; export 'google_word/stories.dart'; export 'launch_ramp/stories.dart'; diff --git a/test/game/components/board_test.dart b/test/game/components/board_test.dart deleted file mode 100644 index 63b7251b..00000000 --- a/test/game/components/board_test.dart +++ /dev/null @@ -1,110 +0,0 @@ -// 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 'package:pinball_components/pinball_components.dart'; - -import '../../helpers/helpers.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - final assets = [ - Assets.images.dash.bumper.main.active.keyName, - Assets.images.dash.bumper.main.inactive.keyName, - Assets.images.dash.bumper.a.active.keyName, - Assets.images.dash.bumper.a.inactive.keyName, - Assets.images.dash.bumper.b.active.keyName, - Assets.images.dash.bumper.b.inactive.keyName, - Assets.images.dash.animatronic.keyName, - Assets.images.signpost.inactive.keyName, - Assets.images.signpost.active1.keyName, - Assets.images.signpost.active2.keyName, - Assets.images.signpost.active3.keyName, - Assets.images.baseboard.left.keyName, - Assets.images.baseboard.right.keyName, - Assets.images.flipper.left.keyName, - Assets.images.flipper.right.keyName, - ]; - final flameTester = FlameTester( - () => EmptyPinballTestGame(assets: assets), - ); - - group('Board', () { - flameTester.test( - 'loads correctly', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - expect(game.contains(board), isTrue); - }, - ); - - group('loads', () { - flameTester.test( - 'one left flipper', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - final leftFlippers = board.descendants().whereType().where( - (flipper) => flipper.side.isLeft, - ); - expect(leftFlippers.length, equals(1)); - }, - ); - - flameTester.test( - 'one right flipper', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - final rightFlippers = board.descendants().whereType().where( - (flipper) => flipper.side.isRight, - ); - expect(rightFlippers.length, equals(1)); - }, - ); - - flameTester.test( - 'two Baseboards', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - final baseboards = board.descendants().whereType(); - expect(baseboards.length, equals(2)); - }, - ); - - flameTester.test( - 'two Kickers', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - final kickers = board.descendants().whereType(); - expect(kickers.length, equals(2)); - }, - ); - - flameTester.test( - 'one FlutterForest', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - final flutterForest = board.descendants().whereType(); - expect(flutterForest.length, equals(1)); - }, - ); - }); - }); -} diff --git a/test/game/components/bottom_group_test.dart b/test/game/components/bottom_group_test.dart new file mode 100644 index 00000000..3254f155 --- /dev/null +++ b/test/game/components/bottom_group_test.dart @@ -0,0 +1,86 @@ +// 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 'package:pinball_components/pinball_components.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final assets = [ + Assets.images.baseboard.left.keyName, + Assets.images.baseboard.right.keyName, + Assets.images.flipper.left.keyName, + Assets.images.flipper.right.keyName, + ]; + final flameTester = FlameTester( + () => EmptyPinballTestGame(assets: assets), + ); + + group('BottomGroup', () { + flameTester.test( + 'loads correctly', + (game) async { + final bottomGroup = BottomGroup(); + await game.ensureAdd(bottomGroup); + + expect(game.contains(bottomGroup), isTrue); + }, + ); + + group('loads', () { + flameTester.test( + 'one left flipper', + (game) async { + final bottomGroup = BottomGroup(); + await game.ensureAdd(bottomGroup); + + final leftFlippers = + bottomGroup.descendants().whereType().where( + (flipper) => flipper.side.isLeft, + ); + expect(leftFlippers.length, equals(1)); + }, + ); + + flameTester.test( + 'one right flipper', + (game) async { + final bottomGroup = BottomGroup(); + await game.ensureAdd(bottomGroup); + + final rightFlippers = + bottomGroup.descendants().whereType().where( + (flipper) => flipper.side.isRight, + ); + expect(rightFlippers.length, equals(1)); + }, + ); + + flameTester.test( + 'two Baseboards', + (game) async { + final bottomGroup = BottomGroup(); + await game.ensureAdd(bottomGroup); + + final basebottomGroups = + bottomGroup.descendants().whereType(); + expect(basebottomGroups.length, equals(2)); + }, + ); + + flameTester.test( + 'two Kickers', + (game) async { + final bottomGroup = BottomGroup(); + await game.ensureAdd(bottomGroup); + + final kickers = bottomGroup.descendants().whereType(); + expect(kickers.length, equals(2)); + }, + ); + }); + }); +} diff --git a/test/game/components/drain_test.dart b/test/game/components/drain_test.dart new file mode 100644 index 00000000..f1875a56 --- /dev/null +++ b/test/game/components/drain_test.dart @@ -0,0 +1,60 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball/game/game.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(TestGame.new); + + group('Drain', () { + flameTester.test( + 'loads correctly', + (game) async { + final drain = Drain(); + await game.ensureAdd(drain); + + expect(game.contains(drain), isTrue); + }, + ); + + flameTester.test( + 'body is static', + (game) async { + final drain = Drain(); + await game.ensureAdd(drain); + + expect(drain.body.bodyType, equals(BodyType.static)); + }, + ); + + flameTester.test( + 'is sensor', + (game) async { + final drain = Drain(); + await game.ensureAdd(drain); + + expect(drain.body.fixtures.first.isSensor, isTrue); + }, + ); + + test( + 'calls lost on contact with ball', + () async { + final drain = Drain(); + final ball = MockControlledBall(); + final controller = MockBallController(); + when(() => ball.controller).thenReturn(controller); + + drain.beginContact(ball, MockContact()); + + verify(controller.lost).called(1); + }, + ); + }); +} diff --git a/test/game/components/wall_test.dart b/test/game/components/wall_test.dart deleted file mode 100644 index 16f7ce34..00000000 --- a/test/game/components/wall_test.dart +++ /dev/null @@ -1,165 +0,0 @@ -// ignore_for_file: cascade_invocations - -import 'package:flame_forge2d/flame_forge2d.dart'; -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(EmptyPinballTestGame.new); - - group('Wall', () { - flameTester.test( - 'loads correctly', - (game) async { - await game.ready(); - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - - expect(game.contains(wall), isTrue); - }, - ); - - group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - game.contains(wall); - - expect(wall.body.position, Vector2.zero()); - }, - ); - - flameTester.test( - 'is static', - (game) async { - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - - expect(wall.body.bodyType, equals(BodyType.static)); - }, - ); - }); - - group('fixture', () { - flameTester.test( - 'exists', - (game) async { - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - - expect(wall.body.fixtures[0], isA()); - }, - ); - - flameTester.test( - 'has restitution', - (game) async { - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - - final fixture = wall.body.fixtures[0]; - expect(fixture.restitution, greaterThan(0)); - }, - ); - - flameTester.test( - 'has no friction', - (game) async { - final wall = Wall( - start: Vector2.zero(), - end: Vector2(100, 0), - ); - await game.ensureAdd(wall); - - final fixture = wall.body.fixtures[0]; - expect(fixture.friction, equals(0)); - }, - ); - }); - }); - - group( - 'BottomWall', - () { - group('removes ball on contact', () { - late GameBloc gameBloc; - - setUp(() { - gameBloc = GameBloc(); - }); - - final flameBlocTester = FlameBlocTester( - gameBuilder: EmptyPinballTestGame.new, - blocBuilder: () => gameBloc, - ); - - flameBlocTester.testGameWidget( - 'when ball is launch', - setUp: (game, tester) async { - final ball = ControlledBall.launch( - characterTheme: game.characterTheme, - ); - final wall = BottomWall(); - await game.ensureAddAll([ball, wall]); - - beginContact(game, ball, wall); - await game.ready(); - - expect(game.contains(ball), isFalse); - }, - ); - - flameBlocTester.testGameWidget( - 'when ball is bonus', - setUp: (game, tester) async { - final ball = ControlledBall.bonus( - characterTheme: game.characterTheme, - ); - final wall = BottomWall(); - await game.ensureAddAll([ball, wall]); - - beginContact(game, ball, wall); - await game.ready(); - - expect(game.contains(ball), isFalse); - }, - ); - - flameBlocTester.testGameWidget( - 'when ball is debug', - setUp: (game, tester) async { - final ball = ControlledBall.debug(); - final wall = BottomWall(); - await game.ensureAddAll([ball, wall]); - - beginContact(game, ball, wall); - await game.ready(); - - expect(game.contains(ball), isFalse); - }, - ); - }); - }, - ); -} diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index 2e585d66..ef831b5c 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -104,38 +104,47 @@ void main() { // TODO(alestiago): tests that Blueprints get added once the Blueprint // class is removed. flameTester.test( - 'has only one BottomWall', + 'has only one Drain', (game) async { await game.ready(); expect( - game.children.whereType().length, + game.children.whereType().length, equals(1), ); }, ); flameTester.test( - 'has only one Plunger', + 'has only one BottomGroup', (game) async { await game.ready(); + expect( - game.children.whereType().length, + game.children.whereType().length, equals(1), ); }, ); flameTester.test( - 'has one Board', + 'has only one Plunger', (game) async { await game.ready(); expect( - game.children.whereType().length, + game.children.whereType().length, equals(1), ); }, ); + flameTester.test('has one FlutterForest', (game) async { + await game.ready(); + expect( + game.children.whereType().length, + equals(1), + ); + }); + flameTester.test( 'one GoogleWord', (game) async { diff --git a/test/helpers/mocks.dart b/test/helpers/mocks.dart index ad999aff..6aab19a2 100644 --- a/test/helpers/mocks.dart +++ b/test/helpers/mocks.dart @@ -15,9 +15,7 @@ import 'package:pinball_components/pinball_components.dart'; class MockPinballGame extends Mock implements PinballGame {} -class MockWall extends Mock implements Wall {} - -class MockBottomWall extends Mock implements BottomWall {} +class MockDrain extends Mock implements Drain {} class MockBody extends Mock implements Body {}