diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 41f54a67..f8b24526 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -8,12 +8,9 @@ import 'package:pinball/game/game.dart'; /// {@endtemplate} class Ball extends BodyComponent with InitialPosition, Layered { /// {@macro ball} - Ball({ - Layer? layer, - }) : _layer = layer ?? Layer.board; - - /// [Layer] of the board that the [Ball] will interact with. - final Layer _layer; + Ball() { + layer = Layer.board; + } /// The size of the [Ball] final Vector2 size = Vector2.all(2); @@ -41,9 +38,7 @@ class Ball extends BodyComponent with InitialPosition, Layered { Body createBody() { final shape = CircleShape()..radius = size.x / 2; - final fixtureDef = FixtureDef(shape) - ..density = 1 - ..filter.maskBits = _layer.maskBits; + final fixtureDef = FixtureDef(shape)..density = 1; final bodyDef = BodyDef() ..position = initialPosition diff --git a/lib/game/components/jetpack_ramp.dart b/lib/game/components/jetpack_ramp.dart index 0180bb64..d871caa4 100644 --- a/lib/game/components/jetpack_ramp.dart +++ b/lib/game/components/jetpack_ramp.dart @@ -23,36 +23,39 @@ class JetpackRamp extends Component with HasGameRef { /// The position of this [JetpackRamp] final Vector2 position; + static const _layer = Layer.jetpack; + @override Future onLoad() async { - await add( - Pathway.arc( - color: const Color.fromARGB(255, 8, 218, 241), - center: position, - width: _width, - radius: _radius, - angle: _angle, - rotation: _rotation, - layer: Layer.jetpack, - )..initialPosition = position, - ); - - await add( - JetpackRampOpening( - orientation: RampOrientation.down, - rotation: radians(15), - )..initialPosition = position + Vector2(-11, 1), - ); - await add( - JetpackRampOpening( - orientation: RampOrientation.down, - rotation: radians(-9), - )..initialPosition = position + Vector2(20.5, 3.4), - ); - gameRef.addContactCallback( RampOpeningBallContactCallback(), ); + + final curvePath = Pathway.arc( + // TODO(ruialonso): Remove color when not needed. + // TODO(ruialonso): Use a bezier curve once control points are defined. + color: const Color.fromARGB(255, 8, 218, 241), + center: position, + width: _width, + radius: _radius, + angle: _angle, + rotation: _rotation, + layer: _layer, + )..initialPosition = position; + final leftOpening = JetpackRampOpening( + orientation: RampOrientation.down, + rotation: radians(15), + )..initialPosition = position + Vector2(-11, 1); + final rightOpening = JetpackRampOpening( + orientation: RampOrientation.down, + rotation: radians(-9), + )..initialPosition = position + Vector2(20.5, 3.4); + + await addAll([ + curvePath, + leftOpening, + rightOpening, + ]); } } diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index 7969617c..d6259ae4 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -26,41 +26,39 @@ class LauncherRamp extends Component with HasGameRef { @override Future onLoad() async { - await add( - Pathway.straight( - color: const Color.fromARGB(255, 34, 255, 0), - start: Vector2(0, 0), - end: Vector2(0, 600), - width: 80, - layer: Layer.launcher, - )..initialPosition = position, - ); - - await add( - Pathway.arc( - color: const Color.fromARGB(255, 251, 255, 0), - center: position + Vector2(-28.8, -6), - radius: _radius, - angle: _angle, - width: _width, - layer: Layer.launcher, - )..initialPosition = position + Vector2(-28.8, -6), - ); - await add( - LauncherRampOpening( - orientation: RampOrientation.down, - rotation: radians(13), - )..initialPosition = position + Vector2(-46.5, -8.5), - ); - await add( - LauncherRampOpening( - orientation: RampOrientation.down, - )..initialPosition = position + Vector2(4, 0), - ); - gameRef.addContactCallback( RampOpeningBallContactCallback(), ); + + final straightPath = Pathway.straight( + color: const Color.fromARGB(255, 34, 255, 0), + start: Vector2(0, 0), + end: Vector2(0, 600), + width: 80, + layer: Layer.launcher, + )..initialPosition = position; + final curvedPath = Pathway.arc( + color: const Color.fromARGB(255, 251, 255, 0), + center: position + Vector2(-28.8, -6), + radius: _radius, + angle: _angle, + width: _width, + layer: Layer.launcher, + )..initialPosition = position + Vector2(-28.8, -6); + final leftOpening = LauncherRampOpening( + orientation: RampOrientation.down, + rotation: radians(13), + )..initialPosition = position + Vector2(-46.5, -8.5); + final rightOpening = LauncherRampOpening( + orientation: RampOrientation.down, + )..initialPosition = position + Vector2(4, 0); + + await addAll([ + straightPath, + curvedPath, + leftOpening, + rightOpening, + ]); } } diff --git a/lib/game/components/layer.dart b/lib/game/components/layer.dart index ef27e01f..45e7f9ec 100644 --- a/lib/game/components/layer.dart +++ b/lib/game/components/layer.dart @@ -11,12 +11,22 @@ import 'package:pinball/game/game.dart'; /// bodies with a different bit value. /// {@endtemplate} mixin Layered on BodyComponent { - /// Sets [Filter] category and mask bits for the [BodyComponent] - set layer(Layer layer) { - for (final fixture in body.fixtures) { - fixture - ..filterData.categoryBits = layer.maskBits - ..filterData.maskBits = layer.maskBits; + Layer _layer = Layer.board; + + /// Sets [Filter] category and mask bits for the [BodyComponent]. + Layer get layer => _layer; + + set layer(Layer value) { + _layer = value; + if (!isLoaded) { + // TODO(erickzanardo): Use loaded.whenComplete once provided. + mounted.whenComplete(() => layer = value); + } else { + for (final fixture in body.fixtures) { + fixture + ..filterData.categoryBits = layer.maskBits + ..filterData.maskBits = layer.maskBits; + } } } }