refactor: move ramp sensor to spaceship ramp children

pull/296/head
RuiAlonso 3 years ago
parent 98cd44ce22
commit 081a22f69a

@ -15,7 +15,18 @@ class AndroidAcres extends Component {
AndroidAcres() AndroidAcres()
: super( : super(
children: [ children: [
SpaceshipRamp(), SpaceshipRamp(
children: [
RampShotBehavior(
points: Points.fiveThousand,
scorePosition: Vector2(0, -45),
),
RampBonusBehavior(
points: Points.oneMillion,
scorePosition: Vector2(0, -60),
),
],
),
SpaceshipRail(), SpaceshipRail(),
AndroidSpaceship(position: Vector2(-26.5, -28.5)), AndroidSpaceship(position: Vector2(-26.5, -28.5)),
AndroidBumper.a( AndroidBumper.a(
@ -33,20 +44,6 @@ class AndroidAcres extends Component {
ScoringBehavior(points: Points.twentyThousand), ScoringBehavior(points: Points.twentyThousand),
], ],
)..initialPosition = Vector2(-20.5, -13.8), )..initialPosition = Vector2(-20.5, -13.8),
RampShotBehavior(
points: 5000,
scorePosition: Vector2(0, -45),
),
RampBonusBehavior(
points: 1000000,
scorePosition: Vector2(0, -60),
),
], ],
); );
/// Creates a [AndroidAcres] without any children.
///
/// This can be used for testing [AndroidAcres]'s behaviors in isolation.
@visibleForTesting
AndroidAcres.test();
} }

@ -10,17 +10,17 @@ import 'package:pinball_flame/pinball_flame.dart';
/// When a [Ball] shot inside the [SpaceshipRamp] 10 times increases score. /// When a [Ball] shot inside the [SpaceshipRamp] 10 times increases score.
/// {@endtemplate} /// {@endtemplate}
class RampBonusBehavior extends Component class RampBonusBehavior extends Component
with ParentIsA<AndroidAcres>, HasGameRef<PinballGame> { with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> {
/// {@macro ramp_bonus_behavior} /// {@macro ramp_bonus_behavior}
RampBonusBehavior({ RampBonusBehavior({
required int points, required Points points,
required Vector2 scorePosition, required Vector2 scorePosition,
}) : _points = points, }) : _points = points,
_scorePosition = scorePosition, _scorePosition = scorePosition,
super(); super();
final int _oneMillionPointsTimes = 10; final int _oneMillionPointsTimes = 10;
final int _points; final Points _points;
final Vector2 _scorePosition; final Vector2 _scorePosition;
final Set<Ball> _balls = HashSet(); final Set<Ball> _balls = HashSet();
@ -30,12 +30,7 @@ class RampBonusBehavior extends Component
void onMount() { void onMount() {
super.onMount(); super.onMount();
final sensors = parent final sensors = parent.descendants().whereType<RampSensor>();
.descendants()
.whereType<SpaceshipRamp>()
.first
.descendants()
.whereType<RampSensor>();
for (final sensor in sensors) { for (final sensor in sensors) {
sensor.bloc.stream.listen((state) { sensor.bloc.stream.listen((state) {
@ -69,10 +64,10 @@ class RampBonusBehavior extends Component
/// current game, like multipliers or score. /// current game, like multipliers or score.
void _shot(int currentHits) { void _shot(int currentHits) {
if (currentHits % _oneMillionPointsTimes == 0) { if (currentHits % _oneMillionPointsTimes == 0) {
gameRef.read<GameBloc>().add(Scored(points: _points)); gameRef.read<GameBloc>().add(Scored(points: _points.value));
gameRef.add( gameRef.add(
ScoreText( ScoreComponent(
text: _points.toString(), points: _points,
position: _getRandomPosition, position: _getRandomPosition,
), ),
); );

@ -11,16 +11,16 @@ import 'package:pinball_flame/pinball_flame.dart';
/// the current game, like multipliers or score. /// the current game, like multipliers or score.
/// {@endtemplate} /// {@endtemplate}
class RampShotBehavior extends Component class RampShotBehavior extends Component
with ParentIsA<AndroidAcres>, HasGameRef<PinballGame> { with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> {
/// {@macro ramp_shot_behavior} /// {@macro ramp_shot_behavior}
RampShotBehavior({ RampShotBehavior({
required int points, required Points points,
required Vector2 scorePosition, required Vector2 scorePosition,
}) : _points = points, }) : _points = points,
_scorePosition = scorePosition, _scorePosition = scorePosition,
super(); super();
final int _points; final Points _points;
final Vector2 _scorePosition; final Vector2 _scorePosition;
final Set<Ball> _balls = HashSet(); final Set<Ball> _balls = HashSet();
@ -29,12 +29,7 @@ class RampShotBehavior extends Component
void onMount() { void onMount() {
super.onMount(); super.onMount();
final sensors = parent final sensors = parent.descendants().whereType<RampSensor>();
.descendants()
.whereType<SpaceshipRamp>()
.first
.descendants()
.whereType<RampSensor>();
for (final sensor in sensors) { for (final sensor in sensors) {
sensor.bloc.stream.listen((state) { sensor.bloc.stream.listen((state) {
@ -64,14 +59,14 @@ class RampShotBehavior extends Component
} }
void _shot() { void _shot() {
parent.descendants().whereType<SpaceshipRamp>().first.progress(); parent.progress();
gameRef.read<GameBloc>() gameRef.read<GameBloc>()
..add(const MultiplierIncreased()) ..add(const MultiplierIncreased())
..add(Scored(points: _points)); ..add(Scored(points: _points.value));
gameRef.add( gameRef.add(
ScoreText( ScoreComponent(
text: _points.toString(), points: _points,
position: _getRandomPosition, position: _getRandomPosition,
), ),
); );

@ -15,8 +15,9 @@ export 'cubit/ramp_sensor_cubit.dart';
/// {@endtemplate} /// {@endtemplate}
class SpaceshipRamp extends Component { class SpaceshipRamp extends Component {
/// {@macro spaceship_ramp} /// {@macro spaceship_ramp}
SpaceshipRamp() SpaceshipRamp({
: super( Iterable<Component>? children,
}) : super(
children: [ children: [
// TODO(ruimiguel): refactor RampSensor and RampOpening to be in // TODO(ruimiguel): refactor RampSensor and RampOpening to be in
// only one sensor. // only one sensor.
@ -44,9 +45,16 @@ class SpaceshipRamp extends Component {
_SpaceshipRampBase()..initialPosition = Vector2(1.7, -20), _SpaceshipRampBase()..initialPosition = Vector2(1.7, -20),
_SpaceshipRampBackgroundRailingSpriteComponent(), _SpaceshipRampBackgroundRailingSpriteComponent(),
_SpaceshipRampArrowSpriteComponent(), _SpaceshipRampArrowSpriteComponent(),
...?children,
], ],
); );
/// Creates a [SpaceshipRamp] without any children.
///
/// This can be used for testing [SpaceshipRamp]'s behaviors in isolation.
@visibleForTesting
SpaceshipRamp.test();
/// Forwards the sprite to the next [SpaceshipRampArrowSpriteState]. /// Forwards the sprite to the next [SpaceshipRampArrowSpriteState].
/// ///
/// If the current state is the last one it cycles back to the initial state. /// If the current state is the last one it cycles back to the initial state.

@ -7,7 +7,7 @@ import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mockingjay/mockingjay.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart'; import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
@ -17,9 +17,6 @@ import '../../../../helpers/helpers.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
final assets = [ final assets = [
Assets.images.android.spaceship.saucer.keyName,
Assets.images.android.spaceship.animatronic.keyName,
Assets.images.android.spaceship.lightBeam.keyName,
Assets.images.android.ramp.boardOpening.keyName, Assets.images.android.ramp.boardOpening.keyName,
Assets.images.android.ramp.railingForeground.keyName, Assets.images.android.ramp.railingForeground.keyName,
Assets.images.android.ramp.railingBackground.keyName, Assets.images.android.ramp.railingBackground.keyName,
@ -32,16 +29,11 @@ void main() {
Assets.images.android.ramp.arrow.active5.keyName, Assets.images.android.ramp.arrow.active5.keyName,
Assets.images.android.rail.main.keyName, Assets.images.android.rail.main.keyName,
Assets.images.android.rail.exit.keyName, Assets.images.android.rail.exit.keyName,
Assets.images.android.bumper.a.lit.keyName, Assets.images.score.oneMillion.keyName,
Assets.images.android.bumper.a.dimmed.keyName,
Assets.images.android.bumper.b.lit.keyName,
Assets.images.android.bumper.b.dimmed.keyName,
Assets.images.android.bumper.cow.lit.keyName,
Assets.images.android.bumper.cow.dimmed.keyName,
]; ];
group('RampBonusBehavior', () { group('RampBonusBehavior', () {
const bonusPoints = 1000000; const bonusPoints = Points.oneMillion;
late GameBloc gameBloc; late GameBloc gameBloc;
@ -68,7 +60,7 @@ void main() {
points: bonusPoints, points: bonusPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final sensors = [ final sensors = [
RampSensor.test( RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
@ -85,10 +77,10 @@ void main() {
} }
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(Scored(points: bonusPoints))); verifyNever(() => gameBloc.add(Scored(points: bonusPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },
); );
@ -103,7 +95,7 @@ void main() {
points: bonusPoints, points: bonusPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -121,10 +113,10 @@ void main() {
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(Scored(points: bonusPoints))); verifyNever(() => gameBloc.add(Scored(points: bonusPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },
); );
@ -134,12 +126,11 @@ void main() {
"less than 10 times doesn't add any score neither shows score points", "less than 10 times doesn't add any score neither shows score points",
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const bonusPoints = 1000000;
final behavior = RampBonusBehavior( final behavior = RampBonusBehavior(
points: bonusPoints, points: bonusPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -158,10 +149,10 @@ void main() {
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(Scored(points: bonusPoints))); verifyNever(() => gameBloc.add(Scored(points: bonusPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },
); );
@ -171,12 +162,11 @@ void main() {
'10 times add score and show score point', '10 times add score and show score point',
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const bonusPoints = 1000000;
final behavior = RampBonusBehavior( final behavior = RampBonusBehavior(
points: bonusPoints, points: bonusPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -197,10 +187,10 @@ void main() {
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verify(() => gameBloc.add(Scored(points: bonusPoints))).called(1); verify(() => gameBloc.add(Scored(points: bonusPoints.value))).called(1);
expect(scores.length, 1); expect(scores.length, 1);
}, },
); );

@ -7,7 +7,7 @@ import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mockingjay/mockingjay.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart'; import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
@ -17,9 +17,6 @@ import '../../../../helpers/helpers.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
final assets = [ final assets = [
Assets.images.android.spaceship.saucer.keyName,
Assets.images.android.spaceship.animatronic.keyName,
Assets.images.android.spaceship.lightBeam.keyName,
Assets.images.android.ramp.boardOpening.keyName, Assets.images.android.ramp.boardOpening.keyName,
Assets.images.android.ramp.railingForeground.keyName, Assets.images.android.ramp.railingForeground.keyName,
Assets.images.android.ramp.railingBackground.keyName, Assets.images.android.ramp.railingBackground.keyName,
@ -32,15 +29,12 @@ void main() {
Assets.images.android.ramp.arrow.active5.keyName, Assets.images.android.ramp.arrow.active5.keyName,
Assets.images.android.rail.main.keyName, Assets.images.android.rail.main.keyName,
Assets.images.android.rail.exit.keyName, Assets.images.android.rail.exit.keyName,
Assets.images.android.bumper.a.lit.keyName, Assets.images.score.fiveThousand.keyName,
Assets.images.android.bumper.a.dimmed.keyName,
Assets.images.android.bumper.b.lit.keyName,
Assets.images.android.bumper.b.dimmed.keyName,
Assets.images.android.bumper.cow.lit.keyName,
Assets.images.android.bumper.cow.dimmed.keyName,
]; ];
group('RampShotBehavior', () { group('RampShotBehavior', () {
const shotPoints = Points.fiveThousand;
late GameBloc gameBloc; late GameBloc gameBloc;
setUp(() { setUp(() {
@ -63,12 +57,11 @@ void main() {
'neither add any score or show any score points', 'neither add any score or show any score points',
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const shotPoints = 5000;
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final sensors = [ final sensors = [
RampSensor.test( RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
@ -85,11 +78,11 @@ void main() {
} }
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(MultiplierIncreased())); verifyNever(() => gameBloc.add(MultiplierIncreased()));
verifyNever(() => gameBloc.add(Scored(points: shotPoints))); verifyNever(() => gameBloc.add(Scored(points: shotPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },
); );
@ -99,12 +92,11 @@ void main() {
"doesn't increase multiplier neither add any score or shows score points", "doesn't increase multiplier neither add any score or shows score points",
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const shotPoints = 5000;
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -122,11 +114,11 @@ void main() {
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(MultiplierIncreased())); verifyNever(() => gameBloc.add(MultiplierIncreased()));
verifyNever(() => gameBloc.add(Scored(points: shotPoints))); verifyNever(() => gameBloc.add(Scored(points: shotPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },
); );
@ -136,12 +128,11 @@ void main() {
'increase multiplier', 'increase multiplier',
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const shotPoints = 5000;
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -155,10 +146,11 @@ void main() {
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
doorSensor.bloc.onDoor(ball); insideSensor.bloc.onDoor(ball);
insideSensor.bloc.onInside(ball); insideSensor.bloc.onInside(ball);
await tester.pump(); await tester.pump();
await game.ready();
verify(() => gameBloc.add(MultiplierIncreased())).called(1); verify(() => gameBloc.add(MultiplierIncreased())).called(1);
}, },
@ -169,12 +161,11 @@ void main() {
'add score and show score points', 'add score and show score points',
setUp: (game, tester) async { setUp: (game, tester) async {
final ball = Ball(baseColor: Colors.red); final ball = Ball(baseColor: Colors.red);
const shotPoints = 5000;
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(), scorePosition: Vector2.zero(),
); );
final parent = AndroidAcres.test(); final parent = SpaceshipRamp.test();
final doorSensor = RampSensor.test( final doorSensor = RampSensor.test(
type: RampSensorType.door, type: RampSensorType.door,
bloc: RampSensorCubit(), bloc: RampSensorCubit(),
@ -193,10 +184,10 @@ void main() {
await tester.pump(); await tester.pump();
final scores = game.descendants().whereType<ScoreText>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verify(() => gameBloc.add(Scored(points: shotPoints))).called(1); verify(() => gameBloc.add(Scored(points: shotPoints.value))).called(1);
expect(scores.length, 1); expect(scores.length, 1);
}, },
); );

Loading…
Cancel
Save