From 2f40dcc971ffae367817bd7ec75912ee2bc8d9d5 Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Wed, 6 Apr 2022 13:22:38 -0500 Subject: [PATCH] feat: add slingshots (#148) * feat: add slingshots * test: slingshot * feat: add slingshot to sandbox * chore: add todo --- lib/game/game_assets.dart | 4 + lib/game/pinball_game.dart | 1 + .../assets/images/slingshot/left_lower.png | Bin 0 -> 6458 bytes .../assets/images/slingshot/left_upper.png | Bin 0 -> 6061 bytes .../assets/images/slingshot/right_lower.png | Bin 0 -> 6542 bytes .../assets/images/slingshot/right_upper.png | Bin 0 -> 6002 bytes .../lib/gen/assets.gen.dart | 21 +++ .../lib/src/components/components.dart | 1 + .../lib/src/components/slingshot.dart | 138 ++++++++++++++++++ packages/pinball_components/pubspec.yaml | 1 + .../pinball_components/sandbox/lib/main.dart | 1 + .../lib/stories/slingshot/slingshot_game.dart | 66 +++++++++ .../lib/stories/slingshot/stories.dart | 17 +++ .../sandbox/lib/stories/stories.dart | 1 + .../test/src/components/golden/slingshots.png | Bin 0 -> 49944 bytes .../test/src/components/slingshot_test.dart | 97 ++++++++++++ 16 files changed, 348 insertions(+) create mode 100644 packages/pinball_components/assets/images/slingshot/left_lower.png create mode 100644 packages/pinball_components/assets/images/slingshot/left_upper.png create mode 100644 packages/pinball_components/assets/images/slingshot/right_lower.png create mode 100644 packages/pinball_components/assets/images/slingshot/right_upper.png create mode 100644 packages/pinball_components/lib/src/components/slingshot.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart create mode 100644 packages/pinball_components/test/src/components/golden/slingshots.png create mode 100644 packages/pinball_components/test/src/components/slingshot_test.dart diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 47175c32..050b2cd3 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -15,6 +15,10 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.baseboard.right.keyName), images.load(components.Assets.images.kicker.left.keyName), images.load(components.Assets.images.kicker.right.keyName), + images.load(components.Assets.images.slingshot.leftUpper.keyName), + images.load(components.Assets.images.slingshot.leftLower.keyName), + images.load(components.Assets.images.slingshot.rightUpper.keyName), + images.load(components.Assets.images.slingshot.rightLower.keyName), images.load(components.Assets.images.launchRamp.ramp.keyName), images.load( components.Assets.images.launchRamp.foregroundRailing.keyName, diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 7a0e6823..2ccf8fe8 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -46,6 +46,7 @@ class PinballGame extends Forge2DGame await add(plunger); unawaited(add(Board())); + unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(DinoWalls())); unawaited(_addBonusWord()); unawaited(addFromBlueprint(SpaceshipRamp())); diff --git a/packages/pinball_components/assets/images/slingshot/left_lower.png b/packages/pinball_components/assets/images/slingshot/left_lower.png new file mode 100644 index 0000000000000000000000000000000000000000..b44b58fbca8025771379cb8ac421e789a896c9ee GIT binary patch literal 6458 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 OAs7vVn>A{7k^cjqC8WIo literal 0 HcmV?d00001 diff --git a/packages/pinball_components/assets/images/slingshot/right_lower.png b/packages/pinball_components/assets/images/slingshot/right_lower.png new file mode 100644 index 0000000000000000000000000000000000000000..71a6a277828fd5d0f99dc5cae819e067e5d3df90 GIT binary patch literal 6542 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 UBvxtz{=tIK(=yU5*KmmXA3&?lwg3PC literal 0 HcmV?d00001 diff --git a/packages/pinball_components/assets/images/slingshot/right_upper.png b/packages/pinball_components/assets/images/slingshot/right_upper.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b42ded4f2a513501042baaba58a1a7174ac402 GIT binary patch literal 6002 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 F{|64fsRRH3 literal 0 HcmV?d00001 diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index de59219e..518d3237 100644 --- a/packages/pinball_components/lib/gen/assets.gen.dart +++ b/packages/pinball_components/lib/gen/assets.gen.dart @@ -29,6 +29,7 @@ class $AssetsImagesGen { $AssetsImagesKickerGen get kicker => const $AssetsImagesKickerGen(); $AssetsImagesLaunchRampGen get launchRamp => const $AssetsImagesLaunchRampGen(); + $AssetsImagesSlingshotGen get slingshot => const $AssetsImagesSlingshotGen(); $AssetsImagesSpaceshipGen get spaceship => const $AssetsImagesSpaceshipGen(); $AssetsImagesSparkyBumperGen get sparkyBumper => const $AssetsImagesSparkyBumperGen(); @@ -127,6 +128,26 @@ class $AssetsImagesLaunchRampGen { const AssetGenImage('assets/images/launch_ramp/ramp.png'); } +class $AssetsImagesSlingshotGen { + const $AssetsImagesSlingshotGen(); + + /// File path: assets/images/slingshot/left_lower.png + AssetGenImage get leftLower => + const AssetGenImage('assets/images/slingshot/left_lower.png'); + + /// File path: assets/images/slingshot/left_upper.png + AssetGenImage get leftUpper => + const AssetGenImage('assets/images/slingshot/left_upper.png'); + + /// File path: assets/images/slingshot/right_lower.png + AssetGenImage get rightLower => + const AssetGenImage('assets/images/slingshot/right_lower.png'); + + /// File path: assets/images/slingshot/right_upper.png + AssetGenImage get rightUpper => + const AssetGenImage('assets/images/slingshot/right_upper.png'); +} + class $AssetsImagesSpaceshipGen { const $AssetsImagesSpaceshipGen(); diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 6b0c2ef5..14d657d5 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -16,6 +16,7 @@ export 'launch_ramp.dart'; export 'layer.dart'; export 'ramp_opening.dart'; export 'shapes/shapes.dart'; +export 'slingshot.dart'; export 'spaceship.dart'; export 'spaceship_rail.dart'; export 'spaceship_ramp.dart'; diff --git a/packages/pinball_components/lib/src/components/slingshot.dart b/packages/pinball_components/lib/src/components/slingshot.dart new file mode 100644 index 00000000..0ebe13ce --- /dev/null +++ b/packages/pinball_components/lib/src/components/slingshot.dart @@ -0,0 +1,138 @@ +// ignore_for_file: avoid_renaming_method_parameters + +import 'dart:math' as math; + +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball_components/pinball_components.dart'; + +/// {@template slingshots} +/// A [Blueprint] which creates the left and right pairs of [Slingshot]s. +/// {@endtemplate} +class Slingshots extends Forge2DBlueprint { + @override + void build(_) { + // TODO(allisonryan0002): use radians values instead of converting degrees. + final leftUpperSlingshot = Slingshot( + length: 5.66, + angle: -1.5 * (math.pi / 180), + spritePath: Assets.images.slingshot.leftUpper.keyName, + )..initialPosition = Vector2(-29, 1.5); + + final leftLowerSlingshot = Slingshot( + length: 3.54, + angle: -29.1 * (math.pi / 180), + spritePath: Assets.images.slingshot.leftLower.keyName, + )..initialPosition = Vector2(-31, -6.2); + + final rightUpperSlingshot = Slingshot( + length: 5.64, + angle: 1 * (math.pi / 180), + spritePath: Assets.images.slingshot.rightUpper.keyName, + )..initialPosition = Vector2(22.3, 1.58); + + final rightLowerSlingshot = Slingshot( + length: 3.46, + angle: 26.8 * (math.pi / 180), + spritePath: Assets.images.slingshot.rightLower.keyName, + )..initialPosition = Vector2(24.7, -6.2); + + addAll([ + leftUpperSlingshot, + leftLowerSlingshot, + rightUpperSlingshot, + rightLowerSlingshot, + ]); + } +} + +/// {@template slingshot} +/// Elastic bumper that bounces the [Ball] off of its straight sides. +/// {@endtemplate} +class Slingshot extends BodyComponent with InitialPosition { + /// {@macro slingshot} + Slingshot({ + required double length, + required double angle, + required String spritePath, + }) : _length = length, + _angle = angle, + _spritePath = spritePath, + super(priority: 1); + + final double _length; + + final double _angle; + + final String _spritePath; + + List _createFixtureDefs() { + final fixturesDef = []; + const circleRadius = 1.55; + + final topCircleShape = CircleShape()..radius = circleRadius; + topCircleShape.position.setValues(0, _length / 2); + final topCircleFixtureDef = FixtureDef(topCircleShape)..friction = 0; + fixturesDef.add(topCircleFixtureDef); + + final bottomCircleShape = CircleShape()..radius = circleRadius; + bottomCircleShape.position.setValues(0, -_length / 2); + final bottomCircleFixtureDef = FixtureDef(bottomCircleShape)..friction = 0; + fixturesDef.add(bottomCircleFixtureDef); + + final leftEdgeShape = EdgeShape() + ..set( + Vector2(circleRadius, _length / 2), + Vector2(circleRadius, -_length / 2), + ); + final leftEdgeShapeFixtureDef = FixtureDef(leftEdgeShape) + ..friction = 0 + ..restitution = 5; + fixturesDef.add(leftEdgeShapeFixtureDef); + + final rightEdgeShape = EdgeShape() + ..set( + Vector2(-circleRadius, _length / 2), + Vector2(-circleRadius, -_length / 2), + ); + final rightEdgeShapeFixtureDef = FixtureDef(rightEdgeShape) + ..friction = 0 + ..restitution = 5; + fixturesDef.add(rightEdgeShapeFixtureDef); + + return fixturesDef; + } + + @override + Body createBody() { + final bodyDef = BodyDef() + ..userData = this + ..position = initialPosition + ..angle = _angle; + + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } + + @override + Future onLoad() async { + await super.onLoad(); + await _loadSprite(); + renderBody = false; + } + + Future _loadSprite() async { + final sprite = await gameRef.loadSprite(_spritePath); + + await add( + SpriteComponent( + sprite: sprite, + size: sprite.originalSize / 10, + anchor: Anchor.center, + angle: _angle, + ), + ); + } +} diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 312e01f3..b6f71b8b 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -39,6 +39,7 @@ flutter: - assets/images/spaceship/ramp/ - assets/images/chrome_dino/ - assets/images/kicker/ + - assets/images/slingshot/ - assets/images/sparky_bumper/a/ - assets/images/sparky_bumper/b/ - assets/images/sparky_bumper/c/ diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index 88b86da6..481ca781 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -21,6 +21,7 @@ void main() { addChromeDinoStories(dashbook); addDashNestBumperStories(dashbook); addKickerStories(dashbook); + addSlingshotStories(dashbook); addSparkyBumperStories(dashbook); runApp(dashbook); } diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart new file mode 100644 index 00000000..c02689ca --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/slingshot_game.dart @@ -0,0 +1,66 @@ +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)); + + static const info = ''' + Shows how Slingshots are rendered. + + - Activate the "trace" parameter to overlay the body. + - 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(); + } + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart new file mode 100644 index 00000000..6e985d32 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/slingshot/stories.dart @@ -0,0 +1,17 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:flame/game.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/slingshot/slingshot_game.dart'; + +void addSlingshotStories(Dashbook dashbook) { + dashbook.storiesOf('Slingshots').add( + 'Basic', + (context) => GameWidget( + 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/stories.dart b/packages/pinball_components/sandbox/lib/stories/stories.dart index 746d83d6..c5d60a8d 100644 --- a/packages/pinball_components/sandbox/lib/stories/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/stories.dart @@ -5,5 +5,6 @@ export 'dash_nest_bumper/stories.dart'; export 'effects/stories.dart'; export 'flipper/stories.dart'; export 'layer/stories.dart'; +export 'slingshot/stories.dart'; export 'spaceship/stories.dart'; export 'sparky_bumper/stories.dart'; diff --git a/packages/pinball_components/test/src/components/golden/slingshots.png b/packages/pinball_components/test/src/components/golden/slingshots.png new file mode 100644 index 0000000000000000000000000000000000000000..2e4ada7b6a610b9dce69f08eabff4dc68bc8c29c GIT binary patch literal 49944 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, + // matchesGoldenFile('golden/slingshots.png'), + // ); + // }, + ); + + flameTester.test( + 'loads correctly', + (game) async { + final slingshot = Slingshot( + length: length, + angle: angle, + spritePath: spritePath, + ); + await game.ensureAdd(slingshot); + + expect(game.contains(slingshot), isTrue); + }, + ); + + flameTester.test( + 'body is static', + (game) async { + final slingshot = Slingshot( + length: length, + angle: angle, + spritePath: spritePath, + ); + await game.ensureAdd(slingshot); + + expect(slingshot.body.bodyType, equals(BodyType.static)); + }, + ); + + flameTester.test( + 'has restitution', + (game) async { + final slingshot = Slingshot( + length: length, + angle: angle, + spritePath: spritePath, + ); + await game.ensureAdd(slingshot); + + final totalRestitution = slingshot.body.fixtures.fold( + 0, + (total, fixture) => total + fixture.restitution, + ); + expect(totalRestitution, greaterThan(0)); + }, + ); + + flameTester.test( + 'has no friction', + (game) async { + final slingshot = Slingshot( + length: length, + angle: angle, + spritePath: spritePath, + ); + await game.ensureAdd(slingshot); + + final totalFriction = slingshot.body.fixtures.fold( + 0, + (total, fixture) => total + fixture.friction, + ); + expect(totalFriction, equals(0)); + }, + ); + }); +}