feat: finishing score text effects

pull/170/head
Erick Zanardo 4 years ago
parent 15baf2ac24
commit a61df839e1

@ -1,18 +1,18 @@
import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/material.dart';
import 'package:pinball/flame/flame.dart'; import 'package:pinball/flame/flame.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
/// /// {@template score_effect_controller}
/// A [ComponentController] responsible for adding [ScoreTextEffect]s
/// on the game screen when the user has earned more points.
/// {@endtemplate}
class ScoreEffectController extends ComponentController<PinballGame> class ScoreEffectController extends ComponentController<PinballGame>
with BlocComponent<GameBloc, GameState> { with BlocComponent<GameBloc, GameState> {
/// /// {@macro score_effect_controller}
ScoreEffectController(PinballGame component) : super(component); ScoreEffectController(PinballGame component) : super(component);
int _lastScore = 0; int _lastScore = 0;
@ -32,11 +32,11 @@ class ScoreEffectController extends ComponentController<PinballGame>
final newScore = state.score - _lastScore; final newScore = state.score - _lastScore;
component.add( component.add(
_Text( ScoreTextEffect(
text: newScore.toString(), text: newScore.toString(),
position: Vector2( position: Vector2(
_noise(), _noise(),
_noise() + (-BoardDimensions.bounds.topCenter.dy + 10), _noise() + (-BoardDimensions.bounds.topCenter.dy + 10),
), ),
), ),
); );
@ -44,41 +44,3 @@ class ScoreEffectController extends ComponentController<PinballGame>
_lastScore = state.score; _lastScore = state.score;
} }
} }
class _Text extends TextComponent {
_Text({
required String text,
required Vector2 position,
}) : super(
text: text,
position: position,
anchor: Anchor.center,
priority: 100,
);
late final Effect _effect;
@override
Future<void> onLoad() async {
textRenderer = TextPaint(
style: const TextStyle(color: Colors.pink, fontSize: 4),
);
unawaited(
add(
_effect = MoveEffect.by(
Vector2(0, -5),
EffectController(duration: 1),
),
),
);
}
@override
void update(double dt) {
super.update(dt);
if (_effect.controller.completed) {
removeFromParent();
}
}
}

@ -3,8 +3,6 @@
/// FlutterGen /// FlutterGen
/// ***************************************************** /// *****************************************************
// ignore_for_file: directives_ordering,unnecessary_import
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
class $AssetsImagesGen { class $AssetsImagesGen {
@ -17,11 +15,8 @@ class $AssetsImagesGen {
class $AssetsImagesComponentsGen { class $AssetsImagesComponentsGen {
const $AssetsImagesComponentsGen(); const $AssetsImagesComponentsGen();
/// File path: assets/images/components/background.png
AssetGenImage get background => AssetGenImage get background =>
const AssetGenImage('assets/images/components/background.png'); const AssetGenImage('assets/images/components/background.png');
/// File path: assets/images/components/plunger.png
AssetGenImage get plunger => AssetGenImage get plunger =>
const AssetGenImage('assets/images/components/plunger.png'); const AssetGenImage('assets/images/components/plunger.png');
} }

@ -11,7 +11,6 @@ import 'package:pinball_components/gen/fonts.gen.dart';
/// once its animation is completed /// once its animation is completed
/// {@endtemplate} /// {@endtemplate}
class ScoreTextEffect extends TextComponent { class ScoreTextEffect extends TextComponent {
/// {@macro score_text_effect} /// {@macro score_text_effect}
ScoreTextEffect({ ScoreTextEffect({
required String text, required String text,
@ -24,6 +23,7 @@ class ScoreTextEffect extends TextComponent {
priority: 100, priority: 100,
); );
late final Effect _effect; late final Effect _effect;
/// The [text] [Color] /// The [text] [Color]
final Color color; final Color color;
@ -31,9 +31,9 @@ class ScoreTextEffect extends TextComponent {
Future<void> onLoad() async { Future<void> onLoad() async {
textRenderer = TextPaint( textRenderer = TextPaint(
style: TextStyle( style: TextStyle(
fontFamily: 'packages/pinball_components/${FontFamily.pixeloidMono}', fontFamily: 'packages/pinball_components/${FontFamily.pixeloidMono}',
color: color, color: color,
fontSize: 4, fontSize: 4,
), ),
); );

@ -26,8 +26,8 @@ void main() {
}, },
verify: (game, tester) async { verify: (game, tester) async {
await expectLater( await expectLater(
find.byGame<TestGame>(), find.byGame<TestGame>(),
matchesGoldenFile('golden/score_text_effect/render.png'), matchesGoldenFile('golden/score_text_effect/render.png'),
); );
}, },
); );
@ -49,8 +49,8 @@ void main() {
}, },
verify: (game, tester) async { verify: (game, tester) async {
await expectLater( await expectLater(
find.byGame<TestGame>(), find.byGame<TestGame>(),
matchesGoldenFile('golden/score_text_effect/movement.png'), matchesGoldenFile('golden/score_text_effect/movement.png'),
); );
}, },
); );

@ -0,0 +1,115 @@
// ignore_for_file: cascade_invocations
import 'package:flame/components.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() {
group('ScoreEffectController', () {
late ScoreEffectController controller;
late PinballGame game;
setUpAll(() {
registerFallbackValue(Component());
});
setUp(() {
game = MockPinballGame();
when(() => game.add(any())).thenAnswer((_) async {});
controller = ScoreEffectController(game);
});
group('listenWhen', () {
test('returns true when the user has earned points', () {
const previous = GameState.initial();
const current = GameState(
score: 10,
balls: 3,
activatedBonusLetters: [],
bonusHistory: [],
activatedDashNests: {},
);
expect(controller.listenWhen(previous, current), isTrue);
});
test(
'returns true when the user has earned points and there was no '
'previous state',
() {
const current = GameState(
score: 10,
balls: 3,
activatedBonusLetters: [],
bonusHistory: [],
activatedDashNests: {},
);
expect(controller.listenWhen(null, current), isTrue);
},
);
test(
'returns false when no points were earned',
() {
const current = GameState.initial();
const previous = GameState.initial();
expect(controller.listenWhen(previous, current), isFalse);
},
);
});
group('onNewState', () {
test(
'adds a ScoreTextEffect with the correct score for the '
'first time',
() {
const state = GameState(
score: 10,
balls: 3,
activatedBonusLetters: [],
bonusHistory: [],
activatedDashNests: {},
);
controller.onNewState(state);
final effect = verify(() => game.add(captureAny())).captured.first
as ScoreTextEffect;
expect(effect.text, equals('10'));
},
);
test('adds a ScoreTextEffect with the correct score', () {
controller.onNewState(
const GameState(
score: 10,
balls: 3,
activatedBonusLetters: [],
bonusHistory: [],
activatedDashNests: {},
),
);
controller.onNewState(
const GameState(
score: 14,
balls: 3,
activatedBonusLetters: [],
bonusHistory: [],
activatedDashNests: {},
),
);
final effect = verify(() => game.add(captureAny())).captured.last
as ScoreTextEffect;
expect(effect.text, equals('4'));
});
});
});
}
Loading…
Cancel
Save