mirror of https://github.com/flutter/pinball.git
chore: score bonus animation (#191)
parent
5889ca8379
commit
ec52486ece
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 422 KiB |
After Width: | Height: | Size: 171 KiB |
After Width: | Height: | Size: 222 KiB |
After Width: | Height: | Size: 298 KiB |
@ -0,0 +1,106 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs
|
||||||
|
|
||||||
|
import 'package:flame/flame.dart';
|
||||||
|
import 'package:flame/sprite.dart';
|
||||||
|
import 'package:flame/widgets.dart';
|
||||||
|
import 'package:flutter/material.dart' hide Image;
|
||||||
|
import 'package:pinball/gen/assets.gen.dart';
|
||||||
|
|
||||||
|
class BonusAnimation extends StatelessWidget {
|
||||||
|
const BonusAnimation._(
|
||||||
|
this.imagePath, {
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
Key? key,
|
||||||
|
}) : _onCompleted = onCompleted,
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
BonusAnimation.dashNest({
|
||||||
|
Key? key,
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
}) : this._(
|
||||||
|
Assets.images.bonusAnimation.dashNest.keyName,
|
||||||
|
onCompleted: onCompleted,
|
||||||
|
key: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
BonusAnimation.sparkyTurboCharge({
|
||||||
|
Key? key,
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
}) : this._(
|
||||||
|
Assets.images.bonusAnimation.sparkyTurboCharge.keyName,
|
||||||
|
onCompleted: onCompleted,
|
||||||
|
key: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
BonusAnimation.dino({
|
||||||
|
Key? key,
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
}) : this._(
|
||||||
|
Assets.images.bonusAnimation.dino.keyName,
|
||||||
|
onCompleted: onCompleted,
|
||||||
|
key: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
BonusAnimation.android({
|
||||||
|
Key? key,
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
}) : this._(
|
||||||
|
Assets.images.bonusAnimation.android.keyName,
|
||||||
|
onCompleted: onCompleted,
|
||||||
|
key: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
BonusAnimation.google({
|
||||||
|
Key? key,
|
||||||
|
VoidCallback? onCompleted,
|
||||||
|
}) : this._(
|
||||||
|
Assets.images.bonusAnimation.google.keyName,
|
||||||
|
onCompleted: onCompleted,
|
||||||
|
key: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
final String imagePath;
|
||||||
|
|
||||||
|
final VoidCallback? _onCompleted;
|
||||||
|
|
||||||
|
static Future<void> loadAssets() {
|
||||||
|
Flame.images.prefix = '';
|
||||||
|
return Flame.images.loadAll([
|
||||||
|
Assets.images.bonusAnimation.dashNest.keyName,
|
||||||
|
Assets.images.bonusAnimation.sparkyTurboCharge.keyName,
|
||||||
|
Assets.images.bonusAnimation.dino.keyName,
|
||||||
|
Assets.images.bonusAnimation.android.keyName,
|
||||||
|
Assets.images.bonusAnimation.google.keyName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final spriteSheet = SpriteSheet.fromColumnsAndRows(
|
||||||
|
image: Flame.images.fromCache(imagePath),
|
||||||
|
columns: 8,
|
||||||
|
rows: 9,
|
||||||
|
);
|
||||||
|
final animation = spriteSheet.createAnimation(
|
||||||
|
row: 0,
|
||||||
|
stepTime: 1 / 24,
|
||||||
|
to: spriteSheet.rows * spriteSheet.columns,
|
||||||
|
loop: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<void>.delayed(
|
||||||
|
Duration(seconds: animation.totalDuration().ceil()),
|
||||||
|
() {
|
||||||
|
_onCompleted?.call();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
child: SpriteAnimationWidget(
|
||||||
|
animation: animation,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
|
export 'bonus_animation.dart';
|
||||||
export 'game_hud.dart';
|
export 'game_hud.dart';
|
||||||
export 'play_button_overlay.dart';
|
export 'play_button_overlay.dart';
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flame/assets.dart';
|
||||||
|
import 'package:flame/widgets.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
import 'package:pinball/game/view/widgets/bonus_animation.dart';
|
||||||
|
|
||||||
|
import '../../../helpers/helpers.dart';
|
||||||
|
|
||||||
|
class MockImages extends Mock implements Images {}
|
||||||
|
|
||||||
|
class MockImage extends Mock implements ui.Image {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
await BonusAnimation.loadAssets();
|
||||||
|
});
|
||||||
|
|
||||||
|
group('loads SpriteAnimationWidget correctly for', () {
|
||||||
|
testWidgets('dashNest', (tester) async {
|
||||||
|
await tester.pumpApp(
|
||||||
|
BonusAnimation.dashNest(),
|
||||||
|
);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byType(SpriteAnimationWidget), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('dino', (tester) async {
|
||||||
|
await tester.pumpApp(
|
||||||
|
BonusAnimation.dino(),
|
||||||
|
);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byType(SpriteAnimationWidget), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('sparkyTurboCharge', (tester) async {
|
||||||
|
await tester.pumpApp(
|
||||||
|
BonusAnimation.sparkyTurboCharge(),
|
||||||
|
);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byType(SpriteAnimationWidget), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('google', (tester) async {
|
||||||
|
await tester.pumpApp(
|
||||||
|
BonusAnimation.google(),
|
||||||
|
);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byType(SpriteAnimationWidget), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('android', (tester) async {
|
||||||
|
await tester.pumpApp(
|
||||||
|
BonusAnimation.android(),
|
||||||
|
);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byType(SpriteAnimationWidget), findsOneWidget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO(arturplaczek): refactor this test when there is a new version of the
|
||||||
|
// flame with an onComplete callback in SpriteAnimationWidget
|
||||||
|
// https://github.com/flame-engine/flame/issues/1543
|
||||||
|
testWidgets('called onCompleted callback at the end of animation ',
|
||||||
|
(tester) async {
|
||||||
|
final completer = Completer<void>();
|
||||||
|
|
||||||
|
await tester.runAsync(() async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: BonusAnimation.dashNest(
|
||||||
|
onCompleted: completer.complete,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
await Future<void>.delayed(const Duration(seconds: 4));
|
||||||
|
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(completer.isCompleted, isTrue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in new issue