From 125e4e14e38a14c0f5f71b93d8f367a64d93fd11 Mon Sep 17 00:00:00 2001 From: Allison Ryan Date: Wed, 6 Apr 2022 13:46:06 -0500 Subject: [PATCH] feat: add sparky computer and mechanics --- lib/game/bloc/game_bloc.dart | 15 +++ lib/game/bloc/game_event.dart | 7 ++ lib/game/bloc/game_state.dart | 3 + lib/game/components/components.dart | 1 + lib/game/components/controlled_ball.dart | 14 +++ .../controlled_sparky_computer.dart | 70 +++++++++++ lib/game/game_assets.dart | 8 ++ lib/game/pinball_game.dart | 3 +- .../bumper}/a/active.png | Bin .../bumper}/a/inactive.png | Bin .../bumper}/b/active.png | Bin .../bumper}/b/inactive.png | Bin .../bumper}/c/active.png | Bin .../bumper}/c/inactive.png | Bin .../assets/images/sparky/computer/base.png | Bin 0 -> 10424 bytes .../assets/images/sparky/computer/top.png | Bin 0 -> 4589 bytes .../lib/gen/assets.gen.dart | 58 +++++++--- .../lib/src/components/ball.dart | 12 +- .../lib/src/components/components.dart | 1 + .../lib/src/components/sparky_bumper.dart | 12 +- .../lib/src/components/sparky_computer.dart | 109 ++++++++++++++++++ .../lib/src/flame/blueprint.dart | 12 +- packages/pinball_components/pubspec.yaml | 7 +- 23 files changed, 292 insertions(+), 40 deletions(-) create mode 100644 lib/game/components/controlled_sparky_computer.dart rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/a/active.png (100%) rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/a/inactive.png (100%) rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/b/active.png (100%) rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/b/inactive.png (100%) rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/c/active.png (100%) rename packages/pinball_components/assets/images/{sparky_bumper => sparky/bumper}/c/inactive.png (100%) create mode 100644 packages/pinball_components/assets/images/sparky/computer/base.png create mode 100644 packages/pinball_components/assets/images/sparky/computer/top.png create mode 100644 packages/pinball_components/lib/src/components/sparky_computer.dart diff --git a/lib/game/bloc/game_bloc.dart b/lib/game/bloc/game_bloc.dart index 7c1b4f44..ce1a78b4 100644 --- a/lib/game/bloc/game_bloc.dart +++ b/lib/game/bloc/game_bloc.dart @@ -13,6 +13,7 @@ class GameBloc extends Bloc { on(_onScored); on(_onBonusLetterActivated); on(_onDashNestActivated); + on(_onSparkyTurboChargeActivated); } static const bonusWord = 'GOOGLE'; @@ -77,4 +78,18 @@ class GameBloc extends Bloc { ); } } + + Future _onSparkyTurboChargeActivated( + SparkyTurboChargeActivated event, + Emitter emit, + ) async { + emit( + state.copyWith( + bonusHistory: [ + ...state.bonusHistory, + GameBonus.sparkyTurboCharge, + ], + ), + ); + } } diff --git a/lib/game/bloc/game_event.dart b/lib/game/bloc/game_event.dart index b05c5336..ee5315ad 100644 --- a/lib/game/bloc/game_event.dart +++ b/lib/game/bloc/game_event.dart @@ -54,3 +54,10 @@ class DashNestActivated extends GameEvent { @override List get props => [nestId]; } + +class SparkyTurboChargeActivated extends GameEvent { + const SparkyTurboChargeActivated(); + + @override + List get props => []; +} diff --git a/lib/game/bloc/game_state.dart b/lib/game/bloc/game_state.dart index bbaa4cd8..0d9485e9 100644 --- a/lib/game/bloc/game_state.dart +++ b/lib/game/bloc/game_state.dart @@ -10,6 +10,9 @@ enum GameBonus { /// Bonus achieved when the user activates all dash nest bumpers. dashNest, + + /// Bonus achieved when a ball enters Sparky's computer. + sparkyTurboCharge, } /// {@template game_state} diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 61d0f3ca..0f2d7730 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -2,6 +2,7 @@ export 'board.dart'; export 'bonus_word.dart'; export 'controlled_ball.dart'; export 'controlled_flipper.dart'; +export 'controlled_sparky_computer.dart'; export 'flutter_forest.dart'; export 'plunger.dart'; export 'score_points.dart'; diff --git a/lib/game/components/controlled_ball.dart b/lib/game/components/controlled_ball.dart index cef076d8..d48ebe66 100644 --- a/lib/game/components/controlled_ball.dart +++ b/lib/game/components/controlled_ball.dart @@ -53,6 +53,20 @@ class BallController extends ComponentController component.shouldRemove = true; } + /// Stops the [Ball] inside of the [SparkyComputer] while the turbo charge + /// sequence runs, then boosts the ball out of the computer. + Future turboCharge() async { + gameRef.read().add(const SparkyTurboChargeActivated()); + + // TODO(allisonryan0002): adjust delay to match animation duration once + // given animations. + component.stop(); + await Future.delayed(const Duration(seconds: 1)); + component + ..resume() + ..boost(Vector2(200, -500)); + } + @override void onRemove() { super.onRemove(); diff --git a/lib/game/components/controlled_sparky_computer.dart b/lib/game/components/controlled_sparky_computer.dart new file mode 100644 index 00000000..4d396037 --- /dev/null +++ b/lib/game/components/controlled_sparky_computer.dart @@ -0,0 +1,70 @@ +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball/flame/flame.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_components/pinball_components.dart'; + +/// {@template controlled_sparky_computer} +/// [SparkyComputer] with a [SparkyComputerController] attached. +/// {@endtemplate} +class ControlledSparkyComputer extends SparkyComputer + with Controls, HasGameRef { + /// {@macro controlled_sparky_computer} + ControlledSparkyComputer() { + controller = SparkyComputerController(this); + } + + @override + void build(Forge2DGame _) { + addContactCallback(_SparkyTurboChargeSensorBallContactCallback()); + final sparkyTurboChargeSensor = _SparkyTurboChargeSensor() + ..initialPosition = Vector2(-13.4, 49.8); + add(sparkyTurboChargeSensor); + super.build(_); + } +} + +class _SparkyTurboChargeSensor extends BodyComponent with InitialPosition { + _SparkyTurboChargeSensor() { + renderBody = false; + } + + @override + Body createBody() { + final shape = CircleShape()..radius = .1; + + final fixtureDef = FixtureDef(shape)..isSensor = true; + + final bodyDef = BodyDef() + ..position = initialPosition + ..userData = this; + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } +} + +/// {@template sparky_computer_controller} +/// Controller attached to a [SparkyComputer] that handles its game related +/// logic. +/// {@endtemplate} +//TODO(allisonryan0002): listen for turbo charge game bonus and animate Sparky. +class SparkyComputerController + extends ComponentController { + /// {@macro sparky_computer_controller} + SparkyComputerController(ControlledSparkyComputer controlledComputer) + : super(controlledComputer); +} + +class _SparkyTurboChargeSensorBallContactCallback + extends ContactCallback<_SparkyTurboChargeSensor, ControlledBall> { + _SparkyTurboChargeSensorBallContactCallback(); + + @override + void begin( + _SparkyTurboChargeSensor sparkyTurboChargeSensor, + ControlledBall ball, + _, + ) { + ball.controller.turboCharge(); + } +} diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 47175c32..913cce5f 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -42,6 +42,14 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.spaceship.rail.foreground.keyName), images.load(components.Assets.images.chromeDino.mouth.keyName), images.load(components.Assets.images.chromeDino.head.keyName), + images.load(components.Assets.images.sparky.computer.base.keyName), + images.load(components.Assets.images.sparky.computer.top.keyName), + images.load(components.Assets.images.sparky.bumper.a.active.keyName), + images.load(components.Assets.images.sparky.bumper.a.inactive.keyName), + images.load(components.Assets.images.sparky.bumper.b.active.keyName), + images.load(components.Assets.images.sparky.bumper.b.inactive.keyName), + images.load(components.Assets.images.sparky.bumper.c.active.keyName), + images.load(components.Assets.images.sparky.bumper.c.inactive.keyName), images.load(Assets.images.components.background.path), ]); } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 7a0e6823..4e01c7ba 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -40,6 +40,7 @@ class PinballGame extends Forge2DGame await _addGameBoundaries(); unawaited(addFromBlueprint(Boundaries())); unawaited(addFromBlueprint(LaunchRamp())); + unawaited(addFromBlueprint(ControlledSparkyComputer())); final plunger = Plunger(compressionDistance: 29) ..initialPosition = Vector2(38, -19); @@ -147,7 +148,7 @@ class DebugPinballGame extends PinballGame with TapDetector { @override Future onLoad() async { await super.onLoad(); - await _loadBackground(); + // await _loadBackground(); } // TODO(alestiago): Move to PinballGame once we have the real background diff --git a/packages/pinball_components/assets/images/sparky_bumper/a/active.png b/packages/pinball_components/assets/images/sparky/bumper/a/active.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/a/active.png rename to packages/pinball_components/assets/images/sparky/bumper/a/active.png diff --git a/packages/pinball_components/assets/images/sparky_bumper/a/inactive.png b/packages/pinball_components/assets/images/sparky/bumper/a/inactive.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/a/inactive.png rename to packages/pinball_components/assets/images/sparky/bumper/a/inactive.png diff --git a/packages/pinball_components/assets/images/sparky_bumper/b/active.png b/packages/pinball_components/assets/images/sparky/bumper/b/active.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/b/active.png rename to packages/pinball_components/assets/images/sparky/bumper/b/active.png diff --git a/packages/pinball_components/assets/images/sparky_bumper/b/inactive.png b/packages/pinball_components/assets/images/sparky/bumper/b/inactive.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/b/inactive.png rename to packages/pinball_components/assets/images/sparky/bumper/b/inactive.png diff --git a/packages/pinball_components/assets/images/sparky_bumper/c/active.png b/packages/pinball_components/assets/images/sparky/bumper/c/active.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/c/active.png rename to packages/pinball_components/assets/images/sparky/bumper/c/active.png diff --git a/packages/pinball_components/assets/images/sparky_bumper/c/inactive.png b/packages/pinball_components/assets/images/sparky/bumper/c/inactive.png similarity index 100% rename from packages/pinball_components/assets/images/sparky_bumper/c/inactive.png rename to packages/pinball_components/assets/images/sparky/bumper/c/inactive.png diff --git a/packages/pinball_components/assets/images/sparky/computer/base.png b/packages/pinball_components/assets/images/sparky/computer/base.png new file mode 100644 index 0000000000000000000000000000000000000000..2e8fe362a08ee871cac7b58f5c8f29a20e048a88 GIT binary patch literal 10424 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 literal 0 HcmV?d00001 diff --git a/packages/pinball_components/assets/images/sparky/computer/top.png b/packages/pinball_components/assets/images/sparky/computer/top.png new file mode 100644 index 0000000000000000000000000000000000000000..d9f3bc6c18f8ea5770c492a8fedf1697af5aefda GIT binary patch literal 4589 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 const $AssetsImagesLaunchRampGen(); $AssetsImagesSpaceshipGen get spaceship => const $AssetsImagesSpaceshipGen(); - $AssetsImagesSparkyBumperGen get sparkyBumper => - const $AssetsImagesSparkyBumperGen(); + $AssetsImagesSparkyGen get sparky => const $AssetsImagesSparkyGen(); } class $AssetsImagesBaseboardGen { @@ -144,12 +143,13 @@ class $AssetsImagesSpaceshipGen { const AssetGenImage('assets/images/spaceship/saucer.png'); } -class $AssetsImagesSparkyBumperGen { - const $AssetsImagesSparkyBumperGen(); +class $AssetsImagesSparkyGen { + const $AssetsImagesSparkyGen(); - $AssetsImagesSparkyBumperAGen get a => const $AssetsImagesSparkyBumperAGen(); - $AssetsImagesSparkyBumperBGen get b => const $AssetsImagesSparkyBumperBGen(); - $AssetsImagesSparkyBumperCGen get c => const $AssetsImagesSparkyBumperCGen(); + $AssetsImagesSparkyBumperGen get bumper => + const $AssetsImagesSparkyBumperGen(); + $AssetsImagesSparkyComputerGen get computer => + const $AssetsImagesSparkyComputerGen(); } class $AssetsImagesDashBumperAGen { @@ -216,40 +216,60 @@ class $AssetsImagesSpaceshipRampGen { 'assets/images/spaceship/ramp/railing-foreground.png'); } +class $AssetsImagesSparkyBumperGen { + const $AssetsImagesSparkyBumperGen(); + + $AssetsImagesSparkyBumperAGen get a => const $AssetsImagesSparkyBumperAGen(); + $AssetsImagesSparkyBumperBGen get b => const $AssetsImagesSparkyBumperBGen(); + $AssetsImagesSparkyBumperCGen get c => const $AssetsImagesSparkyBumperCGen(); +} + +class $AssetsImagesSparkyComputerGen { + const $AssetsImagesSparkyComputerGen(); + + /// File path: assets/images/sparky/computer/base.png + AssetGenImage get base => + const AssetGenImage('assets/images/sparky/computer/base.png'); + + /// File path: assets/images/sparky/computer/top.png + AssetGenImage get top => + const AssetGenImage('assets/images/sparky/computer/top.png'); +} + class $AssetsImagesSparkyBumperAGen { const $AssetsImagesSparkyBumperAGen(); - /// File path: assets/images/sparky_bumper/a/active.png + /// File path: assets/images/sparky/bumper/a/active.png AssetGenImage get active => - const AssetGenImage('assets/images/sparky_bumper/a/active.png'); + const AssetGenImage('assets/images/sparky/bumper/a/active.png'); - /// File path: assets/images/sparky_bumper/a/inactive.png + /// File path: assets/images/sparky/bumper/a/inactive.png AssetGenImage get inactive => - const AssetGenImage('assets/images/sparky_bumper/a/inactive.png'); + const AssetGenImage('assets/images/sparky/bumper/a/inactive.png'); } class $AssetsImagesSparkyBumperBGen { const $AssetsImagesSparkyBumperBGen(); - /// File path: assets/images/sparky_bumper/b/active.png + /// File path: assets/images/sparky/bumper/b/active.png AssetGenImage get active => - const AssetGenImage('assets/images/sparky_bumper/b/active.png'); + const AssetGenImage('assets/images/sparky/bumper/b/active.png'); - /// File path: assets/images/sparky_bumper/b/inactive.png + /// File path: assets/images/sparky/bumper/b/inactive.png AssetGenImage get inactive => - const AssetGenImage('assets/images/sparky_bumper/b/inactive.png'); + const AssetGenImage('assets/images/sparky/bumper/b/inactive.png'); } class $AssetsImagesSparkyBumperCGen { const $AssetsImagesSparkyBumperCGen(); - /// File path: assets/images/sparky_bumper/c/active.png + /// File path: assets/images/sparky/bumper/c/active.png AssetGenImage get active => - const AssetGenImage('assets/images/sparky_bumper/c/active.png'); + const AssetGenImage('assets/images/sparky/bumper/c/active.png'); - /// File path: assets/images/sparky_bumper/c/inactive.png + /// File path: assets/images/sparky/bumper/c/inactive.png AssetGenImage get inactive => - const AssetGenImage('assets/images/sparky_bumper/c/inactive.png'); + const AssetGenImage('assets/images/sparky/bumper/c/inactive.png'); } class Assets { diff --git a/packages/pinball_components/lib/src/components/ball.dart b/packages/pinball_components/lib/src/components/ball.dart index 892936f9..cd682b00 100644 --- a/packages/pinball_components/lib/src/components/ball.dart +++ b/packages/pinball_components/lib/src/components/ball.dart @@ -44,6 +44,8 @@ class Ball extends BodyComponent anchor: Anchor.center, )..tint(tint), ); + + renderBody = false; } @override @@ -64,15 +66,19 @@ class Ball extends BodyComponent /// /// The [Ball] will no longer be affected by any forces, including it's /// weight and those emitted from collisions. + //TODO(allisonryan0002): prevent motion from contact with other balls. void stop() { - body.setType(BodyType.static); + body + ..gravityScale = 0 + ..linearVelocity = Vector2.zero() + ..angularVelocity = 0; } /// Allows the [Ball] to be affected by forces. /// /// If previously [stop]ed, the previous ball's velocity is not kept. void resume() { - body.setType(BodyType.dynamic); + body.gravityScale = 1; } @override @@ -96,7 +102,7 @@ class Ball extends BodyComponent /// Applies a boost on this [Ball]. void boost(Vector2 impulse) { - body.applyLinearImpulse(impulse); + body.linearVelocity = impulse; _boostTimer = _boostDuration; } diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 6b0c2ef5..d25e8f5f 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -20,3 +20,4 @@ export 'spaceship.dart'; export 'spaceship_rail.dart'; export 'spaceship_ramp.dart'; export 'sparky_bumper.dart'; +export 'sparky_computer.dart'; diff --git a/packages/pinball_components/lib/src/components/sparky_bumper.dart b/packages/pinball_components/lib/src/components/sparky_bumper.dart index e6a5f237..c4798624 100644 --- a/packages/pinball_components/lib/src/components/sparky_bumper.dart +++ b/packages/pinball_components/lib/src/components/sparky_bumper.dart @@ -27,8 +27,8 @@ class SparkyBumper extends BodyComponent with InitialPosition { : this._( majorRadius: 2.9, minorRadius: 2.1, - activeAssetPath: Assets.images.sparkyBumper.a.active.keyName, - inactiveAssetPath: Assets.images.sparkyBumper.a.inactive.keyName, + activeAssetPath: Assets.images.sparky.bumper.a.active.keyName, + inactiveAssetPath: Assets.images.sparky.bumper.a.inactive.keyName, spriteComponent: SpriteComponent( anchor: Anchor.center, position: Vector2(0, -0.25), @@ -40,8 +40,8 @@ class SparkyBumper extends BodyComponent with InitialPosition { : this._( majorRadius: 2.85, minorRadius: 2, - activeAssetPath: Assets.images.sparkyBumper.b.active.keyName, - inactiveAssetPath: Assets.images.sparkyBumper.b.inactive.keyName, + activeAssetPath: Assets.images.sparky.bumper.b.active.keyName, + inactiveAssetPath: Assets.images.sparky.bumper.b.inactive.keyName, spriteComponent: SpriteComponent( anchor: Anchor.center, position: Vector2(0, -0.35), @@ -53,8 +53,8 @@ class SparkyBumper extends BodyComponent with InitialPosition { : this._( majorRadius: 3, minorRadius: 2.2, - activeAssetPath: Assets.images.sparkyBumper.c.active.keyName, - inactiveAssetPath: Assets.images.sparkyBumper.c.inactive.keyName, + activeAssetPath: Assets.images.sparky.bumper.c.active.keyName, + inactiveAssetPath: Assets.images.sparky.bumper.c.inactive.keyName, spriteComponent: SpriteComponent( anchor: Anchor.center, position: Vector2(0, -0.4), diff --git a/packages/pinball_components/lib/src/components/sparky_computer.dart b/packages/pinball_components/lib/src/components/sparky_computer.dart new file mode 100644 index 00000000..0f02be71 --- /dev/null +++ b/packages/pinball_components/lib/src/components/sparky_computer.dart @@ -0,0 +1,109 @@ +// 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 sparky_computer} +/// A [Blueprint] which creates the [_ComputerBase] and [_ComputerTop]. +/// {@endtemplate} +class SparkyComputer extends Forge2DBlueprint { + @override + void build(_) { + final computerBase = _ComputerBase(); + final computerTop = _ComputerTop(); + + addAll([ + computerBase, + computerTop, + ]); + } +} + +class _ComputerBase extends BodyComponent with InitialPosition { + _ComputerBase(); + + List _createFixtureDefs() { + final fixturesDef = []; + + final leftEdge = EdgeShape() + ..set( + Vector2(-15.3, 46), + Vector2(-15.7, 49.6), + ); + final leftEdgeFixtureDef = FixtureDef(leftEdge); + fixturesDef.add(leftEdgeFixtureDef); + + final topEdge = EdgeShape() + ..set( + Vector2(-15.7, 49.6), + Vector2(-11.1, 50.6), + ); + final topEdgeFixtureDef = FixtureDef(topEdge); + fixturesDef.add(topEdgeFixtureDef); + + final rightEdge = EdgeShape() + ..set( + Vector2(-11.1, 50.6), + Vector2(-9.4, 47.2), + ); + final rightEdgeFixtureDef = FixtureDef(rightEdge); + fixturesDef.add(rightEdgeFixtureDef); + + return fixturesDef; + } + + @override + Body createBody() { + final bodyDef = BodyDef() + ..userData = this + ..position = initialPosition; + + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } + + @override + Future onLoad() async { + await super.onLoad(); + await _loadSprite(); + renderBody = false; + } + + Future _loadSprite() async { + final sprite = await gameRef.loadSprite( + Assets.images.sparky.computer.base.keyName, + ); + + await add( + SpriteComponent( + sprite: sprite, + size: sprite.originalSize / 10, + anchor: Anchor.center, + position: Vector2(-12.35, -48.35), + ), + ); + } +} + +class _ComputerTop extends SpriteComponent with HasGameRef { + _ComputerTop() + : super( + anchor: Anchor.center, + position: Vector2(-12.85, -49.75), + priority: 1, + ); + + @override + Future onLoad() async { + await super.onLoad(); + + final sprite = await gameRef.loadSprite( + Assets.images.sparky.computer.top.keyName, + ); + this.sprite = sprite; + size = sprite.originalSize / 10; + } +} diff --git a/packages/pinball_components/lib/src/flame/blueprint.dart b/packages/pinball_components/lib/src/flame/blueprint.dart index 57af7d6d..5c2df683 100644 --- a/packages/pinball_components/lib/src/flame/blueprint.dart +++ b/packages/pinball_components/lib/src/flame/blueprint.dart @@ -12,7 +12,8 @@ const _attachedErrorMessage = "Can't add to attached Blueprints"; /// A [Blueprint] is a virtual way of grouping [Component]s /// that are related, but they need to be added directly on /// the [FlameGame] level. -abstract class Blueprint { +// TODO(alestiago): refactor with feat/make-blueprint-extend-component. +abstract class Blueprint extends Component { final List _components = []; final List _blueprints = []; @@ -34,14 +35,9 @@ abstract class Blueprint { _isAttached = true; } - /// Adds a list of [Component]s to this blueprint. - void addAll(List components) { - assert(!_isAttached, _attachedErrorMessage); - _components.addAll(components); - } - /// Adds a single [Component] to this blueprint. - void add(Component component) { + @override + Future add(Component component) async { assert(!_isAttached, _attachedErrorMessage); _components.add(component); } diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 312e01f3..0790d101 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -39,9 +39,10 @@ flutter: - assets/images/spaceship/ramp/ - assets/images/chrome_dino/ - assets/images/kicker/ - - assets/images/sparky_bumper/a/ - - assets/images/sparky_bumper/b/ - - assets/images/sparky_bumper/c/ + - assets/images/sparky/computer/ + - assets/images/sparky/bumper/a/ + - assets/images/sparky/bumper/b/ + - assets/images/sparky/bumper/c/ flutter_gen: line_length: 80