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/board.dart b/lib/game/components/board.dart index 8f04a820..efa3f137 100644 --- a/lib/game/components/board.dart +++ b/lib/game/components/board.dart @@ -7,25 +7,23 @@ import 'package:pinball/game/game.dart'; /// {entemplate} class Board extends Component { /// {@macro board} - Board({required Vector2 size}) : _size = size; - - final Vector2 _size; + Board(); @override Future onLoad() async { // TODO(alestiago): adjust positioning once sprites are added. final bottomGroup = _BottomGroup( position: Vector2( - _size.x / 2, - _size.y / 1.25, + PinballGame.boardBounds.center.dx, + PinballGame.boardBounds.bottom + 10, ), spacing: 2, ); final dashForest = _FlutterForest( position: Vector2( - _size.x / 1.25, - _size.y / 4.25, + PinballGame.boardBounds.center.dx + 20, + PinballGame.boardBounds.center.dy + 48, ), ); diff --git a/lib/game/components/bonus_word.dart b/lib/game/components/bonus_word.dart index 03f64a11..cc6391e8 100644 --- a/lib/game/components/bonus_word.dart +++ b/lib/game/components/bonus_word.dart @@ -36,31 +36,39 @@ class BonusWord extends Component with BlocComponent { for (var i = 0; i < letters.length; i++) { final letter = letters[i]; - letter.add( - SequenceEffect( - [ - ColorEffect( - i.isOdd ? BonusLetter._activeColor : BonusLetter._disableColor, - const Offset(0, 1), - EffectController(duration: 0.25), - ), - ColorEffect( - i.isOdd ? BonusLetter._disableColor : BonusLetter._activeColor, - const Offset(0, 1), - EffectController(duration: 0.25), - ), - ], - repeatCount: 4, - )..onFinishCallback = () { - letter.add( + letter + ..isEnabled = false + ..add( + SequenceEffect( + [ ColorEffect( - BonusLetter._disableColor, + i.isOdd + ? BonusLetter._activeColor + : BonusLetter._disableColor, const Offset(0, 1), EffectController(duration: 0.25), ), - ); - }, - ); + ColorEffect( + i.isOdd + ? BonusLetter._disableColor + : BonusLetter._activeColor, + const Offset(0, 1), + EffectController(duration: 0.25), + ), + ], + repeatCount: 4, + )..onFinishCallback = () { + letter + ..isEnabled = true + ..add( + ColorEffect( + BonusLetter._disableColor, + const Offset(0, 1), + EffectController(duration: 0.25), + ), + ); + }, + ); } } } @@ -107,6 +115,13 @@ class BonusLetter extends BodyComponent final String _letter; final int _index; + /// Indicates if a [BonusLetter] can be activated on [Ball] contact. + /// + /// It is disabled whilst animating and enabled again once the animation + /// completes. The animation is triggered when [GameBonus.word] is + /// awarded. + bool isEnabled = true; + @override Future onLoad() async { await super.onLoad(); @@ -172,6 +187,8 @@ class BonusLetterBallContactCallback extends ContactCallback { @override void begin(Ball ball, BonusLetter bonusLetter, Contact contact) { - bonusLetter.activate(); + if (bonusLetter.isEnabled) { + bonusLetter.activate(); + } } } diff --git a/lib/game/components/flipper.dart b/lib/game/components/flipper.dart index 3dbe71d1..344c94b6 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'; const _leftFlipperKeys = [ LogicalKeyboardKey.arrowLeft, @@ -31,11 +32,6 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition { paint = Paint()..color = Colors.transparent; } - /// 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); @@ -69,7 +65,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/jetpack_ramp.dart b/lib/game/components/jetpack_ramp.dart index 985c8f7d..4afc36d1 100644 --- a/lib/game/components/jetpack_ramp.dart +++ b/lib/game/components/jetpack_ramp.dart @@ -30,18 +30,23 @@ class JetpackRamp extends Component with HasGameRef { // TODO(ruialonso): Use a bezier curve once control points are defined. color: const Color.fromARGB(255, 8, 218, 241), center: position, - width: 62, - radius: 200, + width: 5, + radius: 18, angle: math.pi, + rotation: math.pi, + )..layer = layer; + + final leftOpening = _JetpackRampOpening( + outsideLayer: Layer.spaceship, + rotation: math.pi, ) - ..initialPosition = position - ..layer = layer; - final leftOpening = _JetpackRampOpening(outsideLayer: Layer.spaceship) - ..initialPosition = position + Vector2(-27.6, 25.3) + ..initialPosition = position + Vector2(-2.5, -20.2) ..layer = Layer.jetpack; - final rightOpening = _JetpackRampOpening() - ..initialPosition = position + Vector2(-10.6, 25.3) + final rightOpening = _JetpackRampOpening( + rotation: math.pi, + ) + ..initialPosition = position + Vector2(12.9, -20.2) ..layer = Layer.opening; await addAll([ @@ -60,20 +65,26 @@ class _JetpackRampOpening extends RampOpening { /// {@macro jetpack_ramp_opening} _JetpackRampOpening({ Layer? outsideLayer, - }) : super( + required double rotation, + }) : _rotation = rotation, + super( pathwayLayer: Layer.jetpack, outsideLayer: outsideLayer, orientation: RampOrientation.down, ); - // TODO(ruialonso): Avoid magic number 2, should be proportional to + final double _rotation; + + // TODO(ruialonso): Avoid magic number 3, should be propotional to // [JetpackRamp]. - static const _size = 2; + static final Vector2 _size = Vector2(3, .1); @override Shape get shape => PolygonShape() - ..setAsEdge( - Vector2(initialPosition.x - _size, initialPosition.y), - Vector2(initialPosition.x + _size, initialPosition.y), + ..setAsBox( + _size.x, + _size.y, + initialPosition, + _rotation, ); } diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index 21d4d666..0b6e4dbf 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -26,28 +26,33 @@ class LauncherRamp extends Component with HasGameRef { RampOpeningBallContactCallback<_LauncherRampOpening>(), ); + final launcherRampRotation = + -math.atan(18.6 / PinballGame.boardBounds.height); + final straightPath = Pathway.straight( color: const Color.fromARGB(255, 34, 255, 0), - start: Vector2(0, 0), - end: Vector2(0, 700), - width: 80, + start: position + Vector2(-1.2, 10), + end: position + Vector2(-1.2, 117), + width: 5, + rotation: launcherRampRotation, ) ..initialPosition = position ..layer = layer; + final curvedPath = Pathway.arc( color: const Color.fromARGB(255, 251, 255, 0), - center: position + Vector2(-29, -8), - radius: 300, - angle: 10 * math.pi / 9, - width: 80, - ) - ..initialPosition = position + Vector2(-28.8, -6) - ..layer = layer; - final leftOpening = _LauncherRampOpening(rotation: 13 * math.pi / 180) - ..initialPosition = position + Vector2(-72.5, 12) + center: position + Vector2(-2.8, 87.2), + radius: 16.3, + angle: math.pi / 2, + width: 5, + rotation: 3 * math.pi / 2, + )..layer = layer; + + final leftOpening = _LauncherRampOpening(rotation: math.pi / 2) + ..initialPosition = position + Vector2(-11.8, 66.3) ..layer = Layer.opening; final rightOpening = _LauncherRampOpening(rotation: 0) - ..initialPosition = position + Vector2(-46.8, 17) + ..initialPosition = position + Vector2(-4.9, 59.4) ..layer = Layer.opening; await addAll([ diff --git a/lib/game/components/pathway.dart b/lib/game/components/pathway.dart index 414442d3..0c29dd7b 100644 --- a/lib/game/components/pathway.dart +++ b/lib/game/components/pathway.dart @@ -150,10 +150,7 @@ class Pathway extends BodyComponent with InitialPosition, Layered { final fixturesDef = []; for (final path in _paths) { - final chain = ChainShape() - ..createChain( - path.map(gameRef.screenToWorld).toList(), - ); + final chain = ChainShape()..createChain(path); fixturesDef.add(FixtureDef(chain)); } diff --git a/lib/game/components/score_points.dart b/lib/game/components/score_points.dart index b4ad1bdf..da894652 100644 --- a/lib/game/components/score_points.dart +++ b/lib/game/components/score_points.dart @@ -9,6 +9,12 @@ import 'package:pinball/game/game.dart'; mixin ScorePoints on BodyComponent { /// {@macro score_points} int get points; + + @override + Future onLoad() async { + await super.onLoad(); + body.userData = this; + } } /// Adds points to the score when a [Ball] collides with a [BodyComponent] that diff --git a/lib/game/components/spaceship.dart b/lib/game/components/spaceship.dart index f934d943..8243a974 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 { @@ -15,7 +16,10 @@ class Spaceship extends Forge2DBlueprint { @override void build() { - final position = Vector2(30, -50); + final position = Vector2( + PinballGame.boardBounds.left + radius + 15, + PinballGame.boardBounds.center.dy + 30, + ); addAllContactCallback([ SpaceshipHoleBallContactCallback(), @@ -43,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( @@ -101,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, @@ -139,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, @@ -250,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/components/wall.dart b/lib/game/components/wall.dart index 017f8c4d..7475715e 100644 --- a/lib/game/components/wall.dart +++ b/lib/game/components/wall.dart @@ -1,7 +1,9 @@ // ignore_for_file: avoid_renaming_method_parameters +import 'package:flame/extensions.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/components/components.dart'; +import 'package:pinball/game/pinball_game.dart'; /// {@template wall} /// A continuous generic and [BodyType.static] barrier that divides a game area. @@ -39,15 +41,18 @@ class Wall extends BodyComponent { /// Create top, left, and right [Wall]s for the game board. List createBoundaries(Forge2DGame game) { - final topLeft = Vector2.zero(); - final bottomRight = game.screenToWorld(game.camera.viewport.effectiveSize); - final topRight = Vector2(bottomRight.x, topLeft.y); - final bottomLeft = Vector2(topLeft.x, bottomRight.y); + final topLeft = + PinballGame.boardBounds.topLeft.toVector2() + Vector2(18.6, 0); + final bottomRight = PinballGame.boardBounds.bottomRight.toVector2(); + + final topRight = + PinballGame.boardBounds.topRight.toVector2() - Vector2(18.6, 0); + final bottomLeft = PinballGame.boardBounds.bottomLeft.toVector2(); return [ Wall(start: topLeft, end: topRight), Wall(start: topRight, end: bottomRight), - Wall(start: bottomLeft, end: topLeft), + Wall(start: topLeft, end: bottomLeft), ]; } @@ -59,13 +64,10 @@ List createBoundaries(Forge2DGame game) { /// {@endtemplate} class BottomWall extends Wall { /// {@macro bottom_wall} - BottomWall(Forge2DGame game) + BottomWall() : super( - start: game.screenToWorld(game.camera.viewport.effectiveSize), - end: Vector2( - 0, - game.screenToWorld(game.camera.viewport.effectiveSize).y, - ), + start: PinballGame.boardBounds.bottomLeft.toVector2(), + end: PinballGame.boardBounds.bottomRight.toVector2(), ); } 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 86bceef6..44a7ec01 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -1,6 +1,7 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; +import 'package:flame/extensions.dart'; import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; @@ -10,12 +11,21 @@ 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; late final Plunger plunger; + static final boardSize = Vector2(101.6, 143.8); + static final boardBounds = Rect.fromCenter( + center: Offset.zero, + width: boardSize.x, + height: -boardSize.y, + ); + @override void onAttach() { super.onAttach(); @@ -27,11 +37,16 @@ class PinballGame extends Forge2DGame _addContactCallbacks(); await _addGameBoundaries(); - unawaited(_addBoard()); + unawaited(add(Board())); unawaited(_addPlunger()); unawaited(_addBonusWord()); unawaited(_addPaths()); unawaited(addFromBlueprint(Spaceship())); + + // Fix camera on the center of the board. + camera + ..followVector2(Vector2.zero()) + ..zoom = size.y / 16; } void _addContactCallbacks() { @@ -41,44 +56,27 @@ class PinballGame extends Forge2DGame } Future _addGameBoundaries() async { - await add(BottomWall(this)); + await add(BottomWall()); createBoundaries(this).forEach(add); } - Future _addBoard() async { - final board = Board( - size: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x, - camera.viewport.effectiveSize.y, - ), - ), - ); - await add(board); - } - Future _addPlunger() async { - plunger = Plunger( - compressionDistance: camera.viewport.effectiveSize.y / 12, - ); - plunger.initialPosition = screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 + 450, - camera.viewport.effectiveSize.y - plunger.compressionDistance, - ), - ); + plunger = Plunger(compressionDistance: 2); + plunger.initialPosition = boardBounds.bottomRight.toVector2() + + Vector2( + -5, + 10, + ); await add(plunger); } Future _addBonusWord() async { await add( BonusWord( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2, - camera.viewport.effectiveSize.y - 50, - ), + position: Vector2( + boardBounds.center.dx, + boardBounds.bottom + 10, ), ), ); @@ -86,18 +84,22 @@ class PinballGame extends Forge2DGame Future _addPaths() async { final jetpackRamp = JetpackRamp( - position: Vector2(42.6, -45), + position: Vector2( + PinballGame.boardBounds.left + 40.5, + PinballGame.boardBounds.top - 31.5, + ), ); final launcherRamp = LauncherRamp( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 + 400, - camera.viewport.effectiveSize.y / 2 - 330, - ), + position: Vector2( + PinballGame.boardBounds.right - 30, + PinballGame.boardBounds.bottom + 40, ), ); - await addAll([jetpackRamp, launcherRamp]); + await addAll([ + jetpackRamp, + launcherRamp, + ]); } void spawnBall() { 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 1b87fd24..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,13 +8,13 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(Forge2DGame.new); + final flameTester = FlameTester(PinballGameTest.create); group('Board', () { flameTester.test( 'loads correctly', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -27,7 +26,7 @@ void main() { flameTester.test( 'has one left flipper', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -41,7 +40,7 @@ void main() { flameTester.test( 'has one right flipper', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -55,7 +54,7 @@ void main() { flameTester.test( 'has two Baseboards', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -67,7 +66,7 @@ void main() { flameTester.test( 'has two Kickers', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -80,7 +79,7 @@ void main() { 'has three RoundBumpers', (game) async { // TODO(alestiago): change to [NestBumpers] once provided. - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); diff --git a/test/game/components/bonus_word_test.dart b/test/game/components/bonus_word_test.dart index a9af305e..47a7e257 100644 --- a/test/game/components/bonus_word_test.dart +++ b/test/game/components/bonus_word_test.dart @@ -300,12 +300,26 @@ void main() { test('calls ball.activate', () { final ball = MockBall(); final bonusLetter = MockBonusLetter(); - final contactCallback = BonusLetterBallContactCallback(); + + when(() => bonusLetter.isEnabled).thenReturn(true); + contactCallback.begin(ball, bonusLetter, MockContact()); verify(bonusLetter.activate).called(1); }); + + test("doesn't call ball.activate when letter is disabled", () { + final ball = MockBall(); + final bonusLetter = MockBonusLetter(); + final contactCallback = BonusLetterBallContactCallback(); + + when(() => bonusLetter.isEnabled).thenReturn(false); + + contactCallback.begin(ball, bonusLetter, MockContact()); + + verifyNever(bonusLetter.activate); + }); }); }); } 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.