diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e4db22a8..f3e3fd99 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -8,3 +8,4 @@ jobs: with: flutter_channel: stable flutter_version: 2.10.0 + coverage_excludes: "lib/gen/*.dart" diff --git a/analysis_options.yaml b/analysis_options.yaml index 44aef9ac..f8155aa6 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1,4 @@ include: package:very_good_analysis/analysis_options.2.4.0.yaml +analyzer: + exclude: + - lib/**/*.gen.dart diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 3dc068c2..def21929 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -1,6 +1,7 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball/gen/assets.gen.dart'; /// {@template ball} /// A solid, [BodyType.dynamic] sphere that rolls and bounces along the @@ -20,15 +21,10 @@ class Ball extends BodyComponent with InitialPosition, Layered { /// The size of the [Ball] final Vector2 size = Vector2.all(2); - /// Asset location of the sprite that renders with the [Ball]. - /// - /// Sprite is preloaded by [PinballGameAssetsX]. - static const spritePath = 'components/ball.png'; - @override Future onLoad() async { await super.onLoad(); - final sprite = await gameRef.loadSprite(spritePath); + final sprite = await gameRef.loadSprite(Assets.images.components.ball.path); final tint = gameRef.theme.characterTheme.ballColor.withOpacity(0.5); await add( SpriteComponent( diff --git a/lib/game/components/flipper.dart b/lib/game/components/flipper.dart index cf3fed4f..92b2ddd4 100644 --- a/lib/game/components/flipper.dart +++ b/lib/game/components/flipper.dart @@ -6,6 +6,7 @@ import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball/gen/assets.gen.dart'; /// {@template flipper} /// A bat, typically found in pairs at the bottom of the board. @@ -52,11 +53,6 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition { } } - /// Asset location of the sprite that renders with the [Flipper]. - /// - /// Sprite is preloaded by [PinballGameAssetsX]. - static const spritePath = 'components/flipper.png'; - /// The size of the [Flipper]. static final size = Vector2(12, 2.8); @@ -90,7 +86,9 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition { /// Loads the sprite that renders with the [Flipper]. Future _loadSprite() async { - final sprite = await gameRef.loadSprite(spritePath); + final sprite = await gameRef.loadSprite( + Assets.images.components.flipper.path, + ); final spriteComponent = SpriteComponent( sprite: sprite, size: size, diff --git a/lib/game/components/spaceship.dart b/lib/game/components/spaceship.dart index d933a79f..51dbc291 100644 --- a/lib/game/components/spaceship.dart +++ b/lib/game/components/spaceship.dart @@ -7,6 +7,7 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/flame/blueprint.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball/gen/assets.gen.dart'; /// A [Blueprint] which creates the spaceship feature. class Spaceship extends Forge2DBlueprint { @@ -46,18 +47,12 @@ class SpaceshipSaucer extends BodyComponent with InitialPosition, Layered { layer = Layer.spaceship; } - /// Path for the base sprite - static const saucerSpritePath = 'components/spaceship/saucer.png'; - - /// Path for the upper wall sprite - static const upperWallPath = 'components/spaceship/upper.png'; - @override Future onLoad() async { await super.onLoad(); final sprites = await Future.wait([ - gameRef.loadSprite(saucerSpritePath), - gameRef.loadSprite(upperWallPath), + gameRef.loadSprite(Assets.images.components.spaceship.saucer.path), + gameRef.loadSprite(Assets.images.components.spaceship.upper.path), ]); await add( @@ -104,14 +99,13 @@ class SpaceshipBridgeTop extends BodyComponent with InitialPosition { /// {@macro spaceship_bridge_top} SpaceshipBridgeTop() : super(priority: 6); - /// Path to the top of this sprite - static const spritePath = 'components/spaceship/android-top.png'; - @override Future onLoad() async { await super.onLoad(); - final sprite = await gameRef.loadSprite(spritePath); + final sprite = await gameRef.loadSprite( + Assets.images.components.spaceship.androidTop.path, + ); await add( SpriteComponent( sprite: sprite, @@ -142,16 +136,15 @@ class SpaceshipBridge extends BodyComponent with InitialPosition, Layered { layer = Layer.spaceship; } - /// Path to the spaceship bridge - static const spritePath = 'components/spaceship/android-bottom.png'; - @override Future onLoad() async { await super.onLoad(); renderBody = false; - final sprite = await gameRef.images.load(spritePath); + final sprite = await gameRef.images.load( + Assets.images.components.spaceship.androidBottom.path, + ); await add( SpriteAnimationComponent.fromFrameData( sprite, @@ -253,14 +246,13 @@ class SpaceshipWall extends BodyComponent with InitialPosition, Layered { layer = Layer.spaceship; } - /// Sprite path for the lower wall - static const lowerWallPath = 'components/spaceship/lower.png'; - @override Future onLoad() async { await super.onLoad(); - final sprite = await gameRef.loadSprite(lowerWallPath); + final sprite = await gameRef.loadSprite( + Assets.images.components.spaceship.lower.path, + ); await add( SpriteComponent( diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 00e9d09c..d19ef177 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -1,16 +1,17 @@ import 'package:pinball/game/game.dart'; +import 'package:pinball/gen/assets.gen.dart'; /// Add methods to help loading and caching game assets. extension PinballGameAssetsX on PinballGame { /// Pre load the initial assets of the game. Future preLoadAssets() async { await Future.wait([ - images.load(Ball.spritePath), - images.load(Flipper.spritePath), - images.load(SpaceshipBridge.spritePath), - images.load(SpaceshipBridgeTop.spritePath), - images.load(SpaceshipWall.lowerWallPath), - images.load(SpaceshipSaucer.upperWallPath), + images.load(Assets.images.components.ball.path), + images.load(Assets.images.components.flipper.path), + images.load(Assets.images.components.spaceship.androidTop.path), + images.load(Assets.images.components.spaceship.androidBottom.path), + images.load(Assets.images.components.spaceship.lower.path), + images.load(Assets.images.components.spaceship.upper.path), ]); } } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index e77a1f73..d1abb70e 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -11,7 +11,9 @@ import 'package:pinball_theme/pinball_theme.dart'; class PinballGame extends Forge2DGame with FlameBloc, HasKeyboardHandlerComponents { - PinballGame({required this.theme}); + PinballGame({required this.theme}) { + images.prefix = ''; + } final PinballTheme theme; diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart new file mode 100644 index 00000000..fe4bad8b --- /dev/null +++ b/lib/gen/assets.gen.dart @@ -0,0 +1,96 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +import 'package:flutter/widgets.dart'; + +class $AssetsImagesGen { + const $AssetsImagesGen(); + + $AssetsImagesComponentsGen get components => + const $AssetsImagesComponentsGen(); +} + +class $AssetsImagesComponentsGen { + const $AssetsImagesComponentsGen(); + + AssetGenImage get ball => + const AssetGenImage('assets/images/components/ball.png'); + AssetGenImage get flipper => + const AssetGenImage('assets/images/components/flipper.png'); + AssetGenImage get sauce => + const AssetGenImage('assets/images/components/sauce.png'); + $AssetsImagesComponentsSpaceshipGen get spaceship => + const $AssetsImagesComponentsSpaceshipGen(); +} + +class $AssetsImagesComponentsSpaceshipGen { + const $AssetsImagesComponentsSpaceshipGen(); + + AssetGenImage get androidBottom => const AssetGenImage( + 'assets/images/components/spaceship/android-bottom.png'); + AssetGenImage get androidTop => + const AssetGenImage('assets/images/components/spaceship/android-top.png'); + AssetGenImage get lower => + const AssetGenImage('assets/images/components/spaceship/lower.png'); + AssetGenImage get saucer => + const AssetGenImage('assets/images/components/spaceship/saucer.png'); + AssetGenImage get upper => + const AssetGenImage('assets/images/components/spaceship/upper.png'); +} + +class Assets { + Assets._(); + + static const $AssetsImagesGen images = $AssetsImagesGen(); +} + +class AssetGenImage extends AssetImage { + const AssetGenImage(String assetName) : super(assetName); + + Image image({ + Key? key, + ImageFrameBuilder? frameBuilder, + ImageLoadingBuilder? loadingBuilder, + ImageErrorWidgetBuilder? errorBuilder, + String? semanticLabel, + bool excludeFromSemantics = false, + double? width, + double? height, + Color? color, + BlendMode? colorBlendMode, + BoxFit? fit, + AlignmentGeometry alignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect? centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + bool isAntiAlias = false, + FilterQuality filterQuality = FilterQuality.low, + }) { + return Image( + key: key, + image: this, + frameBuilder: frameBuilder, + loadingBuilder: loadingBuilder, + errorBuilder: errorBuilder, + semanticLabel: semanticLabel, + excludeFromSemantics: excludeFromSemantics, + width: width, + height: height, + color: color, + colorBlendMode: colorBlendMode, + fit: fit, + alignment: alignment, + repeat: repeat, + centerSlice: centerSlice, + matchTextDirection: matchTextDirection, + gaplessPlayback: gaplessPlayback, + isAntiAlias: isAntiAlias, + filterQuality: filterQuality, + ); + } + + String get path => assetName; +} diff --git a/pubspec.yaml b/pubspec.yaml index 25c8fbb9..838dd9ed 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,3 +42,6 @@ flutter: assets: - assets/images/components/ - assets/images/components/spaceship/ + +flutter_gen: + line_length: 80 diff --git a/test/game/components/board_test.dart b/test/game/components/board_test.dart index 04847dec..7791d891 100644 --- a/test/game/components/board_test.dart +++ b/test/game/components/board_test.dart @@ -1,6 +1,5 @@ // ignore_for_file: cascade_invocations -import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball/game/game.dart'; @@ -9,7 +8,7 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(Forge2DGame.new); + final flameTester = FlameTester(PinballGameTest.create); group('Board', () { flameTester.test( diff --git a/test/helpers/extensions.dart b/test/helpers/extensions.dart index a5c56a86..abea191d 100644 --- a/test/helpers/extensions.dart +++ b/test/helpers/extensions.dart @@ -9,7 +9,7 @@ extension PinballGameTest on PinballGame { theme: const PinballTheme( characterTheme: DashTheme(), ), - ); + )..images.prefix = ''; } /// [DebugPinballGame] extension to reduce boilerplate in tests.