mirror of https://github.com/flutter/pinball.git
parent
ff668c0371
commit
2efa110718
@ -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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in new issue