feat(pinball_components): implemented LayerFilteringBehavior

pull/340/head
alestiago 3 years ago
parent ebdaaf953d
commit 2e189a8bcc

@ -21,8 +21,7 @@ enum LayerEntranceOrientation {
/// By default the base [layer] is set to [Layer.board] and the
/// [outsideZIndex] is set to [ZIndexes.ballOnBoard].
/// {@endtemplate}
abstract class LayerSensor extends BodyComponent
with InitialPosition, Layered, ContactCallbacks {
abstract class LayerSensor extends BodyComponent with InitialPosition, Layered {
/// {@macro layer_sensor}
LayerSensor({
required this.insideLayer,
@ -61,9 +60,7 @@ abstract class LayerSensor extends BodyComponent
shape,
isSensor: true,
);
final bodyDef = BodyDef(
position: initialPosition,
);
final bodyDef = BodyDef(position: initialPosition);
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}

@ -0,0 +1,136 @@
// 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_components/pinball_components.dart';
import 'package:pinball_components/src/components/layer_sensor/behaviors/behaviors.dart';
import '../../../../helpers/helpers.dart';
class _TestLayerSensor extends LayerSensor {
_TestLayerSensor({
required LayerEntranceOrientation orientation,
required int insideZIndex,
required Layer insideLayer,
}) : super(
insideLayer: insideLayer,
insideZIndex: insideZIndex,
orientation: orientation,
);
@override
Shape get shape => PolygonShape()..setAsBoxXY(1, 1);
}
class _MockBall extends Mock implements Ball {}
class _MockBody extends Mock implements Body {}
class _MockContact extends Mock implements Contact {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(TestGame.new);
group(
'LayerSensorBehavior',
() {
test('can be instantiated', () {
expect(
LayerFilteringBehavior(),
isA<LayerFilteringBehavior>(),
);
});
flameTester.test(
'loads',
(game) async {
final behavior = LayerFilteringBehavior();
final parent = _TestLayerSensor(
orientation: LayerEntranceOrientation.down,
insideZIndex: 1,
insideLayer: Layer.spaceshipEntranceRamp,
);
await parent.add(behavior);
await game.ensureAdd(parent);
expect(game.contains(parent), isTrue);
},
);
group('beginContact', () {
late Ball ball;
late Body body;
late int insideZIndex;
late Layer insideLayer;
setUp(() {
ball = _MockBall();
body = _MockBody();
insideZIndex = 1;
insideLayer = Layer.spaceshipEntranceRamp;
when(() => ball.body).thenReturn(body);
when(() => ball.layer).thenReturn(Layer.board);
});
flameTester.test(
'changes ball layer and zIndex '
'when a ball enters and exits a downward oriented LayerSensor',
(game) async {
final parent = _TestLayerSensor(
orientation: LayerEntranceOrientation.down,
insideZIndex: 1,
insideLayer: insideLayer,
)..initialPosition = Vector2(0, 10);
final behavior = LayerFilteringBehavior();
await parent.add(behavior);
await game.ensureAdd(parent);
when(() => body.linearVelocity).thenReturn(Vector2(0, -1));
behavior.beginContact(ball, _MockContact());
verify(() => ball.layer = insideLayer).called(1);
verify(() => ball.zIndex = insideZIndex).called(1);
when(() => ball.layer).thenReturn(insideLayer);
behavior.beginContact(ball, _MockContact());
verify(() => ball.layer = Layer.board);
verify(() => ball.zIndex = ZIndexes.ballOnBoard).called(1);
});
flameTester.test(
'changes ball layer and zIndex '
'when a ball enters and exits an upward oriented LayerSensor',
(game) async {
final parent = _TestLayerSensor(
orientation: LayerEntranceOrientation.up,
insideZIndex: 1,
insideLayer: insideLayer,
)..initialPosition = Vector2(0, 10);
final behavior = LayerFilteringBehavior();
await parent.add(behavior);
await game.ensureAdd(parent);
when(() => body.linearVelocity).thenReturn(Vector2(0, 1));
behavior.beginContact(ball, _MockContact());
verify(() => ball.layer = insideLayer).called(1);
verify(() => ball.zIndex = 1).called(1);
when(() => ball.layer).thenReturn(insideLayer);
behavior.beginContact(ball, _MockContact());
verify(() => ball.layer = Layer.board);
verify(() => ball.zIndex = ZIndexes.ballOnBoard).called(1);
});
});
},
);
}

@ -2,16 +2,10 @@
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_components/pinball_components.dart';
import 'package:pinball_components/src/components/layer_sensor/behaviors/behaviors.dart';
import '../../helpers/helpers.dart';
class _MockBall extends Mock implements Ball {}
class _MockBody extends Mock implements Body {}
class _MockContact extends Mock implements Contact {}
import '../../../helpers/helpers.dart';
class TestLayerSensor extends LayerSensor {
TestLayerSensor({
@ -112,68 +106,22 @@ void main() {
);
});
});
});
group('beginContact', () {
late Ball ball;
late Body body;
late int insideZIndex;
late Layer insideLayer;
setUp(() {
ball = _MockBall();
body = _MockBody();
insideZIndex = 1;
insideLayer = Layer.spaceshipEntranceRamp;
when(() => ball.body).thenReturn(body);
when(() => ball.layer).thenReturn(Layer.board);
});
flameTester.test(
'changes ball layer and zIndex '
'when a ball enters and exits a downward oriented LayerSensor',
(game) async {
final sensor = TestLayerSensor(
orientation: LayerEntranceOrientation.down,
insideZIndex: insidePriority,
insideLayer: insideLayer,
)..initialPosition = Vector2(0, 10);
when(() => body.linearVelocity).thenReturn(Vector2(0, -1));
sensor.beginContact(ball, _MockContact());
verify(() => ball.layer = insideLayer).called(1);
verify(() => ball.zIndex = insideZIndex).called(1);
when(() => ball.layer).thenReturn(insideLayer);
sensor.beginContact(ball, _MockContact());
verify(() => ball.layer = Layer.board);
verify(() => ball.zIndex = ZIndexes.ballOnBoard).called(1);
});
flameTester.test(
'changes ball layer and zIndex '
'when a ball enters and exits an upward oriented LayerSensor',
(game) async {
final sensor = TestLayerSensor(
orientation: LayerEntranceOrientation.up,
insideZIndex: insidePriority,
insideLayer: insideLayer,
)..initialPosition = Vector2(0, 10);
when(() => body.linearVelocity).thenReturn(Vector2(0, 1));
sensor.beginContact(ball, _MockContact());
verify(() => ball.layer = insideLayer).called(1);
verify(() => ball.zIndex = insidePriority).called(1);
when(() => ball.layer).thenReturn(insideLayer);
'adds a LayerFilteringBehavior',
(game) async {
final layerSensor = TestLayerSensor(
orientation: LayerEntranceOrientation.down,
insideZIndex: insidePriority,
insideLayer: Layer.spaceshipEntranceRamp,
);
await game.ensureAdd(layerSensor);
sensor.beginContact(ball, _MockContact());
verify(() => ball.layer = Layer.board);
verify(() => ball.zIndex = ZIndexes.ballOnBoard).called(1);
});
expect(
layerSensor.children.whereType<LayerFilteringBehavior>().length,
equals(1),
);
},
);
});
}
Loading…
Cancel
Save