diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 61e04074..2112972b 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -12,7 +12,7 @@ class Ball extends BodyComponent with Layered { required Vector2 position, Layer? layer, }) : _position = position, - _layer = layer ?? Layer.all; + _layer = layer ?? Layer.board; /// The initial position of the [Ball] body. final Vector2 _position; diff --git a/lib/game/components/jetpack_ramp.dart b/lib/game/components/jetpack_ramp.dart index 9039fe3a..aa97a1bf 100644 --- a/lib/game/components/jetpack_ramp.dart +++ b/lib/game/components/jetpack_ramp.dart @@ -19,8 +19,6 @@ class JetpackRamp extends Component with HasGameRef { final double _width = 80; final double _angle = radians(210); final double _rotation = radians(-10); - final double _entranceRotation = radians(15); - final double _exitRotation = radians(-5); /// The position of this [JetpackRamp] final Vector2 position; @@ -41,16 +39,16 @@ class JetpackRamp extends Component with HasGameRef { await add( JetpackRampOpening( - position: position + Vector2(-10.5, 0), - rotation: _entranceRotation, + position: position + Vector2(-11, .5), orientation: RampOrientation.down, + rotation: radians(15), ), ); await add( JetpackRampOpening( - position: position + Vector2(20.5, 3), - rotation: _exitRotation, + position: position + Vector2(20.5, 3.4), orientation: RampOrientation.down, + rotation: radians(-9), ), ); @@ -66,13 +64,15 @@ class JetpackRampOpening extends RampOpening { /// {@macro jetpack_ramp_opening} JetpackRampOpening({ required Vector2 position, - double rotation = 0, required RampOrientation orientation, + double rotation = 0, + Layer? openingLayer, }) : _rotation = rotation, _orientation = orientation, super( position: position, - layer: Layer.jetpack, + pathwayLayer: Layer.jetpack, + openingLayer: openingLayer, ); /// Orientation of entrance/exit of [JetpackRamp] where diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index 5f90a228..b38323b5 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -33,6 +33,7 @@ class LauncherRamp extends Component with HasGameRef { start: Vector2(0, 0), end: Vector2(0, 600), width: 80, + layer: Layer.launcher, ), ); @@ -48,7 +49,7 @@ class LauncherRamp extends Component with HasGameRef { ); await add( LauncherRampOpening( - position: position + Vector2(-46.5, -9), + position: position + Vector2(-46.5, -8.5), orientation: RampOrientation.down, rotation: radians(13), ), @@ -78,7 +79,7 @@ class LauncherRampOpening extends RampOpening { _orientation = orientation, super( position: position, - layer: Layer.launcher, + pathwayLayer: Layer.launcher, ); /// Orientation of entrance/exit of [LauncherRamp] where diff --git a/lib/game/components/layer.dart b/lib/game/components/layer.dart index fc53bc14..af3f8ce0 100644 --- a/lib/game/components/layer.dart +++ b/lib/game/components/layer.dart @@ -29,6 +29,9 @@ enum Layer { /// Collide with all elements. all, + /// Collide only with board elements (the ground level). + board, + /// Collide only with Jetpack group elements. jetpack, @@ -43,6 +46,8 @@ extension LayerX on Layer { switch (this) { case Layer.all: return 0xFFFF; + case Layer.board: + return 0xFF0F; case Layer.jetpack: return 0x0010; case Layer.launcher: @@ -66,24 +71,31 @@ enum RampOrientation { /// [BodyComponent] located at the entrance and exit of a ramp. /// /// [RampOpeningBallContactCallback] detects when a [Ball] passes -/// through this opening. +/// through this opening. By default openings are [Layer.board] that +/// means opening are at ground level, not over board. /// {@endtemplate} abstract class RampOpening extends BodyComponent { /// {@macro ramp_opening} RampOpening({ required Vector2 position, - required Layer layer, + required Layer pathwayLayer, + Layer? openingLayer, }) : _position = position, - _layer = layer { + _pathwayLayer = pathwayLayer, + _openingLayer = openingLayer ?? Layer.board { // TODO(ruialonso): remove paint color for BodyComponent. // Left white for dev and testing. } final Vector2 _position; - final Layer _layer; + final Layer _openingLayer; + final Layer _pathwayLayer; /// Mask of category bits for collision with [RampOpening] - Layer get layer => _layer; + Layer get openingLayer => _openingLayer; + + /// Mask of category bits for collision inside [Pathway] + Layer get pathwayLayer => _pathwayLayer; /// The [Shape] of the [RampOpening] Shape get shape; @@ -95,7 +107,7 @@ abstract class RampOpening extends BodyComponent { Body createBody() { final fixtureDef = FixtureDef(shape) ..isSensor = true - ..filter.categoryBits = _layer.maskBits; + ..filter.categoryBits = _openingLayer.maskBits; final bodyDef = BodyDef() ..userData = this @@ -126,10 +138,12 @@ abstract class RampOpeningBallContactCallback ) { Layer layer; if (!ballsInside.contains(ball)) { - layer = opening.layer; + layer = opening.pathwayLayer; + print('TOUCH begin (add) layer=$layer'); ballsInside.add(ball); } else { - layer = Layer.all; + layer = Layer.board; + print('TOUCH begin (remove) layer=$layer'); ballsInside.remove(ball); } @@ -142,13 +156,19 @@ abstract class RampOpeningBallContactCallback switch (opening.orientation) { case RampOrientation.up: + print('TOUCH end up'); if (ball.body.position.y > opening._position.y) { - layer = Layer.all; + print('layer=$layer'); + layer = Layer.board; + print('layer=$layer'); } break; case RampOrientation.down: + print('TOUCH end down'); if (ball.body.position.y < opening._position.y) { - layer = Layer.all; + print('layer=$layer'); + layer = Layer.board; + print('layer=$layer'); } break; } diff --git a/test/game/components/layer_test.dart b/test/game/components/layer_test.dart index c75e70d1..cbf53b66 100644 --- a/test/game/components/layer_test.dart +++ b/test/game/components/layer_test.dart @@ -13,7 +13,7 @@ class TestRampOpening extends RampOpening { required RampOrientation orientation, required Layer layer, }) : _orientation = orientation, - super(position: position, layer: layer); + super(position: position, pathwayLayer: layer); final RampOrientation _orientation; @@ -42,20 +42,24 @@ class TestRampOpeningBallContactCallback void main() { group('Layer', () { - test('has three values', () { - expect(Layer.values.length, equals(3)); + test('has four values', () { + expect(Layer.values.length, equals(4)); }); }); group('LayerX', () { test('all types are different', () { - expect(Layer.all.maskBits, isNot(equals(Layer.jetpack.maskBits))); + expect(Layer.all.maskBits, isNot(equals(Layer.board.maskBits))); + expect(Layer.board.maskBits, isNot(equals(Layer.jetpack.maskBits))); expect(Layer.jetpack.maskBits, isNot(equals(Layer.launcher.maskBits))); - expect(Layer.launcher.maskBits, isNot(equals(Layer.all.maskBits))); + expect(Layer.launcher.maskBits, isNot(equals(Layer.board.maskBits))); }); - test('all type has default maskBits', () { - expect(Layer.all.maskBits, equals(0xFFFF)); + test('all type has 0xFFFF maskBits', () { + expect(Layer.all.maskBits, equals(0xFF0F)); + }); + test('board type has 0xFF0F maskBits', () { + expect(Layer.board.maskBits, equals(0xFF0F)); }); test('jetpack type has 0x010 maskBits', () { @@ -77,7 +81,7 @@ void main() { final ramp = TestRampOpening( position: Vector2.zero(), orientation: RampOrientation.down, - layer: Layer.all, + layer: Layer.board, ); await game.ready(); await game.ensureAdd(ramp); @@ -94,7 +98,7 @@ void main() { final ramp = TestRampOpening( position: position, orientation: RampOrientation.down, - layer: Layer.all, + layer: Layer.board, ); await game.ensureAdd(ramp); @@ -109,7 +113,7 @@ void main() { final ramp = TestRampOpening( position: Vector2.zero(), orientation: RampOrientation.down, - layer: Layer.all, + layer: Layer.board, ); await game.ensureAdd(ramp); @@ -213,7 +217,7 @@ void main() { callback.end(ball, area, MockContact()); - verifyNever(() => ball.layer = Layer.all); + verifyNever(() => ball.layer = Layer.board); }); test( @@ -240,7 +244,7 @@ void main() { callback.end(ball, area, MockContact()); - verifyNever(() => ball.layer = Layer.all); + verifyNever(() => ball.layer = Layer.board); }); test( @@ -267,7 +271,7 @@ void main() { callback.end(ball, area, MockContact()); - verify(() => ball.layer = Layer.all); + verify(() => ball.layer = Layer.board); }); test( @@ -289,11 +293,11 @@ void main() { callback.begin(ball, area, MockContact()); expect(callback._ballsInside.isEmpty, isTrue); - verify(() => ball.layer = Layer.all).called(1); + verify(() => ball.layer = Layer.board).called(1); callback.end(ball, area, MockContact()); - verify(() => ball.layer = Layer.all).called(1); + verify(() => ball.layer = Layer.board).called(1); }); test( @@ -315,11 +319,11 @@ void main() { callback.begin(ball, area, MockContact()); expect(callback._ballsInside.isEmpty, isTrue); - verify(() => ball.layer = Layer.all).called(1); + verify(() => ball.layer = Layer.board).called(1); callback.end(ball, area, MockContact()); - verify(() => ball.layer = Layer.all).called(1); + verify(() => ball.layer = Layer.board).called(1); }); }); }