feat: added controller for multiball

pull/235/head
RuiAlonso 3 years ago
parent ff668c0371
commit 2efa110718

@ -3,6 +3,7 @@ export 'board.dart';
export 'camera_controller.dart'; export 'camera_controller.dart';
export 'controlled_ball.dart'; export 'controlled_ball.dart';
export 'controlled_flipper.dart'; export 'controlled_flipper.dart';
export 'controlled_multiball.dart';
export 'controlled_plunger.dart'; export 'controlled_plunger.dart';
export 'flutter_forest.dart'; export 'flutter_forest.dart';
export 'game_flow_controller.dart'; export 'game_flow_controller.dart';

@ -0,0 +1,52 @@
import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/material.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template multiball_group_component}
/// A [SpriteGroupComponent] for the multiball over the board.
/// {@endtemplate}
class MultiballGroup extends Component
with Controls<MultiballController>, HasGameRef<PinballGame> {
/// {@macro multiball_group_component}
MultiballGroup()
: super(
children: [
Multiball.a(),
Multiball.b(),
Multiball.c(),
Multiball.d(),
],
) {
controller = MultiballController(this);
}
}
/// {@template multiball_controller}
/// Controller attached to a [MultiballGroup] that handles its game related
/// logic.
/// {@endtemplate}
@visibleForTesting
class MultiballController extends ComponentController<MultiballGroup>
with BlocComponent<GameBloc, GameState>, HasGameRef<PinballGame> {
/// {@macro multiball_controller}
MultiballController(MultiballGroup multiballGroup) : super(multiballGroup);
@override
bool listenWhen(GameState? previousState, GameState newState) {
return previousState?.bonusHistory != newState.bonusHistory;
}
@override
void onNewState(GameState state) {
final isMultiball = state.bonusHistory.contains(GameBonus.dashNest);
if (isMultiball) {
component.children.whereType<Multiball>().forEach((element) {
element.animate();
});
}
}
}

@ -55,6 +55,7 @@ class PinballGame extends Forge2DGame
final launcher = Launcher(); final launcher = Launcher();
unawaited(addFromBlueprint(launcher)); unawaited(addFromBlueprint(launcher));
unawaited(add(Board())); unawaited(add(Board()));
unawaited(add(MultiballGroup()));
unawaited(add(AlienZone())); unawaited(add(AlienZone()));
await addFromBlueprint(SparkyFireZone()); await addFromBlueprint(SparkyFireZone());
unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(Slingshots()));

@ -0,0 +1,111 @@
// ignore_for_file: cascade_invocations
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.multiball.a.active.keyName,
Assets.images.multiball.a.inactive.keyName,
Assets.images.multiball.b.active.keyName,
Assets.images.multiball.b.inactive.keyName,
Assets.images.multiball.c.active.keyName,
Assets.images.multiball.c.inactive.keyName,
Assets.images.multiball.d.active.keyName,
Assets.images.multiball.d.inactive.keyName,
];
final flameTester = FlameTester(() => EmptyPinballTestGame(assets));
group('MultiballGroup', () {
flameTester.test(
'loads correctly',
(game) async {
final multiballGroup = MultiballGroup();
await game.ensureAdd(multiballGroup);
expect(game.contains(multiballGroup), isTrue);
},
);
group('loads', () {
flameTester.test(
'four Multiball',
(game) async {
final multiballGroup = MultiballGroup();
await game.ensureAdd(multiballGroup);
expect(
multiballGroup.descendants().whereType<Multiball>().length,
equals(4),
);
},
);
});
});
group('MultiballController', () {
group('controller', () {
group('listenWhen', () {
flameTester.test(
'listens when obtain a multiball bonus',
(game) async {
const previous = GameState.initial();
final state = previous.copyWith(bonusHistory: [GameBonus.dashNest]);
final multiballGroup = MultiballGroup();
await game.ensureAdd(multiballGroup);
expect(
multiballGroup.controller.listenWhen(previous, state),
isTrue,
);
},
);
flameTester.test(
"doesn't listen when bonus is the same",
(game) async {
const previous = GameState.initial();
final multiballGroup = MultiballGroup();
await game.ensureAdd(multiballGroup);
expect(
multiballGroup.controller.listenWhen(previous, previous),
isFalse,
);
},
);
});
/*
group(
'onNewState',
() {
flameTester.test(
'blink multiballs when state changes',
(game) async {
final multiballGroup = MockMultiballGroup();
final x2multiplier = MockMultiplier();
final controller = MultiballController(multiballGroup);
when(() => multiballGroup.x2multiplier).thenReturn(x2multiplier);
controller.onNewState(
const GameState.initial()
.copyWith(bonusHistory: [GameBonus.dashNest]),
);
verify(() => x2multiplier.toggle(any())).called(1);
},
);
},
);
*/
});
});
}

@ -56,6 +56,14 @@ void main() {
Assets.images.slingshot.lower.keyName, Assets.images.slingshot.lower.keyName,
Assets.images.dino.dinoLandTop.keyName, Assets.images.dino.dinoLandTop.keyName,
Assets.images.dino.dinoLandBottom.keyName, Assets.images.dino.dinoLandBottom.keyName,
Assets.images.multiball.a.active.keyName,
Assets.images.multiball.a.inactive.keyName,
Assets.images.multiball.b.active.keyName,
Assets.images.multiball.b.inactive.keyName,
Assets.images.multiball.c.active.keyName,
Assets.images.multiball.c.inactive.keyName,
Assets.images.multiball.d.active.keyName,
Assets.images.multiball.d.inactive.keyName,
]; ];
final flameTester = FlameTester(() => PinballTestGame(assets)); final flameTester = FlameTester(() => PinballTestGame(assets));
final debugModeFlameTester = FlameTester(() => DebugPinballTestGame(assets)); final debugModeFlameTester = FlameTester(() => DebugPinballTestGame(assets));

Loading…
Cancel
Save