From c51ec65bf1728ffef8beb2efd4475b4fdc83bff5 Mon Sep 17 00:00:00 2001 From: arturplaczek Date: Thu, 28 Apr 2022 17:34:01 +0200 Subject: [PATCH] create: SelectedCharacter --- .../widgets/selected_character.dart | 98 +++++++++++++++++++ .../widgets/selected_character_test.dart | 46 +++++++++ 2 files changed, 144 insertions(+) create mode 100644 lib/select_character/widgets/selected_character.dart create mode 100644 test/select_character/widgets/selected_character_test.dart diff --git a/lib/select_character/widgets/selected_character.dart b/lib/select_character/widgets/selected_character.dart new file mode 100644 index 00000000..3b0fa9f2 --- /dev/null +++ b/lib/select_character/widgets/selected_character.dart @@ -0,0 +1,98 @@ +// ignore_for_file: public_member_api_docs + +import 'package:flame/flame.dart'; +import 'package:flame/sprite.dart'; +import 'package:flutter/material.dart' hide Image; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:pinball/select_character/select_character.dart'; +import 'package:pinball/theme/theme.dart'; +import 'package:pinball_flame/pinball_flame.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +class SelectedCharacter extends StatefulWidget { + const SelectedCharacter({ + Key? key, + }) : super(key: key); + + @override + State createState() => _SelectedCharacterState(); + + static List loadAssets() { + Flame.images.prefix = ''; + + const dashTheme = DashTheme(); + const androidTheme = AndroidTheme(); + const dinoTheme = DinoTheme(); + const sparkyTheme = SparkyTheme(); + + return [ + Flame.images.load(dashTheme.animation.keyName), + Flame.images.load(androidTheme.animation.keyName), + Flame.images.load(dinoTheme.animation.keyName), + Flame.images.load(sparkyTheme.animation.keyName), + Flame.images.load(dashTheme.background.keyName), + Flame.images.load(androidTheme.background.keyName), + Flame.images.load(dinoTheme.background.keyName), + Flame.images.load(sparkyTheme.background.keyName), + ]; + } +} + +class _SelectedCharacterState extends State + with TickerProviderStateMixin { + late SpriteAnimationController _controller; + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final currentCharacter = + context.select( + (cubit) => cubit.state.characterTheme, + ); + final spriteSheet = SpriteSheet.fromColumnsAndRows( + image: Flame.images.fromCache(currentCharacter.animation.keyName), + columns: 12, + rows: 6, + ); + final animation = spriteSheet.createAnimation( + row: 0, + stepTime: 1 / 24, + to: spriteSheet.rows * spriteSheet.columns, + ); + + _controller = SpriteAnimationController( + vsync: this, + animation: animation, + ); + + _controller + ..forward() + ..repeat(); + + return LayoutBuilder( + builder: (context, constraints) { + return ListView( + children: [ + Text( + currentCharacter.name, + style: AppTextStyle.headline3, + ), + const SizedBox(height: 20), + SizedBox( + width: constraints.maxWidth, + height: constraints.maxWidth, + child: SpriteAnimationWidget( + controller: _controller, + ), + ), + ], + ); + }, + ); + } +} diff --git a/test/select_character/widgets/selected_character_test.dart b/test/select_character/widgets/selected_character_test.dart new file mode 100644 index 00000000..8e379ebd --- /dev/null +++ b/test/select_character/widgets/selected_character_test.dart @@ -0,0 +1,46 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:bloc_test/bloc_test.dart'; +import 'package:flame/flame.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/select_character/select_character.dart'; +import 'package:pinball_flame/pinball_flame.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + late CharacterThemeCubit characterThemeCubit; + + setUpAll(() async { + Flame.images.prefix = ''; + await Flame.images.load(const DashTheme().animation.keyName); + }); + + setUp(() async { + characterThemeCubit = MockCharacterThemeCubit(); + + whenListen( + characterThemeCubit, + Stream.value(const CharacterThemeState.initial()), + initialState: const CharacterThemeState.initial(), + ); + }); + + group('SelectedCharacter', () { + testWidgets('loadAssets returns list of futures', (tester) async { + expect(SelectedCharacter.loadAssets(), isList); + }); + + testWidgets('renders selected character', (tester) async { + await tester.pumpApp( + SelectedCharacter(), + characterThemeCubit: characterThemeCubit, + ); + await tester.pump(); + + expect(find.byType(SpriteAnimationWidget), findsOneWidget); + }); + }); +}