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 16b09d3a..2f411bc3 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), @@ -80,8 +82,6 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.alienBumper.a.inactive.keyName), images.load(components.Assets.images.alienBumper.b.active.keyName), images.load(components.Assets.images.alienBumper.b.inactive.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 1bac998a..603991a7 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -58,6 +58,7 @@ class PinballGame extends Forge2DGame await addFromBlueprint(SparkyFireZone()); unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(DinoWalls())); + await add(ChromeDino()..initialPosition = Vector2(24.2, -14.1)); unawaited(_addBonusWord()); unawaited(addFromBlueprint(SpaceshipRamp())); unawaited( diff --git a/packages/pinball_components/assets/images/chrome_dino/head.png b/packages/pinball_components/assets/images/dino/animatronic/head.png similarity index 100% rename from packages/pinball_components/assets/images/chrome_dino/head.png rename to packages/pinball_components/assets/images/dino/animatronic/head.png diff --git a/packages/pinball_components/assets/images/chrome_dino/mouth.png b/packages/pinball_components/assets/images/dino/animatronic/mouth.png similarity index 100% rename from packages/pinball_components/assets/images/chrome_dino/mouth.png rename to packages/pinball_components/assets/images/dino/animatronic/mouth.png 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 558d36a1..f23029ee 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(); @@ -91,18 +89,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(); @@ -116,13 +102,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 { @@ -298,6 +287,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/chrome_dino.dart b/packages/pinball_components/lib/src/components/chrome_dino.dart index 6cc2ddf6..337cb2df 100644 --- a/packages/pinball_components/lib/src/components/chrome_dino.dart +++ b/packages/pinball_components/lib/src/components/chrome_dino.dart @@ -1,26 +1,23 @@ 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, - ); + ChromeDino() : super(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. @@ -42,60 +39,30 @@ class ChromeDino extends BodyComponent with InitialPosition { Future onLoad() async { await super.onLoad(); final joint = await _anchorToJoint(); - await addAll( - [ - TimerComponent( - period: 1, - onTick: joint._swivel, - repeat: true, - ), - _ChromeDinoMouthSprite(), - _ChromeDinoHeadSprite(), - ], + await add( + TimerComponent( + period: 98 / 48, + onTick: joint._swivel, + repeat: true, + ), ); + joint._swivel(); } 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 to match sprite. + final box = PolygonShape() + ..setAsBox( + size.x / 2, + size.y / 2, + initialPosition + Vector2(-4, 2), + -0.1143, + ); + 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; } @@ -115,12 +82,22 @@ class ChromeDino extends BodyComponent with InitialPosition { } /// {@template flipper_anchor} -/// [JointAnchor] positioned at the end of a [ChromeDino]. +/// [JointAnchor] positioned at the back of the [ChromeDino]. /// {@endtemplate} class _ChromeDinoAnchor extends JointAnchor { /// {@macro flipper_anchor} _ChromeDinoAnchor() { - initialPosition = Vector2(9, 0); + initialPosition = Vector2(9, -4); + } + + @override + Future onLoad() async { + const spriteAngle = 0.1143; + await super.onLoad(); + await addAll([ + _ChromeDinoMouthSprite()..angle = spriteAngle, + _ChromeDinoHeadSprite()..angle = spriteAngle, + ]); } } @@ -139,20 +116,22 @@ 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; + const angle = 0.1143; + lowerAngle = -angle; + upperAngle = angle; 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); + /// Half the angle of the arc motion. + // static const _halfSweepingAngle = 0.1143; + /// Sweeps the [ChromeDino] up and down repeatedly. void _swivel() { setMotorSpeed(-motorSpeed); @@ -160,16 +139,18 @@ class _ChromeDinoJoint extends RevoluteJoint { } class _ChromeDinoMouthSprite extends SpriteAnimationComponent with HasGameRef { + _ChromeDinoMouthSprite() + : super( + anchor: Anchor(Anchor.center.x + 0.47, Anchor.center.y - 0.29), + ); + @override Future onLoad() async { await super.onLoad(); - final image = await gameRef.images.load( - Assets.images.chromeDino.mouth.keyName, + final image = gameRef.images.fromCache( + Assets.images.dino.animatronic.mouth.keyName, ); - position = Vector2(0, -2); - anchor = Anchor.center; - const amountPerRow = 11; const amountPerColumn = 9; final textureSize = Vector2( @@ -181,24 +162,26 @@ class _ChromeDinoMouthSprite extends SpriteAnimationComponent with HasGameRef { final data = SpriteAnimationData.sequenced( amount: (amountPerColumn * amountPerRow) - 1, amountPerRow: amountPerRow, - stepTime: 0.1, + stepTime: 1 / 24, textureSize: textureSize, ); - animation = SpriteAnimation.fromFrameData(image, data); + animation = SpriteAnimation.fromFrameData(image, data)..currentIndex = 95; } } class _ChromeDinoHeadSprite extends SpriteAnimationComponent with HasGameRef { + _ChromeDinoHeadSprite() + : super( + anchor: Anchor(Anchor.center.x + 0.47, Anchor.center.y - 0.29), + ); + @override Future onLoad() async { await super.onLoad(); - final image = await gameRef.images.load( - Assets.images.chromeDino.head.keyName, + final image = gameRef.images.fromCache( + Assets.images.dino.animatronic.head.keyName, ); - position = Vector2(0, -2); - anchor = Anchor.center; - const amountPerRow = 11; const amountPerColumn = 9; final textureSize = Vector2( @@ -210,9 +193,9 @@ class _ChromeDinoHeadSprite extends SpriteAnimationComponent with HasGameRef { final data = SpriteAnimationData.sequenced( amount: (amountPerColumn * amountPerRow) - 1, amountPerRow: amountPerRow, - stepTime: 0.1, + stepTime: 1 / 24, textureSize: textureSize, ); - animation = SpriteAnimation.fromFrameData(image, data); + animation = SpriteAnimation.fromFrameData(image, data)..currentIndex = 95; } } diff --git a/packages/pinball_components/lib/src/components/dino_walls.dart b/packages/pinball_components/lib/src/components/dino_walls.dart index 9ce5a523..ca748799 100644 --- a/packages/pinball_components/lib/src/components/dino_walls.dart +++ b/packages/pinball_components/lib/src/components/dino_walls.dart @@ -107,7 +107,7 @@ class _DinoTopWallSpriteComponent extends SpriteComponent with HasGameRef { Future onLoad() async { await super.onLoad(); final sprite = await gameRef.loadSprite( - Assets.images.dino.dinoLandTop.keyName, + Assets.images.dino.topWall.keyName, ); this.sprite = sprite; size = sprite.originalSize / 10; @@ -213,7 +213,7 @@ class _DinoBottomWallSpriteComponent extends SpriteComponent with HasGameRef { Future onLoad() async { await super.onLoad(); final sprite = await gameRef.loadSprite( - Assets.images.dino.dinoLandBottom.keyName, + Assets.images.dino.bottomWall.keyName, ); this.sprite = sprite; size = sprite.originalSize / 10; diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index a7cb8367..055d8e99 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -45,6 +45,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/ @@ -55,7 +56,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 89422019..065761ea 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 @@ -9,6 +9,11 @@ class ChromeDinoGame extends BasicGame with Traceable { Future onLoad() async { await super.onLoad(); + await images.loadAll([ + Assets.images.dino.animatronic.mouth.keyName, + Assets.images.dino.animatronic.head.keyName, + ]); + camera.followVector2(Vector2.zero()); await add(ChromeDino());