fix: enable auto-pulling for all devices (#455)

pull/457/head
Alejandro Santiago 2 years ago committed by GitHub
parent e90de8dedd
commit 5007705e82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,7 +5,6 @@ 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
@ -68,31 +67,25 @@ class GameBlocStatusListener extends Component
gameRef.descendants().whereType<Signpost>().single.bloc.onReset(); gameRef.descendants().whereType<Signpost>().single.bloc.onReset();
} }
void _addPlungerBehaviors(Plunger plunger) { void _addPlungerBehaviors(Plunger plunger) => plunger
final platformHelper = readProvider<PlatformHelper>(); .firstChild<FlameBlocProvider<PlungerCubit, PlungerState>>()!
const pullingStrength = 7.0; .addAll(
final provider =
plunger.firstChild<FlameBlocProvider<PlungerCubit, PlungerState>>()!;
if (platformHelper.isMobile) {
provider.add(
PlungerAutoPullingBehavior(strength: pullingStrength),
);
} else {
provider.addAll(
[ [
PlungerKeyControllingBehavior(), PlungerPullingBehavior(strength: 7),
PlungerPullingBehavior(strength: pullingStrength), PlungerAutoPullingBehavior(),
PlungerKeyControllingBehavior()
], ],
); );
}
}
void _removePlungerBehaviors(Plunger plunger) { void _removePlungerBehaviors(Plunger plunger) {
plunger plunger
.descendants() .descendants()
.whereType<PlungerPullingBehavior>() .whereType<PlungerPullingBehavior>()
.forEach(plunger.remove); .forEach(plunger.remove);
plunger
.descendants()
.whereType<PlungerAutoPullingBehavior>()
.forEach(plunger.remove);
plunger plunger
.descendants() .descendants()
.whereType<PlungerKeyControllingBehavior>() .whereType<PlungerKeyControllingBehavior>()

@ -167,7 +167,7 @@ class PinballGame extends PinballForge2DGame
.whereType<FlameBlocProvider<PlungerCubit, PlungerState>>() .whereType<FlameBlocProvider<PlungerCubit, PlungerState>>()
.first .first
.bloc .bloc
.pulled(); .autoPulled();
} else { } else {
final tappedLeftSide = info.eventPosition.widget.x < canvasSize.x / 2; final tappedLeftSide = info.eventPosition.widget.x < canvasSize.x / 2;
focusedBoardSide[pointerId] = focusedBoardSide[pointerId] =

@ -28,14 +28,19 @@ class PlungerPullingBehavior extends Component
} }
} }
class PlungerAutoPullingBehavior extends PlungerPullingBehavior { class PlungerAutoPullingBehavior extends Component
PlungerAutoPullingBehavior({ with FlameBlocReader<PlungerCubit, PlungerState> {
required double strength, late final Plunger _plunger;
}) : super(strength: strength);
@override
Future<void> onLoad() async {
await super.onLoad();
_plunger = parent!.parent! as Plunger;
}
@override @override
void update(double dt) { void update(double dt) {
super.update(dt); if (!bloc.state.isAutoPulling) return;
final joint = _plunger.body.joints.whereType<PrismaticJoint>().single; final joint = _plunger.body.joints.whereType<PrismaticJoint>().single;
final reachedBottom = joint.getJointTranslation() <= joint.getLowerLimit(); final reachedBottom = joint.getJointTranslation() <= joint.getLowerLimit();

@ -8,4 +8,6 @@ class PlungerCubit extends Cubit<PlungerState> {
void pulled() => emit(PlungerState.pulling); void pulled() => emit(PlungerState.pulling);
void released() => emit(PlungerState.releasing); void released() => emit(PlungerState.releasing);
void autoPulled() => emit(PlungerState.autoPulling);
} }

@ -4,9 +4,13 @@ enum PlungerState {
pulling, pulling,
releasing, releasing,
autoPulling,
} }
extension PlungerStateX on PlungerState { extension PlungerStateX on PlungerState {
bool get isPulling => this == PlungerState.pulling; bool get isPulling =>
this == PlungerState.pulling || this == PlungerState.autoPulling;
bool get isReleasing => this == PlungerState.releasing; bool get isReleasing => this == PlungerState.releasing;
bool get isAutoPulling => this == PlungerState.autoPulling;
} }

@ -132,6 +132,7 @@ class _PlungerSpriteAnimationGroupComponent
animations = { animations = {
PlungerState.releasing: pullAnimation.reversed(), PlungerState.releasing: pullAnimation.reversed(),
PlungerState.pulling: pullAnimation, PlungerState.pulling: pullAnimation,
PlungerState.autoPulling: pullAnimation,
}; };
current = readBloc<PlungerCubit, PlungerState>().state; current = readBloc<PlungerCubit, PlungerState>().state;

@ -3,6 +3,7 @@
import 'dart:async'; import 'dart:async';
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
@ -12,7 +13,7 @@ import 'package:pinball_components/pinball_components.dart';
class _TestGame extends Forge2DGame { class _TestGame extends Forge2DGame {
Future<void> pump( Future<void> pump(
PlungerPullingBehavior behavior, { Component behavior, {
PlungerCubit? plungerBloc, PlungerCubit? plungerBloc,
}) async { }) async {
final plunger = Plunger.test(); final plunger = Plunger.test();
@ -85,62 +86,28 @@ void main() {
group('PlungerAutoPullingBehavior', () { group('PlungerAutoPullingBehavior', () {
test('can be instantiated', () { test('can be instantiated', () {
expect( expect(
PlungerAutoPullingBehavior(strength: 0), PlungerAutoPullingBehavior(),
isA<PlungerAutoPullingBehavior>(), isA<PlungerAutoPullingBehavior>(),
); );
}); });
flameTester.test('can be loaded', (game) async { flameTester.test('can be loaded', (game) async {
final behavior = PlungerAutoPullingBehavior(strength: 0); final behavior = PlungerAutoPullingBehavior();
await game.pump(behavior); await game.pump(behavior);
expect(game.descendants(), contains(behavior)); expect(game.descendants(), contains(behavior));
}); });
flameTester.test(
"pulls while joint hasn't reached limit",
(game) async {
final plungerBloc = _MockPlungerCubit();
whenListen<PlungerState>(
plungerBloc,
Stream.value(PlungerState.pulling),
initialState: PlungerState.pulling,
);
const strength = 2.0;
final behavior = PlungerAutoPullingBehavior(
strength: strength,
);
await game.pump(
behavior,
plungerBloc: plungerBloc,
);
final plunger = behavior.ancestors().whereType<Plunger>().single;
final joint = _MockPrismaticJoint();
when(joint.getJointTranslation).thenReturn(2);
when(joint.getLowerLimit).thenReturn(0);
plunger.body.joints.add(joint);
game.update(0);
expect(plunger.body.linearVelocity.x, equals(0));
expect(plunger.body.linearVelocity.y, equals(strength));
},
);
flameTester.test( flameTester.test(
'releases when joint reaches limit', 'releases when joint reaches limit',
(game) async { (game) async {
final plungerBloc = _MockPlungerCubit(); final plungerBloc = _MockPlungerCubit();
whenListen<PlungerState>( whenListen<PlungerState>(
plungerBloc, plungerBloc,
Stream.value(PlungerState.pulling), Stream.value(PlungerState.autoPulling),
initialState: PlungerState.pulling, initialState: PlungerState.autoPulling,
); );
const strength = 2.0; final behavior = PlungerAutoPullingBehavior();
final behavior = PlungerAutoPullingBehavior(
strength: strength,
);
await game.pump( await game.pump(
behavior, behavior,
plungerBloc: plungerBloc, plungerBloc: plungerBloc,

@ -0,0 +1,25 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart';
void main() {
group('PlungerCubit', () {
test('can be instantiated', () {
expect(PlungerCubit(), isA<PlungerCubit>());
});
blocTest<PlungerCubit, PlungerState>(
'overrides previous pulling state',
build: PlungerCubit.new,
act: (cubit) => cubit
..pulled()
..autoPulled()
..pulled(),
expect: () => [
PlungerState.pulling,
PlungerState.autoPulling,
PlungerState.pulling,
],
);
});
}

@ -36,7 +36,6 @@ class _TestGame extends Forge2DGame with HasTappables {
Future<void> pump( Future<void> pump(
Iterable<Component> children, { Iterable<Component> children, {
PinballAudioPlayer? pinballAudioPlayer, PinballAudioPlayer? pinballAudioPlayer,
PlatformHelper? platformHelper,
GoogleWordCubit? googleWordBloc, GoogleWordCubit? googleWordBloc,
}) async { }) async {
return ensureAdd( return ensureAdd(
@ -62,7 +61,7 @@ class _TestGame extends Forge2DGame with HasTappables {
_MockAppLocalizations(), _MockAppLocalizations(),
), ),
FlameProvider<PlatformHelper>.value( FlameProvider<PlatformHelper>.value(
platformHelper ?? PlatformHelper(), PlatformHelper(),
), ),
], ],
children: children, children: children,
@ -80,8 +79,6 @@ 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 _MockPlungerCubit extends Mock implements PlungerCubit {} class _MockPlungerCubit extends Mock implements PlungerCubit {}
class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {} class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {}
@ -278,7 +275,7 @@ void main() {
create: PlungerCubit.new, create: PlungerCubit.new,
children: [ children: [
PlungerPullingBehavior(strength: 0), PlungerPullingBehavior(strength: 0),
PlungerAutoPullingBehavior(strength: 0) PlungerAutoPullingBehavior()
], ],
), ),
); );
@ -460,10 +457,8 @@ void main() {
); );
flameTester.test( flameTester.test(
'adds PlungerKeyControllingBehavior to Plunger when on desktop', 'adds PlungerKeyControllingBehavior to Plunger',
(game) async { (game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(false);
final component = GameBlocStatusListener(); final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository(); final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository(); final shareRepository = _MockShareRepository();
@ -482,7 +477,6 @@ void main() {
bloc: _MockSignpostCubit(), bloc: _MockSignpostCubit(),
), ),
], ],
platformHelper: platformHelper,
); );
await plunger.ensureAdd( await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>( FlameBlocProvider<PlungerCubit, PlungerState>(
@ -506,10 +500,8 @@ void main() {
); );
flameTester.test( flameTester.test(
'adds PlungerPullingBehavior to Plunger when on desktop', 'adds PlungerPullingBehavior to Plunger',
(game) async { (game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(false);
final component = GameBlocStatusListener(); final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository(); final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository(); final shareRepository = _MockShareRepository();
@ -528,7 +520,6 @@ void main() {
bloc: _MockSignpostCubit(), bloc: _MockSignpostCubit(),
), ),
], ],
platformHelper: platformHelper,
); );
await plunger.ensureAdd( await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>( FlameBlocProvider<PlungerCubit, PlungerState>(
@ -549,10 +540,8 @@ void main() {
); );
flameTester.test( flameTester.test(
'adds PlungerAutoPullingBehavior to Plunger when on mobile', 'adds PlungerAutoPullingBehavior to Plunger',
(game) async { (game) async {
final platformHelper = _MockPlatformHelper();
when(() => platformHelper.isMobile).thenReturn(true);
final component = GameBlocStatusListener(); final component = GameBlocStatusListener();
final leaderboardRepository = _MockLeaderboardRepository(); final leaderboardRepository = _MockLeaderboardRepository();
final shareRepository = _MockShareRepository(); final shareRepository = _MockShareRepository();
@ -571,7 +560,6 @@ void main() {
bloc: _MockSignpostCubit(), bloc: _MockSignpostCubit(),
), ),
], ],
platformHelper: platformHelper,
); );
await plunger.ensureAdd( await plunger.ensureAdd(
FlameBlocProvider<PlungerCubit, PlungerState>( FlameBlocProvider<PlungerCubit, PlungerState>(

@ -434,7 +434,7 @@ void main() {
.single .single
.bloc; .bloc;
expect(plungerBloc.state, PlungerState.pulling); expect(plungerBloc.state, PlungerState.autoPulling);
}); });
}); });
}); });

Loading…
Cancel
Save