chore: score bonus animation (#191)

pull/216/head
arturplaczek 3 years ago committed by GitHub
parent 5889ca8379
commit ec52486ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

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';

@ -10,10 +10,36 @@ import 'package:flutter/widgets.dart';
class $AssetsImagesGen { class $AssetsImagesGen {
const $AssetsImagesGen(); const $AssetsImagesGen();
$AssetsImagesBonusAnimationGen get bonusAnimation =>
const $AssetsImagesBonusAnimationGen();
$AssetsImagesComponentsGen get components => $AssetsImagesComponentsGen get components =>
const $AssetsImagesComponentsGen(); const $AssetsImagesComponentsGen();
} }
class $AssetsImagesBonusAnimationGen {
const $AssetsImagesBonusAnimationGen();
/// File path: assets/images/bonus_animation/android.png
AssetGenImage get android =>
const AssetGenImage('assets/images/bonus_animation/android.png');
/// File path: assets/images/bonus_animation/dash_nest.png
AssetGenImage get dashNest =>
const AssetGenImage('assets/images/bonus_animation/dash_nest.png');
/// File path: assets/images/bonus_animation/dino.png
AssetGenImage get dino =>
const AssetGenImage('assets/images/bonus_animation/dino.png');
/// File path: assets/images/bonus_animation/google.png
AssetGenImage get google =>
const AssetGenImage('assets/images/bonus_animation/google.png');
/// File path: assets/images/bonus_animation/sparky_turbo_charge.png
AssetGenImage get sparkyTurboCharge => const AssetGenImage(
'assets/images/bonus_animation/sparky_turbo_charge.png');
}
class $AssetsImagesComponentsGen { class $AssetsImagesComponentsGen {
const $AssetsImagesComponentsGen(); const $AssetsImagesComponentsGen();

@ -47,6 +47,7 @@ flutter:
assets: assets:
- assets/images/components/ - assets/images/components/
- assets/images/bonus_animation/
flutter_gen: flutter_gen:
line_length: 80 line_length: 80

@ -160,6 +160,10 @@ void main() {
}); });
group('PinballGameView', () { group('PinballGameView', () {
setUp(() async {
await Future.wait<void>(game.preLoadAssets());
});
testWidgets('renders game and a hud', (tester) async { testWidgets('renders game and a hud', (tester) async {
final gameBloc = MockGameBloc(); final gameBloc = MockGameBloc();
whenListen( whenListen(

@ -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…
Cancel
Save