From 4e2598c2b3d9a7e7ca0012af70054c1dedeee130 Mon Sep 17 00:00:00 2001 From: RuiAlonso Date: Thu, 24 Mar 2022 18:26:32 +0100 Subject: [PATCH] refactor: launcher ramp --- lib/game/components/jetpack_ramp.dart | 1 - lib/game/components/launcher_ramp.dart | 168 +++++++++++++++++++------ lib/game/pinball_game.dart | 12 +- 3 files changed, 128 insertions(+), 53 deletions(-) diff --git a/lib/game/components/jetpack_ramp.dart b/lib/game/components/jetpack_ramp.dart index 5cd16347..67c53c35 100644 --- a/lib/game/components/jetpack_ramp.dart +++ b/lib/game/components/jetpack_ramp.dart @@ -2,7 +2,6 @@ import 'dart:math' as math; -import 'package:flame/components.dart'; import 'package:flame/extensions.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index aae9265f..f9d3f36e 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -1,62 +1,49 @@ +// ignore_for_file: public_member_api_docs + import 'dart:math' as math; -import 'package:flame/components.dart'; import 'package:flame/extensions.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flutter/material.dart'; +import 'package:pinball/flame/blueprint.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; -/// {@template launcher_ramp} -/// The yellow left ramp, where the [Ball] goes through when launched from the -/// [Plunger]. -/// {@endtemplate} -class LauncherRamp extends Component with HasGameRef { - /// {@macro launcher_ramp} - LauncherRamp({ - required this.position, - }); +/// A [Blueprint] which creates the [LauncherRamp]. +class Launcher extends Forge2DBlueprint { + /// Width between walls of the [Pathway]. + static const width = 5.0; - /// The position of this [LauncherRamp]. - final Vector2 position; + /// Size for the radius of the external wall [Pathway]. + static const externalRadius = 16.3; @override - Future onLoad() async { - const layer = Layer.launcher; + void build(_) { + final position = Vector2( + PinballGame.boardBounds.right - 30, + PinballGame.boardBounds.bottom + 40, + ); - gameRef.addContactCallback( + addAllContactCallback([ RampOpeningBallContactCallback<_LauncherRampOpening>(), - ); + ]); - final launcherRampRotation = - -math.atan(18.6 / PinballGame.boardBounds.height); + final straightPath = LauncherStraightRamp() + ..initialPosition = position + Vector2(1.7, 0) + ..layer = Layer.launcher; - final straightPath = Pathway.straight( - color: const Color.fromARGB(255, 34, 255, 0), - start: position + Vector2(-1.2, 10), - end: position + Vector2(-1.2, 117), - width: 5, - rotation: launcherRampRotation, - ) - ..initialPosition = position - ..layer = layer; - - final curvedPath = Pathway.arc( - color: const Color.fromARGB(255, 251, 255, 0), - center: position + Vector2(-2.8, 87.2), - radius: 16.3, - angle: math.pi / 2, - width: 5, - rotation: 3 * math.pi / 2, - )..layer = layer; + final curvedPath = LauncherCurveRamp() + ..initialPosition = position + Vector2(-12, 59.3) + ..layer = Layer.launcher; final leftOpening = _LauncherRampOpening(rotation: math.pi / 2) - ..initialPosition = position + Vector2(-11.8, 66.3) + ..initialPosition = position + Vector2(-11.6, 66.3) ..layer = Layer.opening; final rightOpening = _LauncherRampOpening(rotation: 0) ..initialPosition = position + Vector2(-4.9, 59.4) ..layer = Layer.opening; - await addAll([ + addAll([ straightPath, curvedPath, leftOpening, @@ -65,6 +52,107 @@ class LauncherRamp extends Component with HasGameRef { } } +/// {@template launcher_straight_ramp} +/// The green left ramp, where the [Ball] goes through when launched from the +/// [Plunger]. +/// {@endtemplate} +class LauncherStraightRamp extends BodyComponent with InitialPosition, Layered { + /// {@macro launcher_straight_ramp} + LauncherStraightRamp() : super(priority: 2) { + layer = Layer.launcher; + paint = Paint() + ..color = const Color.fromARGB(255, 34, 255, 0) + ..style = PaintingStyle.stroke; + } + + List _createFixtureDefs() { + final fixturesDef = []; + + final launcherRampRotation = + -math.atan(18.6 / PinballGame.boardBounds.height); + + final startPosition = initialPosition + Vector2(0, 3); + final endPosition = initialPosition + Vector2(0, 117); + + final externalStraightShape = EdgeShape() + ..set( + startPosition..rotate(launcherRampRotation), + endPosition..rotate(launcherRampRotation), + ); + final externalStraightFixtureDef = FixtureDef(externalStraightShape); + fixturesDef.add(externalStraightFixtureDef); + + final internalStraightShape = EdgeShape() + ..set( + startPosition - Vector2(Launcher.width, 0), + endPosition - Vector2(Launcher.width, 0), + ); + final internalStraightFixtureDef = FixtureDef(internalStraightShape); + fixturesDef.add(internalStraightFixtureDef); + + return fixturesDef; + } + + @override + Body createBody() { + final bodyDef = BodyDef() + ..userData = this + ..position = initialPosition; + + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } +} + +/// {@template launcher_curve_ramp} +/// The yellow left ramp, where the [Ball] goes through when launched from the +/// [Plunger]. +/// {@endtemplate} +class LauncherCurveRamp extends BodyComponent with InitialPosition, Layered { + /// {@macro launcher_curve_ramp} + LauncherCurveRamp() : super(priority: 2) { + layer = Layer.launcher; + paint = Paint() + ..color = const Color.fromARGB(255, 251, 255, 0) + ..style = PaintingStyle.stroke; + } + + List _createFixtureDefs() { + final fixturesDef = []; + + final externalCurveShape = ArcShape( + center: initialPosition, + arcRadius: Launcher.externalRadius, + angle: math.pi / 2, + rotation: 3 * math.pi / 2, + ); + final externalCurveFixtureDef = FixtureDef(externalCurveShape); + fixturesDef.add(externalCurveFixtureDef); + + final internalCurveShape = externalCurveShape.copyWith( + arcRadius: Launcher.externalRadius - Launcher.width, + ); + final internalCurveFixtureDef = FixtureDef(internalCurveShape); + fixturesDef.add(internalCurveFixtureDef); + + return fixturesDef; + } + + @override + Body createBody() { + final bodyDef = BodyDef() + ..userData = this + ..position = initialPosition; + + final body = world.createBody(bodyDef); + _createFixtureDefs().forEach(body.createFixture); + + return body; + } +} + /// {@template launcher_ramp_opening} /// [RampOpening] with [Layer.launcher] to filter [Ball]s collisions /// inside [LauncherRamp]. @@ -81,9 +169,7 @@ class _LauncherRampOpening extends RampOpening { final double _rotation; - // TODO(ruialonso): Avoid magic number 3, should be propotional to - // [JetpackRamp]. - static final Vector2 _size = Vector2(3, .1); + static final Vector2 _size = Vector2(Launcher.width / 3, .1); @override Shape get shape => PolygonShape() diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 9f5055ef..78b26d4a 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -83,17 +83,7 @@ class PinballGame extends Forge2DGame Future _addPaths() async { unawaited(addFromBlueprint(Jetpack())); - - final launcherRamp = LauncherRamp( - position: Vector2( - PinballGame.boardBounds.right - 30, - PinballGame.boardBounds.bottom + 40, - ), - ); - - await addAll([ - launcherRamp, - ]); + unawaited(addFromBlueprint(Launcher())); } void spawnBall() {