diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart index 8ee4128f..666cec5b 100644 --- a/lib/game/components/board.dart +++ b/lib/game/components/board.dart @@ -18,17 +18,8 @@ class Board extends Component { final flutterForest = FlutterForest(); - // TODO(alestiago): adjust positioning to real design. - // TODO(alestiago): add dino in pinball game. - final dino = ChromeDino() - ..initialPosition = Vector2( - BoardDimensions.bounds.center.dx + 25, - BoardDimensions.bounds.center.dy - 10, - ); - await addAll([ bottomGroup, - dino, flutterForest, ]); } diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 993215b5..ab4e9860 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -34,8 +34,10 @@ extension PinballGameAssetsX on PinballGame { images.load( components.Assets.images.launchRamp.backgroundRailing.keyName, ), - images.load(components.Assets.images.dino.dinoLandTop.keyName), - images.load(components.Assets.images.dino.dinoLandBottom.keyName), + images.load(components.Assets.images.dino.bottomWall.keyName), + images.load(components.Assets.images.dino.topWall.keyName), + images.load(components.Assets.images.dino.animatronic.head.keyName), + images.load(components.Assets.images.dino.animatronic.mouth.keyName), images.load(components.Assets.images.dash.animatronic.keyName), images.load(components.Assets.images.dash.bumper.a.active.keyName), images.load(components.Assets.images.dash.bumper.a.inactive.keyName), @@ -81,8 +83,6 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.androidBumper.a.dimmed.keyName), images.load(components.Assets.images.androidBumper.b.lit.keyName), images.load(components.Assets.images.androidBumper.b.dimmed.keyName), - images.load(components.Assets.images.chromeDino.mouth.keyName), - images.load(components.Assets.images.chromeDino.head.keyName), images.load(components.Assets.images.sparky.computer.top.keyName), images.load(components.Assets.images.sparky.computer.base.keyName), images.load(components.Assets.images.sparky.animatronic.keyName), diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index c0d4445e..4b57f1dd 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -57,6 +57,7 @@ class PinballGame extends Forge2DGame await addFromBlueprint(AndroidAcres()); unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(DinoWalls())); + await add(ChromeDino()..initialPosition = Vector2(12.3, -6.9)); await add( GoogleWord( position: Vector2( diff --git a/packages/pinball_components/assets/images/chrome_dino/head.png b/packages/pinball_components/assets/images/chrome_dino/head.png deleted file mode 100644 index 15be6fcd..00000000 Binary files a/packages/pinball_components/assets/images/chrome_dino/head.png and /dev/null differ diff --git a/packages/pinball_components/assets/images/chrome_dino/mouth.png b/packages/pinball_components/assets/images/chrome_dino/mouth.png deleted file mode 100644 index 3d9caeae..00000000 Binary files a/packages/pinball_components/assets/images/chrome_dino/mouth.png and /dev/null differ diff --git a/packages/pinball_components/assets/images/dino/animatronic/head.png b/packages/pinball_components/assets/images/dino/animatronic/head.png new file mode 100644 index 00000000..87332679 Binary files /dev/null and b/packages/pinball_components/assets/images/dino/animatronic/head.png differ diff --git a/packages/pinball_components/assets/images/dino/animatronic/mouth.png b/packages/pinball_components/assets/images/dino/animatronic/mouth.png new file mode 100644 index 00000000..4955bdf3 Binary files /dev/null and b/packages/pinball_components/assets/images/dino/animatronic/mouth.png differ diff --git a/packages/pinball_components/assets/images/dino/dino-land-bottom.png b/packages/pinball_components/assets/images/dino/bottom-wall.png similarity index 100% rename from packages/pinball_components/assets/images/dino/dino-land-bottom.png rename to packages/pinball_components/assets/images/dino/bottom-wall.png diff --git a/packages/pinball_components/assets/images/dino/dino-land-top.png b/packages/pinball_components/assets/images/dino/top-wall.png similarity index 100% rename from packages/pinball_components/assets/images/dino/dino-land-top.png rename to packages/pinball_components/assets/images/dino/top-wall.png diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index 72b3d5eb..1a272d31 100644 --- a/packages/pinball_components/lib/gen/assets.gen.dart +++ b/packages/pinball_components/lib/gen/assets.gen.dart @@ -16,8 +16,6 @@ class $AssetsImagesGen { $AssetsImagesBallGen get ball => const $AssetsImagesBallGen(); $AssetsImagesBaseboardGen get baseboard => const $AssetsImagesBaseboardGen(); $AssetsImagesBoundaryGen get boundary => const $AssetsImagesBoundaryGen(); - $AssetsImagesChromeDinoGen get chromeDino => - const $AssetsImagesChromeDinoGen(); $AssetsImagesDashGen get dash => const $AssetsImagesDashGen(); $AssetsImagesDinoGen get dino => const $AssetsImagesDinoGen(); $AssetsImagesFlipperGen get flipper => const $AssetsImagesFlipperGen(); @@ -97,18 +95,6 @@ class $AssetsImagesBoundaryGen { const AssetGenImage('assets/images/boundary/outer.png'); } -class $AssetsImagesChromeDinoGen { - const $AssetsImagesChromeDinoGen(); - - /// File path: assets/images/chrome_dino/head.png - AssetGenImage get head => - const AssetGenImage('assets/images/chrome_dino/head.png'); - - /// File path: assets/images/chrome_dino/mouth.png - AssetGenImage get mouth => - const AssetGenImage('assets/images/chrome_dino/mouth.png'); -} - class $AssetsImagesDashGen { const $AssetsImagesDashGen(); @@ -122,13 +108,16 @@ class $AssetsImagesDashGen { class $AssetsImagesDinoGen { const $AssetsImagesDinoGen(); - /// File path: assets/images/dino/dino-land-bottom.png - AssetGenImage get dinoLandBottom => - const AssetGenImage('assets/images/dino/dino-land-bottom.png'); + $AssetsImagesDinoAnimatronicGen get animatronic => + const $AssetsImagesDinoAnimatronicGen(); + + /// File path: assets/images/dino/bottom-wall.png + AssetGenImage get bottomWall => + const AssetGenImage('assets/images/dino/bottom-wall.png'); - /// File path: assets/images/dino/dino-land-top.png - AssetGenImage get dinoLandTop => - const AssetGenImage('assets/images/dino/dino-land-top.png'); + /// File path: assets/images/dino/top-wall.png + AssetGenImage get topWall => + const AssetGenImage('assets/images/dino/top-wall.png'); } class $AssetsImagesFlipperGen { @@ -304,6 +293,18 @@ class $AssetsImagesDashBumperGen { const $AssetsImagesDashBumperMainGen(); } +class $AssetsImagesDinoAnimatronicGen { + const $AssetsImagesDinoAnimatronicGen(); + + /// File path: assets/images/dino/animatronic/head.png + AssetGenImage get head => + const AssetGenImage('assets/images/dino/animatronic/head.png'); + + /// File path: assets/images/dino/animatronic/mouth.png + AssetGenImage get mouth => + const AssetGenImage('assets/images/dino/animatronic/mouth.png'); +} + class $AssetsImagesSpaceshipRailGen { const $AssetsImagesSpaceshipRailGen(); diff --git a/packages/pinball_components/lib/src/components/boundaries.dart b/packages/pinball_components/lib/src/components/boundaries.dart index 59bacb08..3d0f9445 100644 --- a/packages/pinball_components/lib/src/components/boundaries.dart +++ b/packages/pinball_components/lib/src/components/boundaries.dart @@ -67,7 +67,7 @@ class _BottomBoundarySpriteComponent extends SpriteComponent with HasGameRef { _BottomBoundarySpriteComponent() : super( anchor: Anchor.center, - position: Vector2(-5.4, 55.6), + position: Vector2(-5, 55.6), ); @override diff --git a/packages/pinball_components/lib/src/components/chrome_dino.dart b/packages/pinball_components/lib/src/components/chrome_dino.dart index 7846f140..e1a1a1fc 100644 --- a/packages/pinball_components/lib/src/components/chrome_dino.dart +++ b/packages/pinball_components/lib/src/components/chrome_dino.dart @@ -1,31 +1,33 @@ import 'dart:async'; -import 'dart:math' as math; import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart' hide Timer; -import 'package:flutter/material.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template chrome_dino} -/// Dinosaur that gobbles up a [Ball], swivel his head around, and shoots it -/// back out. +/// Dino that swivels back and forth, opening its mouth to eat a [Ball]. +/// +/// Upon eating a [Ball], the dino rotates and spits the [Ball] out in a +/// different direction. /// {@endtemplate} class ChromeDino extends BodyComponent with InitialPosition { /// {@macro chrome_dino} ChromeDino() : super( - // TODO(alestiago): Remove once sprites are defined. - paint: Paint()..color = Colors.blue, priority: RenderPriority.dino, + renderBody: false, ); /// The size of the dinosaur mouth. - static final size = Vector2(5, 2.5); + static final size = Vector2(5.5, 5); /// Anchors the [ChromeDino] to the [RevoluteJoint] that controls its arc /// motion. Future<_ChromeDinoJoint> _anchorToJoint() async { - final anchor = _ChromeDinoAnchor(); + // TODO(allisonryan0002): try moving to anchor after new body is defined. + final anchor = _ChromeDinoAnchor() + ..initialPosition = initialPosition + Vector2(9, -4); + await add(anchor); final jointDef = _ChromeDinoAnchorRevoluteJointDef( @@ -42,9 +44,11 @@ class ChromeDino extends BodyComponent with InitialPosition { Future onLoad() async { await super.onLoad(); final joint = await _anchorToJoint(); + const framesInAnimation = 98; + const animationFPS = 1 / 24; await add( TimerComponent( - period: 1, + period: (framesInAnimation / 2) * animationFPS, onTick: joint._swivel, repeat: true, ), @@ -54,44 +58,17 @@ class ChromeDino extends BodyComponent with InitialPosition { List _createFixtureDefs() { final fixtureDefs = []; - // TODO(alestiago): Subject to change when sprites are added. - final box = PolygonShape()..setAsBoxXY(size.x / 2, size.y / 2); - final fixtureDef = FixtureDef( - box, - density: 999, - friction: 0.3, - restitution: 0.1, - isSensor: true, - ); - + // TODO(allisonryan0002): Update this shape to better match sprite. + final box = PolygonShape() + ..setAsBox( + size.x / 2, + size.y / 2, + initialPosition + Vector2(-4, 2), + -_ChromeDinoJoint._halfSweepingAngle, + ); + final fixtureDef = FixtureDef(box, density: 1); fixtureDefs.add(fixtureDef); - // FIXME(alestiago): Investigate why adding these fixtures is considered as - // an invalid contact type. - // final upperEdge = EdgeShape() - // ..set( - // Vector2(-size.x / 2, -size.y / 2), - // Vector2(size.x / 2, -size.y / 2), - // ); - // final upperEdgeDef = FixtureDef(upperEdge)..density = 0.5; - // fixtureDefs.add(upperEdgeDef); - - // final lowerEdge = EdgeShape() - // ..set( - // Vector2(-size.x / 2, size.y / 2), - // Vector2(size.x / 2, size.y / 2), - // ); - // final lowerEdgeDef = FixtureDef(lowerEdge)..density = 0.5; - // fixtureDefs.add(lowerEdgeDef); - - // final rightEdge = EdgeShape() - // ..set( - // Vector2(size.x / 2, -size.y / 2), - // Vector2(size.x / 2, size.y / 2), - // ); - // final rightEdgeDef = FixtureDef(rightEdge)..density = 0.5; - // fixtureDefs.add(rightEdgeDef); - return fixtureDefs; } @@ -110,13 +87,18 @@ class ChromeDino extends BodyComponent with InitialPosition { } } -/// {@template flipper_anchor} -/// [JointAnchor] positioned at the end of a [ChromeDino]. -/// {@endtemplate} class _ChromeDinoAnchor extends JointAnchor { - /// {@macro flipper_anchor} - _ChromeDinoAnchor() { - initialPosition = Vector2(ChromeDino.size.x / 2, 0); + _ChromeDinoAnchor(); + + // TODO(allisonryan0002): if these aren't moved when fixing the rendering, see + // if the joint can be created in onMount to resolve render syncing. + @override + Future onLoad() async { + await super.onLoad(); + await addAll([ + _ChromeDinoMouthSprite(), + _ChromeDinoHeadSprite(), + ]); } } @@ -135,22 +117,86 @@ class _ChromeDinoAnchorRevoluteJointDef extends RevoluteJointDef { chromeDino.body.position + anchor.body.position, ); enableLimit = true; - // TODO(alestiago): Apply design angle value. - const angle = math.pi / 3.5; - lowerAngle = -angle / 2; - upperAngle = angle / 2; + lowerAngle = -_ChromeDinoJoint._halfSweepingAngle; + upperAngle = _ChromeDinoJoint._halfSweepingAngle; enableMotor = true; - // TODO(alestiago): Tune this values. - maxMotorTorque = motorSpeed = chromeDino.body.mass * 30; + maxMotorTorque = chromeDino.body.mass * 255; + motorSpeed = 2; } } class _ChromeDinoJoint extends RevoluteJoint { _ChromeDinoJoint(_ChromeDinoAnchorRevoluteJointDef def) : super(def); + static const _halfSweepingAngle = 0.1143; + /// Sweeps the [ChromeDino] up and down repeatedly. void _swivel() { setMotorSpeed(-motorSpeed); } } + +class _ChromeDinoMouthSprite extends SpriteAnimationComponent with HasGameRef { + _ChromeDinoMouthSprite() + : super( + anchor: Anchor(Anchor.center.x + 0.47, Anchor.center.y - 0.29), + angle: _ChromeDinoJoint._halfSweepingAngle, + ); + + @override + Future onLoad() async { + await super.onLoad(); + final image = gameRef.images.fromCache( + Assets.images.dino.animatronic.mouth.keyName, + ); + + const amountPerRow = 11; + const amountPerColumn = 9; + final textureSize = Vector2( + image.width / amountPerRow, + image.height / amountPerColumn, + ); + size = textureSize / 10; + + final data = SpriteAnimationData.sequenced( + amount: (amountPerColumn * amountPerRow) - 1, + amountPerRow: amountPerRow, + stepTime: 1 / 24, + textureSize: textureSize, + ); + animation = SpriteAnimation.fromFrameData(image, data)..currentIndex = 45; + } +} + +class _ChromeDinoHeadSprite extends SpriteAnimationComponent with HasGameRef { + _ChromeDinoHeadSprite() + : super( + anchor: Anchor(Anchor.center.x + 0.47, Anchor.center.y - 0.29), + angle: _ChromeDinoJoint._halfSweepingAngle, + ); + + @override + Future onLoad() async { + await super.onLoad(); + final image = gameRef.images.fromCache( + Assets.images.dino.animatronic.head.keyName, + ); + + const amountPerRow = 11; + const amountPerColumn = 9; + final textureSize = Vector2( + image.width / amountPerRow, + image.height / amountPerColumn, + ); + size = textureSize / 10; + + final data = SpriteAnimationData.sequenced( + amount: (amountPerColumn * amountPerRow) - 1, + amountPerRow: amountPerRow, + stepTime: 1 / 24, + textureSize: textureSize, + ); + animation = SpriteAnimation.fromFrameData(image, data)..currentIndex = 45; + } +} diff --git a/packages/pinball_components/lib/src/components/dino_walls.dart b/packages/pinball_components/lib/src/components/dino_walls.dart index 0e0e2efa..39824490 100644 --- a/packages/pinball_components/lib/src/components/dino_walls.dart +++ b/packages/pinball_components/lib/src/components/dino_walls.dart @@ -35,51 +35,46 @@ class _DinoTopWall extends BodyComponent with InitialPosition { List _createFixtureDefs() { final topStraightShape = EdgeShape() ..set( - Vector2(28.65, -35.1), - Vector2(29.5, -35.1), + Vector2(28.65, -34.3), + Vector2(29.5, -34.3), ); - final topStraightFixtureDef = FixtureDef(topStraightShape); final topCurveShape = BezierCurveShape( controlPoints: [ topStraightShape.vertex1, - Vector2(18.8, -27), - Vector2(26.6, -21), + Vector2(18.8, -26.2), + Vector2(26.6, -20.2), ], ); - final topCurveFixtureDef = FixtureDef(topCurveShape); final middleCurveShape = BezierCurveShape( controlPoints: [ topCurveShape.vertices.last, - Vector2(27.8, -20.1), - Vector2(26.8, -19.5), + Vector2(27.8, -19.3), + Vector2(26.8, -18.7), ], ); - final middleCurveFixtureDef = FixtureDef(middleCurveShape); final bottomCurveShape = BezierCurveShape( controlPoints: [ middleCurveShape.vertices.last, - Vector2(23, -15), - Vector2(27, -15), + Vector2(23, -14.2), + Vector2(27, -14.2), ], ); - final bottomCurveFixtureDef = FixtureDef(bottomCurveShape); final bottomStraightShape = EdgeShape() ..set( bottomCurveShape.vertices.last, - Vector2(31, -14.5), + Vector2(31, -13.7), ); - final bottomStraightFixtureDef = FixtureDef(bottomStraightShape); return [ - topStraightFixtureDef, - topCurveFixtureDef, - middleCurveFixtureDef, - bottomCurveFixtureDef, - bottomStraightFixtureDef, + FixtureDef(topStraightShape), + FixtureDef(topCurveShape), + FixtureDef(middleCurveShape), + FixtureDef(bottomCurveShape), + FixtureDef(bottomStraightShape), ]; } @@ -109,12 +104,12 @@ class _DinoTopWallSpriteComponent extends SpriteComponent with HasGameRef { await super.onLoad(); final sprite = Sprite( gameRef.images.fromCache( - Assets.images.dino.dinoLandTop.keyName, + Assets.images.dino.topWall.keyName, ), ); this.sprite = sprite; size = sprite.originalSize / 10; - position = Vector2(22.8, -38.9); + position = Vector2(22.8, -38.1); } } @@ -131,17 +126,11 @@ class _DinoBottomWall extends BodyComponent with InitialPosition { ); List _createFixtureDefs() { - const restitution = 1.0; - final topStraightShape = EdgeShape() ..set( Vector2(32.4, -8.8), Vector2(25, -7.7), ); - final topStraightFixtureDef = FixtureDef( - topStraightShape, - restitution: restitution, - ); final topLeftCurveShape = BezierCurveShape( controlPoints: [ @@ -150,36 +139,24 @@ class _DinoBottomWall extends BodyComponent with InitialPosition { Vector2(29.8, 13.8), ], ); - final topLeftCurveFixtureDef = FixtureDef( - topLeftCurveShape, - restitution: restitution, - ); final bottomLeftStraightShape = EdgeShape() ..set( topLeftCurveShape.vertices.last, Vector2(31.9, 44.1), ); - final bottomLeftStraightFixtureDef = FixtureDef( - bottomLeftStraightShape, - restitution: restitution, - ); final bottomStraightShape = EdgeShape() ..set( bottomLeftStraightShape.vertex2, Vector2(37.8, 44.1), ); - final bottomStraightFixtureDef = FixtureDef( - bottomStraightShape, - restitution: restitution, - ); return [ - topStraightFixtureDef, - topLeftCurveFixtureDef, - bottomLeftStraightFixtureDef, - bottomStraightFixtureDef, + FixtureDef(topStraightShape), + FixtureDef(topLeftCurveShape), + FixtureDef(bottomLeftStraightShape), + FixtureDef(bottomStraightShape), ]; } @@ -203,11 +180,11 @@ class _DinoBottomWallSpriteComponent extends SpriteComponent with HasGameRef { await super.onLoad(); final sprite = Sprite( gameRef.images.fromCache( - Assets.images.dino.dinoLandBottom.keyName, + Assets.images.dino.bottomWall.keyName, ), ); this.sprite = sprite; size = sprite.originalSize / 10; - position = Vector2(23.6, -9.5); + position = Vector2(23.8, -9.5); } } diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 9d043e9a..c260b626 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -50,6 +50,7 @@ flutter: - assets/images/baseboard/ - assets/images/boundary/ - assets/images/dino/ + - assets/images/dino/animatronic/ - assets/images/flipper/ - assets/images/launch_ramp/ - assets/images/dash/ @@ -60,7 +61,6 @@ flutter: - assets/images/spaceship/rail/ - assets/images/spaceship/ramp/ - assets/images/spaceship/ramp/arrow/ - - assets/images/chrome_dino/ - assets/images/kicker/ - assets/images/plunger/ - assets/images/slingshot/ diff --git a/packages/pinball_components/sandbox/lib/stories/chrome_dino/chrome_dino_game.dart b/packages/pinball_components/sandbox/lib/stories/chrome_dino/chrome_dino_game.dart index 2e6831e3..d6e7ef95 100644 --- a/packages/pinball_components/sandbox/lib/stories/chrome_dino/chrome_dino_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/chrome_dino/chrome_dino_game.dart @@ -1,8 +1,22 @@ import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/stories/ball/basic_ball_game.dart'; -class ChromeDinoGame extends Forge2DGame { - static const description = 'Shows how a ChromeDino is rendered.'; +class ChromeDinoGame extends BallGame { + ChromeDinoGame() + : super( + imagesFileNames: [ + Assets.images.dino.animatronic.mouth.keyName, + Assets.images.dino.animatronic.head.keyName, + ], + ); + + static const description = ''' + Shows how ChromeDino is rendered. + + - Activate the "trace" parameter to overlay the body. + - Tap anywhere on the screen to spawn a ball into the game. +'''; @override Future onLoad() async { @@ -10,5 +24,7 @@ class ChromeDinoGame extends Forge2DGame { camera.followVector2(Vector2.zero()); await add(ChromeDino()); + + await traceAllBodies(); } } diff --git a/packages/pinball_components/sandbox/lib/stories/chrome_dino/stories.dart b/packages/pinball_components/sandbox/lib/stories/chrome_dino/stories.dart index 391cdca7..a4c70c03 100644 --- a/packages/pinball_components/sandbox/lib/stories/chrome_dino/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/chrome_dino/stories.dart @@ -4,7 +4,7 @@ import 'package:sandbox/stories/chrome_dino/chrome_dino_game.dart'; void addChromeDinoStories(Dashbook dashbook) { dashbook.storiesOf('Chrome Dino').addGame( - title: 'Trace', + title: 'Traced', description: ChromeDinoGame.description, gameBuilder: (_) => ChromeDinoGame(), ); diff --git a/packages/pinball_components/sandbox/lib/stories/dino_wall/dino_wall_game.dart b/packages/pinball_components/sandbox/lib/stories/dino_wall/dino_wall_game.dart index b491d64b..a6987fcc 100644 --- a/packages/pinball_components/sandbox/lib/stories/dino_wall/dino_wall_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/dino_wall/dino_wall_game.dart @@ -20,8 +20,8 @@ class DinoWallGame extends BallGame { await super.onLoad(); await images.loadAll([ - Assets.images.dino.dinoLandTop.keyName, - Assets.images.dino.dinoLandBottom.keyName, + Assets.images.dino.topWall.keyName, + Assets.images.dino.bottomWall.keyName, ]); await addFromBlueprint(DinoWalls()); diff --git a/packages/pinball_components/test/src/components/chrome_dino_test.dart b/packages/pinball_components/test/src/components/chrome_dino_test.dart index 8a0adb85..f97270b9 100644 --- a/packages/pinball_components/test/src/components/chrome_dino_test.dart +++ b/packages/pinball_components/test/src/components/chrome_dino_test.dart @@ -1,13 +1,19 @@ // ignore_for_file: cascade_invocations -import 'package:flame_forge2d/flame_forge2d.dart'; +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() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(Forge2DGame.new); + final assets = [ + Assets.images.dino.animatronic.mouth.keyName, + Assets.images.dino.animatronic.head.keyName, + ]; + final flameTester = FlameTester(() => TestGame(assets)); group('ChromeDino', () { flameTester.test( @@ -20,19 +26,84 @@ void main() { }, ); - flameTester.test( - 'swivels', - (game) async { - // TODO(alestiago): Write golden tests to check the - // swivel animation. - final chromeDino = ChromeDino(); - await game.ensureAdd(chromeDino); + flameTester.testGameWidget( + 'renders correctly', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd(ChromeDino()); + game.camera.followVector2(Vector2.zero()); + await tester.pump(); + }, + verify: (game, tester) async { + final sweepAnimationDuration = game + .descendants() + .whereType() + .first + .animation! + .totalDuration() / + 2; + + await expectLater( + find.byGame(), + matchesGoldenFile('golden/chrome_dino/up.png'), + ); - final previousPosition = chromeDino.body.position.clone(); - game.update(64); + game.update(sweepAnimationDuration * 0.25); + await tester.pump(); + await expectLater( + find.byGame(), + matchesGoldenFile('golden/chrome_dino/middle.png'), + ); - expect(chromeDino.body.position, isNot(equals(previousPosition))); + game.update(sweepAnimationDuration * 0.25); + await tester.pump(); + await expectLater( + find.byGame(), + matchesGoldenFile('golden/chrome_dino/down.png'), + ); }, ); + + group('swivels', () { + flameTester.test( + 'up', + (game) async { + final chromeDino = ChromeDino(); + await game.ensureAdd(chromeDino); + game.camera.followVector2(Vector2.zero()); + + final sweepAnimationDuration = game + .descendants() + .whereType() + .first + .animation! + .totalDuration() / + 2; + game.update(sweepAnimationDuration * 1.5); + + expect(chromeDino.body.angularVelocity, isPositive); + }, + ); + + flameTester.test( + 'down', + (game) async { + final chromeDino = ChromeDino(); + await game.ensureAdd(chromeDino); + game.camera.followVector2(Vector2.zero()); + + final sweepAnimationDuration = game + .descendants() + .whereType() + .first + .animation! + .totalDuration() / + 2; + game.update(sweepAnimationDuration * 0.5); + + expect(chromeDino.body.angularVelocity, isNegative); + }, + ); + }); }); } diff --git a/packages/pinball_components/test/src/components/dash_animatronic_test.dart b/packages/pinball_components/test/src/components/dash_animatronic_test.dart index d0707223..d64c3f07 100644 --- a/packages/pinball_components/test/src/components/dash_animatronic_test.dart +++ b/packages/pinball_components/test/src/components/dash_animatronic_test.dart @@ -45,6 +45,7 @@ void main() { ); }, ); + flameTester.test( 'loads correctly', (game) async { diff --git a/packages/pinball_components/test/src/components/dino_walls_test.dart b/packages/pinball_components/test/src/components/dino_walls_test.dart index 7ed97248..ff64fb00 100644 --- a/packages/pinball_components/test/src/components/dino_walls_test.dart +++ b/packages/pinball_components/test/src/components/dino_walls_test.dart @@ -12,8 +12,8 @@ void main() { group('DinoWalls', () { TestWidgetsFlutterBinding.ensureInitialized(); final assets = [ - Assets.images.dino.dinoLandTop.keyName, - Assets.images.dino.dinoLandBottom.keyName, + Assets.images.dino.topWall.keyName, + Assets.images.dino.bottomWall.keyName, ]; final flameTester = FlameTester(() => TestGame(assets)); diff --git a/packages/pinball_components/test/src/components/golden/boundaries.png b/packages/pinball_components/test/src/components/golden/boundaries.png index 01afebd0..9e9b5633 100644 Binary files a/packages/pinball_components/test/src/components/golden/boundaries.png and b/packages/pinball_components/test/src/components/golden/boundaries.png differ diff --git a/packages/pinball_components/test/src/components/golden/chrome_dino/down.png b/packages/pinball_components/test/src/components/golden/chrome_dino/down.png new file mode 100644 index 00000000..ef91da0a Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/chrome_dino/down.png differ diff --git a/packages/pinball_components/test/src/components/golden/chrome_dino/middle.png b/packages/pinball_components/test/src/components/golden/chrome_dino/middle.png new file mode 100644 index 00000000..d4e6286a Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/chrome_dino/middle.png differ diff --git a/packages/pinball_components/test/src/components/golden/chrome_dino/up.png b/packages/pinball_components/test/src/components/golden/chrome_dino/up.png new file mode 100644 index 00000000..042028d1 Binary files /dev/null and b/packages/pinball_components/test/src/components/golden/chrome_dino/up.png differ diff --git a/packages/pinball_components/test/src/components/golden/dino-walls.png b/packages/pinball_components/test/src/components/golden/dino-walls.png index 5956b43b..b47c453f 100644 Binary files a/packages/pinball_components/test/src/components/golden/dino-walls.png and b/packages/pinball_components/test/src/components/golden/dino-walls.png differ diff --git a/test/game/components/board_test.dart b/test/game/components/board_test.dart index a73d7a50..63b7251b 100644 --- a/test/game/components/board_test.dart +++ b/test/game/components/board_test.dart @@ -105,18 +105,6 @@ void main() { expect(flutterForest.length, equals(1)); }, ); - - flameTester.test( - 'one ChromeDino', - (game) async { - final board = Board(); - await game.ready(); - await game.ensureAdd(board); - - final chromeDino = board.descendants().whereType(); - expect(chromeDino.length, equals(1)); - }, - ); }); }); } diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index 65f24ea2..2fdbe6c4 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -27,10 +27,10 @@ void main() { Assets.images.boundary.bottom.keyName, Assets.images.boundary.outer.keyName, Assets.images.boundary.outerBottom.keyName, - Assets.images.chromeDino.mouth.keyName, - Assets.images.chromeDino.head.keyName, - Assets.images.dino.dinoLandTop.keyName, - Assets.images.dino.dinoLandBottom.keyName, + Assets.images.dino.animatronic.mouth.keyName, + Assets.images.dino.animatronic.head.keyName, + Assets.images.dino.topWall.keyName, + Assets.images.dino.bottomWall.keyName, Assets.images.dash.animatronic.keyName, Assets.images.dash.bumper.a.active.keyName, Assets.images.dash.bumper.a.inactive.keyName,