feat: applied Plunger behaviours depending on platfotm

pull/434/head
alestiago 3 years ago
parent 0d2acbf987
commit 4ef2140e09

@ -5,6 +5,7 @@ import 'package:pinball/select_character/select_character.dart';
import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:platform_helper/platform_helper.dart';
/// Listens to the [GameBloc] and updates the game accordingly. /// Listens to the [GameBloc] and updates the game accordingly.
class GameBlocStatusListener extends Component class GameBlocStatusListener extends Component
@ -53,11 +54,36 @@ class GameBlocStatusListener extends Component
} }
} }
void _addPlungerKeyControls(Plunger plunger) => void _addPlungerKeyControls(Plunger plunger) {
plunger.add(PlungerKeyControllingBehavior()); final platformHelper = readProvider<PlatformHelper>();
const pullingStrength = 7.0;
final provider =
plunger.firstChild<FlameBlocProvider<PlungerCubit, PlungerState>>()!;
void _removePlungerKeyControls(Plunger plunger) => if (platformHelper.isMobile) {
plunger.remove(PlungerKeyControllingBehavior()); provider.add(
PlungerAutoPullingBehavior(strength: pullingStrength),
);
} else {
provider.addAll(
[
PlungerKeyControllingBehavior(),
PlungerPullingBehavior(strength: 7),
],
);
}
}
void _removePlungerKeyControls(Plunger plunger) {
plunger
.descendants()
.whereType<PlungerPullingBehavior>()
.forEach(plunger.remove);
plunger
.descendants()
.whereType<PlungerKeyControllingBehavior>()
.forEach(plunger.remove);
}
void _addFlipperKeyControls(Flipper flipper) => flipper void _addFlipperKeyControls(Flipper flipper) => flipper
..add(FlipperKeyControllingBehavior()) ..add(FlipperKeyControllingBehavior())

@ -6,7 +6,7 @@ import 'package:pinball_components/pinball_components.dart';
/// Allows controlling the [Plunger]'s movement with keyboard input. /// Allows controlling the [Plunger]'s movement with keyboard input.
class PlungerKeyControllingBehavior extends Component class PlungerKeyControllingBehavior extends Component
with KeyboardHandler, FlameBlocReader<PlungerCubit, PlungerState> { with KeyboardHandler, FlameBlocReader<PlungerCubit, PlungerState> {
/// The [LogicalKeyboardKey]s that will control the [Flipper]. /// The [LogicalKeyboardKey]s that will control the [Plunger].
/// ///
/// [onKeyEvent] method listens to when one of these keys is pressed. /// [onKeyEvent] method listens to when one of these keys is pressed.
static const List<LogicalKeyboardKey> _keys = [ static const List<LogicalKeyboardKey> _keys = [

@ -24,8 +24,8 @@ class Plunger extends BodyComponent with InitialPosition, Layered, ZIndex {
create: PlungerCubit.new, create: PlungerCubit.new,
children: [ children: [
_PlungerSpriteAnimationGroupComponent(), _PlungerSpriteAnimationGroupComponent(),
PlungerPullingBehavior(strength: 7),
PlungerReleasingBehavior(strength: 11), PlungerReleasingBehavior(strength: 11),
PlungerNoiseBehavior(),
], ],
), ),
PlungerJointingBehavior(compressionDistance: 9.2), PlungerJointingBehavior(compressionDistance: 9.2),

@ -26,6 +26,44 @@ void main() {
}, },
); );
group('adds', () {
flameTester.test(
'a PlungerReleasingBehavior',
(game) async {
final plunger = Plunger();
await game.ensureAdd(plunger);
expect(
game.descendants().whereType<PlungerReleasingBehavior>().length,
equals(1),
);
},
);
flameTester.test(
'a PlungerJointingBehavior',
(game) async {
final plunger = Plunger();
await game.ensureAdd(plunger);
expect(
game.descendants().whereType<PlungerJointingBehavior>().length,
equals(1),
);
},
);
flameTester.test(
'a PlungerNoiseBehavior',
(game) async {
final plunger = Plunger();
await game.ensureAdd(plunger);
expect(
game.descendants().whereType<PlungerNoiseBehavior>().length,
equals(1),
);
},
);
});
group('renders correctly', () { group('renders correctly', () {
const goldenPath = '../golden/plunger/'; const goldenPath = '../golden/plunger/';
flameTester.testGameWidget( flameTester.testGameWidget(
@ -74,30 +112,5 @@ void main() {
}, },
); );
}); });
// group('body', () {
// test('is dynamic', () {
// final body = Plunger.test().createBody();
// expect(body.bodyType, equals(BodyType.dynamic));
// });
// test('ignores gravity', () {
// final body = Plunger().createBody();
// expect(body.gravityScale, equals(Vector2.zero()));
// });
// });
// group('fixture', () {
// test('exists', () async {
// final body = Plunger().createBody();
// expect(body.fixtures[0], isA<Fixture>());
// });
// test('has density', () {
// final body = Plunger().createBody();
// final fixture = body.fixtures[0];
// expect(fixture.density, greaterThan(0));
// });
// });
}); });
} }

@ -36,6 +36,7 @@ class _TestGame extends Forge2DGame with HasTappables {
Future<void> pump( Future<void> pump(
Iterable<Component> children, { Iterable<Component> children, {
PinballAudioPlayer? pinballAudioPlayer, PinballAudioPlayer? pinballAudioPlayer,
PlatformHelper? platformHelper,
}) async { }) async {
return ensureAdd( return ensureAdd(
FlameMultiBlocProvider( FlameMultiBlocProvider(
@ -57,7 +58,7 @@ class _TestGame extends Forge2DGame with HasTappables {
_MockAppLocalizations(), _MockAppLocalizations(),
), ),
FlameProvider<PlatformHelper>.value( FlameProvider<PlatformHelper>.value(
_MockPlatformHelper(), platformHelper ?? PlatformHelper(),
), ),
], ],
children: children, children: children,
@ -75,10 +76,9 @@ class _MockLeaderboardRepository extends Mock implements LeaderboardRepository {
class _MockShareRepository extends Mock implements ShareRepository {} class _MockShareRepository extends Mock implements ShareRepository {}
class _MockPlatformHelper extends Mock implements PlatformHelper { class _MockPlatformHelper extends Mock implements PlatformHelper {}
@override
bool get isMobile => false; class _MockPlungerCubit extends Mock implements PlungerCubit {}
}
class _MockAppLocalizations extends Mock implements AppLocalizations { class _MockAppLocalizations extends Mock implements AppLocalizations {
@override @override
@ -196,7 +196,6 @@ void main() {
await flipper.ensureAdd(behavior); await flipper.ensureAdd(behavior);
expect(state.status, GameStatus.gameOver); expect(state.status, GameStatus.gameOver);
component.onNewState(state); component.onNewState(state);
await game.ready(); await game.ready();
@ -219,13 +218,18 @@ void main() {
entries: const [], entries: const [],
); );
final plunger = Plunger.test(); final plunger = Plunger.test();
final behavior = PlungerKeyControllingBehavior(); await game.pump(
[component, backbox, plunger],
);
await game.pump([component, backbox, plunger]); await plunger.ensureAdd(
await plunger.ensureAdd(behavior); FlameBlocProvider<PlungerCubit, PlungerState>(
create: PlungerCubit.new,
children: [PlungerKeyControllingBehavior()],
),
);
expect(state.status, GameStatus.gameOver); expect(state.status, GameStatus.gameOver);
component.onNewState(state); component.onNewState(state);
await game.ready(); await game.ready();
@ -236,6 +240,43 @@ void main() {
}, },
); );
flameTester.test(
'removes PlungerPullingBehavior from Plunger',
(game) async {
final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository();
final backbox = Backbox(
leaderboardRepository: leaderboardRepository,
shareRepository: shareRepository,
entries: const [],
);
final plunger = Plunger.test();
await game.pump(
[component, backbox, plunger],
);
await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>(
create: PlungerCubit.new,
children: [
PlungerPullingBehavior(strength: 0),
PlungerAutoPullingBehavior(strength: 0)
],
),
);
expect(state.status, GameStatus.gameOver);
component.onNewState(state);
await game.ready();
expect(
plunger.children.whereType<PlungerPullingBehavior>(),
isEmpty,
);
},
);
flameTester.test( flameTester.test(
'plays the game over voice over', 'plays the game over voice over',
(game) async { (game) async {
@ -292,7 +333,7 @@ void main() {
); );
flameTester.test( flameTester.test(
'adds key controlling behavior to Flippers when the game is started', 'adds FlipperKeyControllingBehavior to Flippers',
(game) async { (game) async {
final component = GameBlocStatusListener(); final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository(); final leaderboardRepository = _MockLeaderboardRepository();
@ -317,6 +358,120 @@ void main() {
); );
}, },
); );
flameTester.test(
'adds PlungerKeyControllingBehavior to Plunger when on desktop',
(game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(false);
final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository();
final backbox = Backbox(
leaderboardRepository: leaderboardRepository,
shareRepository: shareRepository,
entries: const [],
);
final plunger = Plunger.test();
await game.pump(
[component, backbox, plunger],
platformHelper: platformHelper,
);
await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>(
create: _MockPlungerCubit.new,
),
);
expect(state.status, GameStatus.playing);
component.onNewState(state);
await game.ready();
expect(
plunger
.descendants()
.whereType<PlungerKeyControllingBehavior>()
.length,
equals(1),
);
},
);
flameTester.test(
'adds PlungerPullingBehavior to Plunger when on desktop',
(game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(false);
final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository();
final backbox = Backbox(
leaderboardRepository: leaderboardRepository,
shareRepository: shareRepository,
entries: const [],
);
final plunger = Plunger.test();
await game.pump(
[component, backbox, plunger],
platformHelper: platformHelper,
);
await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>(
create: _MockPlungerCubit.new,
),
);
expect(state.status, GameStatus.playing);
component.onNewState(state);
await game.ready();
expect(
plunger.descendants().whereType<PlungerPullingBehavior>().length,
equals(1),
);
},
);
flameTester.test(
'adds PlungerAutoPullingBehavior to Plunger when on mobile',
(game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(true);
final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository();
final backbox = Backbox(
leaderboardRepository: leaderboardRepository,
shareRepository: shareRepository,
entries: const [],
);
final plunger = Plunger.test();
await game.pump(
[component, backbox, plunger],
platformHelper: platformHelper,
);
await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>(
create: _MockPlungerCubit.new,
),
);
expect(state.status, GameStatus.playing);
component.onNewState(state);
await game.ready();
expect(
plunger
.descendants()
.whereType<PlungerAutoPullingBehavior>()
.length,
equals(1),
);
},
);
}); });
}); });
}); });

Loading…
Cancel
Save