diff --git a/lib/game/components/flutter_forest.dart b/lib/game/components/flutter_forest.dart index 2d7bdf33..966b0a6b 100644 --- a/lib/game/components/flutter_forest.dart +++ b/lib/game/components/flutter_forest.dart @@ -68,7 +68,7 @@ class _FlutterForestController extends ComponentController void onNewState(GameState state) { super.onNewState(state); - component.add( + gameRef.add( ControlledBall.bonus(theme: gameRef.theme) ..initialPosition = Vector2(17.2, 52.7), ); diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index e0d25592..15c39f86 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -21,6 +21,8 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.dashBumper.b.inactive.keyName), images.load(components.Assets.images.dashBumper.main.active.keyName), images.load(components.Assets.images.dashBumper.main.inactive.keyName), + images.load(components.Assets.images.boundary.bottom.keyName), + images.load(components.Assets.images.boundary.outer.keyName), images.load(Assets.images.components.background.path), images.load(Assets.images.components.spaceshipDropTube.path), ]); diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 0711e677..38327df3 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -33,6 +33,7 @@ class PinballGame extends Forge2DGame await _addGameBoundaries(); unawaited(add(Board())); + unawaited(addFromBlueprint(Boundaries())); unawaited(_addPlunger()); unawaited(_addBonusWord()); unawaited(_addPaths()); @@ -128,7 +129,7 @@ class DebugPinballGame extends PinballGame with TapDetector { anchor: Anchor.center, ) ..position = Vector2(0, -7.8) - ..priority = -1; + ..priority = -2; await add(spriteComponent); } diff --git a/packages/pinball_components/assets/images/boundary/bottom.png b/packages/pinball_components/assets/images/boundary/bottom.png new file mode 100644 index 00000000..7caf3e2f Binary files /dev/null and b/packages/pinball_components/assets/images/boundary/bottom.png differ diff --git a/packages/pinball_components/assets/images/boundary/outer.png b/packages/pinball_components/assets/images/boundary/outer.png new file mode 100644 index 00000000..c0b81e96 Binary files /dev/null and b/packages/pinball_components/assets/images/boundary/outer.png differ diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index cf32e986..b7472ad9 100644 --- a/packages/pinball_components/lib/gen/assets.gen.dart +++ b/packages/pinball_components/lib/gen/assets.gen.dart @@ -14,9 +14,14 @@ class $AssetsImagesGen { AssetGenImage get ball => const AssetGenImage('assets/images/ball.png'); $AssetsImagesBaseboardGen get baseboard => const $AssetsImagesBaseboardGen(); + + $AssetsImagesBoundaryGen get boundary => const $AssetsImagesBoundaryGen(); + $AssetsImagesDashBumperGen get dashBumper => const $AssetsImagesDashBumperGen(); + $AssetsImagesDinoGen get dino => const $AssetsImagesDinoGen(); + $AssetsImagesFlipperGen get flipper => const $AssetsImagesFlipperGen(); /// File path: assets/images/flutter_sign_post.png @@ -44,6 +49,18 @@ class $AssetsImagesBaseboardGen { const AssetGenImage('assets/images/baseboard/right.png'); } +class $AssetsImagesBoundaryGen { + const $AssetsImagesBoundaryGen(); + + /// File path: assets/images/boundary/bottom.png + AssetGenImage get bottom => + const AssetGenImage('assets/images/boundary/bottom.png'); + + /// File path: assets/images/boundary/outer.png + AssetGenImage get outer => + const AssetGenImage('assets/images/boundary/outer.png'); +} + class $AssetsImagesDashBumperGen { const $AssetsImagesDashBumperGen(); diff --git a/packages/pinball_components/lib/src/components/boundaries.dart b/packages/pinball_components/lib/src/components/boundaries.dart new file mode 100644 index 00000000..66c4a8c0 --- /dev/null +++ b/packages/pinball_components/lib/src/components/boundaries.dart @@ -0,0 +1,152 @@ +// ignore_for_file: avoid_renaming_method_parameters + +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball_components/pinball_components.dart'; + +/// {@template boundaries} +/// A [Blueprint] which creates the [_BottomBoundary] and [_OuterBoundary]. +///{@endtemplate boundaries} +class Boundaries extends Forge2DBlueprint { + @override + void build(_) { + final bottomBoundary = _BottomBoundary(); + final outerBoundary = _OuterBoundary(); + + addAll([bottomBoundary, outerBoundary]); + } +} + +/// {@template bottom_boundary} +/// Curved boundary at the bottom of the board where the [Ball] exits the field +/// of play. +/// {@endtemplate bottom_boundary} +class _BottomBoundary extends BodyComponent with InitialPosition { + /// {@macro bottom_boundary} + _BottomBoundary() : super(priority: 2); + + List _createFixtureDefs() { + final fixturesDefs = []; + + final bottomLeftCurve = BezierCurveShape( + controlPoints: [ + Vector2(-43.6, -44.4), + Vector2(-31, -43.4), + Vector2(-18.7, -52.1), + ], + ); + final bottomLeftCurveFixtureDef = FixtureDef(bottomLeftCurve); + fixturesDefs.add(bottomLeftCurveFixtureDef); + + final bottomRightCurve = BezierCurveShape( + controlPoints: [ + Vector2(31.8, -44.1), + Vector2(21.95, -47), + Vector2(12.3, -51.4), + ], + ); + final bottomRightCurveFixtureDef = FixtureDef(bottomRightCurve); + fixturesDefs.add(bottomRightCurveFixtureDef); + + return fixturesDefs; + } + + @override + Future onLoad() async { + await super.onLoad(); + + final sprite = await gameRef.loadSprite( + Assets.images.boundary.bottom.keyName, + ); + + await add( + SpriteComponent( + sprite: sprite, + size: Vector2(96.7, 29.1), + anchor: Anchor.center, + position: Vector2(-5.4, 57.4), + ), + ); + + renderBody = false; + } + + @override + Body createBody() { + final bodyDef = BodyDef()..position = initialPosition; + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } +} + +/// {@template outer_boundary} +/// Boundary enclosing the top and left side of the board. The right side of the +/// board is closed by the barrier the [LaunchRamp] creates. +/// {@endtemplate outer_boundary} +class _OuterBoundary extends BodyComponent with InitialPosition { + /// {@macro outer_boundary} + _OuterBoundary() : super(priority: -1); + + List _createFixtureDefs() { + final fixturesDefs = []; + + final topWall = EdgeShape() + ..set( + Vector2(3.6, 70.2), + Vector2(-14.1, 70.2), + ); + final topWallFixtureDef = FixtureDef(topWall); + fixturesDefs.add(topWallFixtureDef); + + final topLeftCurve = BezierCurveShape( + controlPoints: [ + Vector2(-32.3, 57.2), + Vector2(-31.5, 69.9), + Vector2(-14.1, 70.2), + ], + ); + final topLeftCurveFixtureDef = FixtureDef(topLeftCurve); + fixturesDefs.add(topLeftCurveFixtureDef); + + final leftWall = EdgeShape() + ..set( + Vector2(-32.3, 57.2), + Vector2(-44.1, -44.4), + ); + final leftWallFixtureDef = FixtureDef(leftWall); + fixturesDefs.add(leftWallFixtureDef); + + return fixturesDefs; + } + + @override + Future onLoad() async { + await super.onLoad(); + + final sprite = await gameRef.loadSprite( + Assets.images.boundary.outer.keyName, + ); + + await add( + SpriteComponent( + sprite: sprite, + size: Vector2(105.1, 146.7), + anchor: Anchor.center, + position: Vector2(-0.2, -1.4), + ), + ); + + renderBody = false; + } + + @override + Body createBody() { + final bodyDef = BodyDef()..position = initialPosition; + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } +} diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index bbb2c29c..3613dc63 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -2,6 +2,7 @@ export 'ball.dart'; export 'baseboard.dart'; export 'board_dimensions.dart'; export 'board_side.dart'; +export 'boundaries.dart'; export 'dash_nest_bumper.dart'; export 'dino_walls.dart'; export 'fire_effect.dart'; diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 8fc9c6f8..c5ba274e 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -27,6 +27,7 @@ flutter: assets: - assets/images/ - assets/images/baseboard/ + - assets/images/boundary/ - assets/images/dino/ - assets/images/flipper/ - assets/images/dash_bumper/a/