mirror of https://github.com/flutter/pinball.git
parent
8817038f6a
commit
f587911651
@ -1,2 +1 @@
|
|||||||
export 'ramp_arrow_blinking_behavior.dart';
|
|
||||||
export 'ramp_ball_ascending_contact_behavior.dart';
|
export 'ramp_ball_ascending_contact_behavior.dart';
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
import 'package:flame/components.dart';
|
|
||||||
import 'package:flame_bloc/flame_bloc.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_flame/pinball_flame.dart';
|
|
||||||
|
|
||||||
/// {@template ramp_arrow_blinking_behavior}
|
|
||||||
/// Makes a [SpaceshipRampArrowSpriteComponent] blink between
|
|
||||||
/// [ArrowLightState.values].
|
|
||||||
/// {@endtemplate}
|
|
||||||
class RampArrowBlinkingBehavior extends TimerComponent
|
|
||||||
with ParentIsA<SpaceshipRamp> {
|
|
||||||
/// {@macro ramp_arrow_blinking_behavior}
|
|
||||||
RampArrowBlinkingBehavior() : super(period: 0.05);
|
|
||||||
|
|
||||||
final _maxBlinks = 20;
|
|
||||||
|
|
||||||
int _blinksCounter = 0;
|
|
||||||
|
|
||||||
bool _isAnimating = false;
|
|
||||||
|
|
||||||
void _onNewState(SpaceshipRampState state) {
|
|
||||||
final animationEnabled =
|
|
||||||
state.animationState == ArrowAnimationState.blinking;
|
|
||||||
final canBlink = _blinksCounter < _maxBlinks;
|
|
||||||
|
|
||||||
if (animationEnabled && canBlink) {
|
|
||||||
_start();
|
|
||||||
} else {
|
|
||||||
_stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _start() {
|
|
||||||
if (!_isAnimating) {
|
|
||||||
_isAnimating = true;
|
|
||||||
timer
|
|
||||||
..reset()
|
|
||||||
..start();
|
|
||||||
_animate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _animate() {
|
|
||||||
readBloc<SpaceshipRampCubit, SpaceshipRampState>().onBlink();
|
|
||||||
_blinksCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _stop() {
|
|
||||||
if (_isAnimating) {
|
|
||||||
_isAnimating = false;
|
|
||||||
timer.stop();
|
|
||||||
_blinksCounter = 0;
|
|
||||||
readBloc<SpaceshipRampCubit, SpaceshipRampState>().onStop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
await super.onLoad();
|
|
||||||
await add(
|
|
||||||
FlameBlocListener<SpaceshipRampCubit, SpaceshipRampState>(
|
|
||||||
onNewState: _onNewState,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTick() {
|
|
||||||
super.onTick();
|
|
||||||
if (!_isAnimating) {
|
|
||||||
timer.stop();
|
|
||||||
} else {
|
|
||||||
if (_blinksCounter < _maxBlinks) {
|
|
||||||
_animate();
|
|
||||||
timer
|
|
||||||
..reset()
|
|
||||||
..start();
|
|
||||||
} else {
|
|
||||||
timer.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,219 +0,0 @@
|
|||||||
// ignore_for_file: prefer_const_constructors, cascade_invocations
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:bloc_test/bloc_test.dart';
|
|
||||||
import 'package:flame_bloc/flame_bloc.dart';
|
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
||||||
import 'package:flame_test/flame_test.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:mocktail/mocktail.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_components/src/components/spaceship_ramp/behavior/ramp_arrow_blinking_behavior.dart';
|
|
||||||
import 'package:pinball_flame/pinball_flame.dart';
|
|
||||||
|
|
||||||
class _TestGame extends Forge2DGame {
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
images.prefix = '';
|
|
||||||
await images.loadAll([
|
|
||||||
Assets.images.multiball.lit.keyName,
|
|
||||||
Assets.images.android.ramp.railingForeground.keyName,
|
|
||||||
Assets.images.android.ramp.railingBackground.keyName,
|
|
||||||
Assets.images.android.ramp.main.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.inactive.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.active1.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.active2.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.active3.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.active4.keyName,
|
|
||||||
Assets.images.android.ramp.arrow.active5.keyName,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> pump(
|
|
||||||
SpaceshipRamp child, {
|
|
||||||
required SpaceshipRampCubit spaceshipRampCubit,
|
|
||||||
}) async {
|
|
||||||
await ensureAdd(
|
|
||||||
FlameBlocProvider<SpaceshipRampCubit, SpaceshipRampState>.value(
|
|
||||||
value: spaceshipRampCubit,
|
|
||||||
children: [
|
|
||||||
ZCanvasComponent(children: [child]),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MockSpaceshipRampCubit extends Mock implements SpaceshipRampCubit {}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
final flameTester = FlameTester(_TestGame.new);
|
|
||||||
|
|
||||||
group(
|
|
||||||
'RampArrowBlinkingBehavior',
|
|
||||||
() {
|
|
||||||
flameTester.testGameWidget(
|
|
||||||
'calls onBlink every 0.05 seconds when animation state is animated',
|
|
||||||
setUp: (game, tester) async {
|
|
||||||
final behavior = RampArrowBlinkingBehavior();
|
|
||||||
final bloc = _MockSpaceshipRampCubit();
|
|
||||||
final streamController = StreamController<SpaceshipRampState>();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
streamController.stream,
|
|
||||||
initialState: SpaceshipRampState.initial(),
|
|
||||||
);
|
|
||||||
|
|
||||||
final spaceshipRamp = SpaceshipRamp.test();
|
|
||||||
await game.pump(
|
|
||||||
spaceshipRamp,
|
|
||||||
spaceshipRampCubit: bloc,
|
|
||||||
);
|
|
||||||
await spaceshipRamp.add(behavior);
|
|
||||||
|
|
||||||
streamController.add(
|
|
||||||
SpaceshipRampState(
|
|
||||||
hits: 1,
|
|
||||||
animationState: ArrowAnimationState.blinking,
|
|
||||||
lightState: ArrowLightState.active1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await tester.pump();
|
|
||||||
game.update(0);
|
|
||||||
|
|
||||||
verify(bloc.onBlink).called(1);
|
|
||||||
|
|
||||||
await tester.pump();
|
|
||||||
game.update(0.05);
|
|
||||||
|
|
||||||
await streamController.close();
|
|
||||||
verify(bloc.onBlink).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.testGameWidget(
|
|
||||||
'calls onStop when animation state is stopped',
|
|
||||||
setUp: (game, tester) async {
|
|
||||||
final behavior = RampArrowBlinkingBehavior();
|
|
||||||
final bloc = _MockSpaceshipRampCubit();
|
|
||||||
final streamController = StreamController<SpaceshipRampState>();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
streamController.stream,
|
|
||||||
initialState: SpaceshipRampState.initial(),
|
|
||||||
);
|
|
||||||
when(bloc.onBlink).thenAnswer((_) async {});
|
|
||||||
|
|
||||||
final spaceshipRamp = SpaceshipRamp.test();
|
|
||||||
await game.pump(
|
|
||||||
spaceshipRamp,
|
|
||||||
spaceshipRampCubit: bloc,
|
|
||||||
);
|
|
||||||
await spaceshipRamp.add(behavior);
|
|
||||||
|
|
||||||
streamController.add(
|
|
||||||
SpaceshipRampState(
|
|
||||||
hits: 1,
|
|
||||||
animationState: ArrowAnimationState.blinking,
|
|
||||||
lightState: ArrowLightState.active1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
streamController.add(
|
|
||||||
SpaceshipRampState(
|
|
||||||
hits: 1,
|
|
||||||
animationState: ArrowAnimationState.idle,
|
|
||||||
lightState: ArrowLightState.active1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await streamController.close();
|
|
||||||
|
|
||||||
await game.ready();
|
|
||||||
|
|
||||||
verify(bloc.onStop).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.testGameWidget(
|
|
||||||
'onTick stops when there is no animation',
|
|
||||||
setUp: (game, tester) async {
|
|
||||||
final behavior = RampArrowBlinkingBehavior();
|
|
||||||
final bloc = _MockSpaceshipRampCubit();
|
|
||||||
final streamController = StreamController<SpaceshipRampState>();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
streamController.stream,
|
|
||||||
initialState: SpaceshipRampState.initial(),
|
|
||||||
);
|
|
||||||
when(bloc.onBlink).thenAnswer((_) async {});
|
|
||||||
|
|
||||||
final spaceshipRamp = SpaceshipRamp.test();
|
|
||||||
await game.pump(
|
|
||||||
spaceshipRamp,
|
|
||||||
spaceshipRampCubit: bloc,
|
|
||||||
);
|
|
||||||
await spaceshipRamp.add(behavior);
|
|
||||||
|
|
||||||
streamController.add(
|
|
||||||
SpaceshipRampState(
|
|
||||||
hits: 1,
|
|
||||||
animationState: ArrowAnimationState.idle,
|
|
||||||
lightState: ArrowLightState.active1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
behavior.onTick();
|
|
||||||
|
|
||||||
await game.ready();
|
|
||||||
|
|
||||||
expect(behavior.timer.isRunning(), false);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.testGameWidget(
|
|
||||||
'onTick stops after 10 blinks repetitions',
|
|
||||||
setUp: (game, tester) async {
|
|
||||||
final behavior = RampArrowBlinkingBehavior();
|
|
||||||
final bloc = _MockSpaceshipRampCubit();
|
|
||||||
final streamController = StreamController<SpaceshipRampState>();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
streamController.stream,
|
|
||||||
initialState: SpaceshipRampState.initial(),
|
|
||||||
);
|
|
||||||
when(bloc.onBlink).thenAnswer((_) async {});
|
|
||||||
|
|
||||||
final spaceshipRamp = SpaceshipRamp.test();
|
|
||||||
await game.pump(
|
|
||||||
spaceshipRamp,
|
|
||||||
spaceshipRampCubit: bloc,
|
|
||||||
);
|
|
||||||
await spaceshipRamp.add(behavior);
|
|
||||||
|
|
||||||
streamController.add(
|
|
||||||
SpaceshipRampState(
|
|
||||||
hits: 1,
|
|
||||||
animationState: ArrowAnimationState.blinking,
|
|
||||||
lightState: ArrowLightState.inactive,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
behavior.onTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
await game.ready();
|
|
||||||
|
|
||||||
expect(behavior.timer.isRunning(), false);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in new issue