diff --git a/.github/workflows/pinball_components.yaml b/.github/workflows/pinball_components.yaml index bf1907f8..e4154059 100644 --- a/.github/workflows/pinball_components.yaml +++ b/.github/workflows/pinball_components.yaml @@ -13,7 +13,7 @@ on: jobs: build: - uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@b075749771679a5baa4c90d36ad2e8580bbf273b with: working_directory: packages/pinball_components coverage_excludes: "lib/gen/*.dart" diff --git a/lib/game/components/plunger.dart b/lib/game/components/plunger.dart index b319af80..1911be02 100644 --- a/lib/game/components/plunger.dart +++ b/lib/game/components/plunger.dart @@ -129,8 +129,8 @@ class PlungerAnchor extends JointAnchor { required Plunger plunger, }) { initialPosition = Vector2( - plunger.body.position.x, - plunger.body.position.y - plunger.compressionDistance, + 0, + -plunger.compressionDistance, ); } @@ -161,7 +161,7 @@ class PlungerAnchorPrismaticJointDef extends PrismaticJointDef { initialize( plunger.body, anchor.body, - anchor.body.position, + plunger.body.position + anchor.body.position, Vector2(18.6, BoardDimensions.bounds.height), ); enableLimit = true; diff --git a/packages/pinball_components/lib/src/components/camera_zoom.dart b/packages/pinball_components/lib/src/components/camera_zoom.dart new file mode 100644 index 00000000..a3da382e --- /dev/null +++ b/packages/pinball_components/lib/src/components/camera_zoom.dart @@ -0,0 +1,56 @@ +import 'dart:async'; + +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:flutter/material.dart'; + +/// {@template camera_zoom} +/// Applies zoom to the camera of the game where this is added to +/// {@endtemplate} +class CameraZoom extends Effect with HasGameRef { + /// {@macro camera_zoom} + CameraZoom({ + required this.value, + }) : super( + EffectController( + duration: 0.4, + curve: Curves.easeOut, + ), + ); + + /// The total zoom value to be applied to the camera + final double value; + + late final Tween _tween; + + final Completer _completer = Completer(); + + @override + Future onLoad() async { + _tween = Tween( + begin: gameRef.camera.zoom, + end: value, + ); + } + + @override + void apply(double progress) { + gameRef.camera.zoom = _tween.transform(progress); + } + + /// Returns a [Future] that completes once the zoom is finished + Future get completed { + if (controller.completed) { + return Future.value(); + } + + return _completer.future; + } + + @override + void onRemove() { + _completer.complete(); + + super.onRemove(); + } +} diff --git a/packages/pinball_components/lib/src/components/chrome_dino.dart b/packages/pinball_components/lib/src/components/chrome_dino.dart index 2caa40c8..327e14f5 100644 --- a/packages/pinball_components/lib/src/components/chrome_dino.dart +++ b/packages/pinball_components/lib/src/components/chrome_dino.dart @@ -23,7 +23,7 @@ class ChromeDino extends BodyComponent with InitialPosition { /// Anchors the [ChromeDino] to the [RevoluteJoint] that controls its arc /// motion. Future<_ChromeDinoJoint> _anchorToJoint() async { - final anchor = _ChromeDinoAnchor(chromeDino: this); + final anchor = _ChromeDinoAnchor(); await add(anchor); final jointDef = _ChromeDinoAnchorRevoluteJointDef( @@ -110,12 +110,10 @@ class ChromeDino extends BodyComponent with InitialPosition { /// {@endtemplate} class _ChromeDinoAnchor extends JointAnchor { /// {@macro flipper_anchor} - _ChromeDinoAnchor({ - required ChromeDino chromeDino, - }) { + _ChromeDinoAnchor() { initialPosition = Vector2( - chromeDino.body.position.x + ChromeDino.size.x / 2, - chromeDino.body.position.y, + ChromeDino.size.x / 2, + 0, ); } } @@ -132,7 +130,7 @@ class _ChromeDinoAnchorRevoluteJointDef extends RevoluteJointDef { initialize( chromeDino.body, anchor.body, - anchor.body.position, + chromeDino.body.position + anchor.body.position, ); enableLimit = true; // TODO(alestiago): Apply design angle value. diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 19fb170e..62ed3d70 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -4,6 +4,7 @@ export 'baseboard.dart'; export 'board_dimensions.dart'; export 'board_side.dart'; export 'boundaries.dart'; +export 'camera_zoom.dart'; export 'chrome_dino.dart'; export 'dash_nest_bumper.dart'; export 'dino_walls.dart'; diff --git a/packages/pinball_components/lib/src/components/flipper.dart b/packages/pinball_components/lib/src/components/flipper.dart index 49bd6d6f..64a82269 100644 --- a/packages/pinball_components/lib/src/components/flipper.dart +++ b/packages/pinball_components/lib/src/components/flipper.dart @@ -159,8 +159,9 @@ class _FlipperAnchor extends JointAnchor { required Flipper flipper, }) { initialPosition = Vector2( - flipper.body.position.x + ((Flipper.size.x * flipper.side.direction) / 2), - flipper.body.position.y, + (Flipper.size.x * flipper.side.direction) / 2 - + (1.65 * flipper.side.direction), + 0.15, ); } } @@ -178,7 +179,7 @@ class _FlipperAnchorRevoluteJointDef extends RevoluteJointDef { initialize( flipper.body, anchor.body, - anchor.body.position, + flipper.body.position + anchor.body.position, ); } diff --git a/packages/pinball_components/lib/src/components/joint_anchor.dart b/packages/pinball_components/lib/src/components/joint_anchor.dart index 98b80ece..7ca75ba0 100644 --- a/packages/pinball_components/lib/src/components/joint_anchor.dart +++ b/packages/pinball_components/lib/src/components/joint_anchor.dart @@ -12,7 +12,7 @@ import 'package:pinball_components/pinball_components.dart'; /// initialize( /// dynamicBody.body, /// anchor.body, -/// anchor.body.position, +/// dynabmicBody.body + anchor.body.position, /// ); /// ``` /// {@endtemplate} diff --git a/packages/pinball_components/sandbox/lib/common/trace.dart b/packages/pinball_components/sandbox/lib/common/trace.dart index d64a5c6c..8585169e 100644 --- a/packages/pinball_components/sandbox/lib/common/trace.dart +++ b/packages/pinball_components/sandbox/lib/common/trace.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; +import 'package:pinball_components/pinball_components.dart'; extension BodyTrace on BodyComponent { void trace({Color color = const Color(0xFFFF0000)}) { @@ -13,7 +14,28 @@ extension BodyTrace on BodyComponent { mounted.whenComplete(() { final sprite = children.whereType().first; sprite.paint.color = sprite.paint.color.withOpacity(0.5); + + descendants().whereType().forEach((anchor) { + final fixtureDef = FixtureDef(CircleShape()..radius = 0.5); + anchor.body.createFixture(fixtureDef); + anchor.renderBody = true; + }); }), ); } } + +mixin Traceable on Forge2DGame { + late final bool trace; + + Future traceAllBodies({ + Color color = const Color(0xFFFF0000), + }) async { + if (trace) { + await ready(); + children + .whereType() + .forEach((bodyComponent) => bodyComponent.trace()); + } + } +} diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index 5abef41d..b4468ade 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -24,5 +24,6 @@ void main() { addSlingshotStories(dashbook); addSparkyBumperStories(dashbook); addAlienBumperStories(dashbook); + addZoomStories(dashbook); runApp(dashbook); } diff --git a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart index 9638c36d..649256d8 100644 --- a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/big_dash_nest_bumper_game.dart @@ -5,10 +5,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class BigDashNestBumperGame extends BasicBallGame { - BigDashNestBumperGame({ - required this.trace, - }) : super(color: const Color(0xFF0000FF)); +class BigDashNestBumperGame extends BasicBallGame with Traceable { + BigDashNestBumperGame() : super(color: const Color(0xFF0000FF)); static const info = ''' Shows how a BigDashNestBumper is rendered. @@ -16,8 +14,6 @@ class BigDashNestBumperGame extends BasicBallGame { Activate the "trace" parameter to overlay the body. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -28,6 +24,6 @@ class BigDashNestBumperGame extends BasicBallGame { ..priority = 1; await add(bigDashNestBumper); - if (trace) bigDashNestBumper.trace(); + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart index 95f3cd2a..22f792bc 100644 --- a/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/dash_nest_bumper/stories.dart @@ -8,9 +8,8 @@ void addDashNestBumperStories(Dashbook dashbook) { dashbook.storiesOf('Dash Nest Bumpers').add( 'Big', (context) => GameWidget( - game: BigDashNestBumperGame( - trace: context.boolProperty('Trace', true), - ), + game: BigDashNestBumperGame() + ..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('dash_nest_bumper/big.dart'), info: BasicBallGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/basic_flipper_game.dart b/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart similarity index 77% rename from packages/pinball_components/sandbox/lib/stories/flipper/basic_flipper_game.dart rename to packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart index 78959374..5a9e1787 100644 --- a/packages/pinball_components/sandbox/lib/stories/flipper/basic_flipper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/flipper/flipper_game.dart @@ -2,13 +2,21 @@ import 'package:flame/input.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class BasicFlipperGame extends BasicBallGame with KeyboardEvents { - BasicFlipperGame() : super(color: Colors.blue); +class FlipperGame extends BasicBallGame with KeyboardEvents, Traceable { + FlipperGame() : super(color: Colors.blue); - static const info = 'Shows how a Flipper works.'; + static const info = ''' + Shows how Flippers are rendered. + + - Activate the "trace" parameter to overlay the body. + - Tap anywhere on the screen to spawn a ball into the game. + - Press left arrow key or "A" to move the left flipper. + - Press right arrow key or "D" to move the right flipper. + '''; static const _leftFlipperKeys = [ LogicalKeyboardKey.arrowLeft, @@ -38,6 +46,8 @@ class BasicFlipperGame extends BasicBallGame with KeyboardEvents { leftFlipper, rightFlipper, ]); + + await traceAllBodies(); } @override diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/flipper_tracing_game.dart b/packages/pinball_components/sandbox/lib/stories/flipper/flipper_tracing_game.dart deleted file mode 100644 index 482440cb..00000000 --- a/packages/pinball_components/sandbox/lib/stories/flipper/flipper_tracing_game.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'dart:async'; - -import 'package:flame_forge2d/flame_forge2d.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/flipper/basic_flipper_game.dart'; - -class FlipperTracingGame extends BasicFlipperGame { - static const info = ''' - Basic example of how the Flipper body overlays the sprite. -'''; - - @override - Future onLoad() async { - await super.onLoad(); - - leftFlipper.trace(); - leftFlipper.body.joints.whereType().forEach( - (joint) => joint.setLimits(0, 0), - ); - - rightFlipper.trace(); - rightFlipper.body.joints.whereType().forEach( - (joint) => joint.setLimits(0, 0), - ); - } -} diff --git a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart b/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart index 3cad3ade..f8aa0075 100644 --- a/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/flipper/stories.dart @@ -1,25 +1,15 @@ import 'package:dashbook/dashbook.dart'; import 'package:flame/game.dart'; import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/flipper/basic_flipper_game.dart'; -import 'package:sandbox/stories/flipper/flipper_tracing_game.dart'; +import 'package:sandbox/stories/flipper/flipper_game.dart'; void addFlipperStories(Dashbook dashbook) { - dashbook.storiesOf('Flipper') - ..add( - 'Basic', - (context) => GameWidget( - game: BasicFlipperGame(), - ), - codeLink: buildSourceLink('flipper/basic.dart'), - info: BasicFlipperGame.info, - ) - ..add( - 'Tracing', - (context) => GameWidget( - game: FlipperTracingGame(), - ), - codeLink: buildSourceLink('flipper/tracing.dart'), - info: FlipperTracingGame.info, - ); + dashbook.storiesOf('Flipper').add( + 'Basic', + (context) => GameWidget( + game: FlipperGame()..trace = context.boolProperty('Trace', true), + ), + codeLink: buildSourceLink('flipper/basic.dart'), + info: FlipperGame.info, + ); } diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart b/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart index 21c0cfb8..1b29c3f9 100644 --- a/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/kicker/kicker_game.dart @@ -3,10 +3,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class KickerGame extends BasicBallGame { - KickerGame({ - required this.trace, - }) : super(color: const Color(0xFFFF0000)); +class KickerGame extends BasicBallGame with Traceable { + KickerGame() : super(color: const Color(0xFFFF0000)); static const info = ''' Shows how Kickers are rendered. @@ -15,8 +13,6 @@ class KickerGame extends BasicBallGame { - Tap anywhere on the screen to spawn a ball into the game. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -31,9 +27,6 @@ class KickerGame extends BasicBallGame { ..initialPosition = Vector2(center.x + (Kicker.size.x * 2), center.y); await add(rightKicker); - if (trace) { - leftKicker.trace(); - rightKicker.trace(); - } + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart b/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart index f4a6bf91..77d6ff29 100644 --- a/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/kicker/stories.dart @@ -7,9 +7,7 @@ void addKickerStories(Dashbook dashbook) { dashbook.storiesOf('Kickers').add( 'Basic', (context) => GameWidget( - game: KickerGame( - trace: context.boolProperty('Trace', true), - ), + game: KickerGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('kicker_game/basic.dart'), info: KickerGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart index c02689ca..8d54f391 100644 --- a/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart @@ -1,14 +1,10 @@ -import 'dart:math' as math; - import 'package:flame/extensions.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class SlingshotGame extends BasicBallGame { - SlingshotGame({ - required this.trace, - }) : super(color: const Color(0xFFFF0000)); +class SlingshotGame extends BasicBallGame with Traceable { + SlingshotGame() : super(color: const Color(0xFFFF0000)); static const info = ''' Shows how Slingshots are rendered. @@ -17,50 +13,11 @@ class SlingshotGame extends BasicBallGame { - Tap anywhere on the screen to spawn a ball into the game. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); - - final center = screenToWorld(camera.viewport.canvasSize! / 2); - - final leftUpperSlingshot = Slingshot( - length: 5.66, - angle: -1.5 * (math.pi / 180), - spritePath: Assets.images.slingshot.leftUpper.keyName, - )..initialPosition = center + Vector2(-29, 1.5); - - final leftLowerSlingshot = Slingshot( - length: 3.54, - angle: -29.1 * (math.pi / 180), - spritePath: Assets.images.slingshot.leftLower.keyName, - )..initialPosition = center + Vector2(-31, -6.2); - - final rightUpperSlingshot = Slingshot( - length: 5.64, - angle: 1 * (math.pi / 180), - spritePath: Assets.images.slingshot.rightUpper.keyName, - )..initialPosition = center + Vector2(22.3, 1.58); - - final rightLowerSlingshot = Slingshot( - length: 3.46, - angle: 26.8 * (math.pi / 180), - spritePath: Assets.images.slingshot.rightLower.keyName, - )..initialPosition = center + Vector2(24.7, -6.2); - - await addAll([ - leftUpperSlingshot, - leftLowerSlingshot, - rightUpperSlingshot, - rightLowerSlingshot, - ]); - - if (trace) { - leftUpperSlingshot.trace(); - leftLowerSlingshot.trace(); - rightUpperSlingshot.trace(); - rightLowerSlingshot.trace(); - } + await addFromBlueprint(Slingshots()); + camera.followVector2(Vector2.zero()); + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart index 6e985d32..70dfa021 100644 --- a/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart @@ -7,9 +7,7 @@ void addSlingshotStories(Dashbook dashbook) { dashbook.storiesOf('Slingshots').add( 'Basic', (context) => GameWidget( - game: SlingshotGame( - trace: context.boolProperty('Trace', true), - ), + game: SlingshotGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('slingshot_game/basic.dart'), info: SlingshotGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart index a0ad661a..a57beb8d 100644 --- a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/sparky_bumper_game.dart @@ -5,10 +5,8 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class SparkyBumperGame extends BasicBallGame { - SparkyBumperGame({ - required this.trace, - }) : super(color: const Color(0xFF0000FF)); +class SparkyBumperGame extends BasicBallGame with Traceable { + SparkyBumperGame() : super(color: const Color(0xFF0000FF)); static const info = ''' Shows how a SparkyBumper is rendered. @@ -16,8 +14,6 @@ class SparkyBumperGame extends BasicBallGame { Activate the "trace" parameter to overlay the body. '''; - final bool trace; - @override Future onLoad() async { await super.onLoad(); @@ -38,10 +34,6 @@ class SparkyBumperGame extends BasicBallGame { sparkyBumperC, ]); - if (trace) { - sparkyBumperA.trace(); - sparkyBumperB.trace(); - sparkyBumperC.trace(); - } + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart index d0933b67..1a5f8801 100644 --- a/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/sparky_bumper/stories.dart @@ -7,9 +7,7 @@ void addSparkyBumperStories(Dashbook dashbook) { dashbook.storiesOf('Sparky Bumpers').add( 'Basic', (context) => GameWidget( - game: SparkyBumperGame( - trace: context.boolProperty('Trace', true), - ), + game: SparkyBumperGame()..trace = context.boolProperty('Trace', true), ), codeLink: buildSourceLink('sparky_bumper/basic.dart'), info: SparkyBumperGame.info, diff --git a/packages/pinball_components/sandbox/lib/stories/stories.dart b/packages/pinball_components/sandbox/lib/stories/stories.dart index f25b1990..871e056e 100644 --- a/packages/pinball_components/sandbox/lib/stories/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/stories.dart @@ -9,3 +9,4 @@ export 'layer/stories.dart'; export 'slingshot/stories.dart'; export 'spaceship/stories.dart'; export 'sparky_bumper/stories.dart'; +export 'zoom/stories.dart'; diff --git a/packages/pinball_components/sandbox/lib/stories/zoom/basic_zoom_game.dart b/packages/pinball_components/sandbox/lib/stories/zoom/basic_zoom_game.dart new file mode 100644 index 00000000..276dd39c --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/zoom/basic_zoom_game.dart @@ -0,0 +1,37 @@ +import 'package:flame/components.dart'; +import 'package:flame/input.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; + +class BasicCameraZoomGame extends BasicGame with TapDetector { + static const info = ''' + Simple game to demonstrate how the CameraZoom can be used. + Tap to zoom in/out + '''; + + bool zoomApplied = false; + + @override + Future onLoad() async { + final sprite = await loadSprite(Assets.images.flutterSignPost.keyName); + + await add( + SpriteComponent( + sprite: sprite, + size: Vector2(4, 8), + anchor: Anchor.center, + ), + ); + + camera.followVector2(Vector2.zero()); + } + + @override + void onTap() { + if (firstChild() == null) { + final zoom = CameraZoom(value: zoomApplied ? 30 : 10); + add(zoom); + zoomApplied = !zoomApplied; + } + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/zoom/stories.dart b/packages/pinball_components/sandbox/lib/stories/zoom/stories.dart new file mode 100644 index 00000000..653d5491 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/zoom/stories.dart @@ -0,0 +1,15 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:flame/game.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/zoom/basic_zoom_game.dart'; + +void addZoomStories(Dashbook dashbook) { + dashbook.storiesOf('CameraZoom').add( + 'Basic', + (context) => GameWidget( + game: BasicCameraZoomGame(), + ), + codeLink: buildSourceLink('zoom/basic_zoom_game.dart'), + info: BasicCameraZoomGame.info, + ); +} diff --git a/packages/pinball_components/test/src/components/camera_zoom_test.dart b/packages/pinball_components/test/src/components/camera_zoom_test.dart new file mode 100644 index 00000000..00f43847 --- /dev/null +++ b/packages/pinball_components/test/src/components/camera_zoom_test.dart @@ -0,0 +1,85 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame/components.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball_components/pinball_components.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('CameraZoom', () { + final tester = FlameTester(TestGame.new); + + tester.testGameWidget( + 'renders correctly', + setUp: (game, tester) async { + game.camera.followVector2(Vector2.zero()); + game.camera.zoom = 10; + final sprite = await game.loadSprite( + Assets.images.flutterSignPost.keyName, + ); + + await game.add( + SpriteComponent( + sprite: sprite, + size: Vector2(4, 8), + anchor: Anchor.center, + ), + ); + + await game.add(CameraZoom(value: 40)); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/camera_zoom/no_zoom.png'), + ); + + game.update(0.2); + await tester.pump(); + await expectLater( + find.byGame(), + matchesGoldenFile('golden/camera_zoom/in_between.png'), + ); + + game.update(0.4); + await tester.pump(); + await expectLater( + find.byGame(), + matchesGoldenFile('golden/camera_zoom/finished.png'), + ); + game.update(0.1); + await tester.pump(); + + expect(game.firstChild(), isNull); + }, + ); + + tester.test( + 'completes when checked after it is finished', + (game) async { + await game.add(CameraZoom(value: 40)); + game.update(10); + final cameraZoom = game.firstChild(); + final future = cameraZoom!.completed; + + expect(future, completes); + }, + ); + + tester.test( + 'completes when checked before it is finished', + (game) async { + final zoom = CameraZoom(value: 40); + final future = zoom.completed; + + await game.add(zoom); + game.update(10); + game.update(0); + + expect(future, completes); + }, + ); + }); +} diff --git a/packages/pinball_components/test/src/components/golden/camera_zoom/finished.png b/packages/pinball_components/test/src/components/golden/camera_zoom/finished.png new file mode 100644 index 00000000..be784ada Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/camera_zoom/finished.png differ diff --git a/packages/pinball_components/test/src/components/golden/camera_zoom/in_between.png b/packages/pinball_components/test/src/components/golden/camera_zoom/in_between.png new file mode 100644 index 00000000..3809f0d0 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/camera_zoom/in_between.png differ diff --git a/packages/pinball_components/test/src/components/golden/camera_zoom/no_zoom.png b/packages/pinball_components/test/src/components/golden/camera_zoom/no_zoom.png new file mode 100644 index 00000000..a6215d65 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/camera_zoom/no_zoom.png differ