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 1fa99b8c..660269fd 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -39,6 +39,7 @@ class PinballGame extends Forge2DGame unawaited(addFromBlueprint(LaunchRamp())); unawaited(_addPlunger()); 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 00000000..b44b58fb Binary files /dev/null and b/packages/pinball_components/assets/images/slingshot/left_lower.png differ diff --git a/packages/pinball_components/assets/images/slingshot/left_upper.png b/packages/pinball_components/assets/images/slingshot/left_upper.png new file mode 100644 index 00000000..c74267ca Binary files /dev/null and b/packages/pinball_components/assets/images/slingshot/left_upper.png differ 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 00000000..71a6a277 Binary files /dev/null and b/packages/pinball_components/assets/images/slingshot/right_lower.png differ 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 00000000..e6b42ded Binary files /dev/null and b/packages/pinball_components/assets/images/slingshot/right_upper.png differ diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index 154930bc..6fe4d75f 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(); } @@ -125,6 +126,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 bf578ea7..1caf2aab 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..52bcf318 --- /dev/null +++ b/packages/pinball_components/lib/src/components/slingshot.dart @@ -0,0 +1,131 @@ +// 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(_) { + 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); + fixturesDef.add(topCircleFixtureDef); + + final bottomCircleShape = CircleShape()..radius = circleRadius; + bottomCircleShape.position.setValues(0, -_length / 2); + final bottomCircleFixtureDef = FixtureDef(bottomCircleShape); + fixturesDef.add(bottomCircleFixtureDef); + + final leftEdgeShape = EdgeShape() + ..set( + Vector2(circleRadius, _length / 2), + Vector2(circleRadius, -_length / 2), + ); + final leftEdgeShapeFixtureDef = FixtureDef(leftEdgeShape)..restitution = 5; + fixturesDef.add(leftEdgeShapeFixtureDef); + + final righttEdgeShape = EdgeShape() + ..set( + Vector2(-circleRadius, _length / 2), + Vector2(-circleRadius, -_length / 2), + ); + final righttEdgeShapeFixtureDef = FixtureDef(righttEdgeShape) + ..restitution = 5; + fixturesDef.add(righttEdgeShapeFixtureDef); + + 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 c7302d0d..68141623 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/ flutter_gen: line_length: 80