From 4ceb0cd2c2d5800c55b1d4f1716fc753ecc00d36 Mon Sep 17 00:00:00 2001 From: alestiago Date: Mon, 21 Mar 2022 16:09:57 +0000 Subject: [PATCH] feat: made ChromeDino sweep --- lib/game/components/chrome_dino.dart | 105 ++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 3 deletions(-) diff --git a/lib/game/components/chrome_dino.dart b/lib/game/components/chrome_dino.dart index e7c76573..a297781c 100644 --- a/lib/game/components/chrome_dino.dart +++ b/lib/game/components/chrome_dino.dart @@ -1,4 +1,8 @@ +import 'dart:async'; +import 'dart:math' as math; + import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flutter/material.dart'; import 'package:pinball/game/game.dart'; /// {@template chrome_dino} @@ -7,11 +11,106 @@ import 'package:pinball/game/game.dart'; /// {@endtemplate} class ChromeDino extends BodyComponent with InitialPosition { /// {@macro chrome_dino} - ChromeDino(); + ChromeDino() { + // TODO(alestiago): Remove once sprites are defined. + paint = Paint()..color = Colors.blue; + } + + static final size = Vector2(3, 1); + + /// Anchors the [ChromeDino] to the [RevoluteJoint] that controls its arc + /// motion. + Future _anchorToJoint() async { + final anchor = ChromeDinoAnchor(chromeDino: this); + await add(anchor); + + final jointDef = ChromeDinoAnchorRevoluteJointDef( + chromeDino: this, + anchor: anchor, + ); + final joint = world.createJoint(jointDef) as RevoluteJoint; + + ChromeDinoAnchorRevoluteJointDef.spin(joint, removed); + } + + Completer removed = Completer(); + + @override + void onRemove() { + super.onRemove(); + removed.complete(true); + } + + @override + Future onLoad() async { + await super.onLoad(); + await _anchorToJoint(); + } @override Body createBody() { - // TODO: implement createBody - throw UnimplementedError(); + final shape = PolygonShape()..setAsBoxXY(size.x, size.y); + final fixtureDef = FixtureDef(shape)..density = 1; + + final bodyDef = BodyDef() + ..gravityScale = 0 + ..position = initialPosition + ..type = BodyType.dynamic; + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } +} + +/// {@template flipper_anchor} +/// [JointAnchor] positioned at the end of a [ChromeDino]. +/// {@endtemplate} +class ChromeDinoAnchor extends JointAnchor { + /// {@macro flipper_anchor} + ChromeDinoAnchor({ + required ChromeDino chromeDino, + }) { + initialPosition = Vector2( + chromeDino.body.position.x + ChromeDino.size.x / 2, + chromeDino.body.position.y, + ); + } +} + +/// {@template chrome_dino_anchor_revolute_joint_def} +/// Hinges a [ChromeDino] to a [ChromeDinoAnchor]. +/// {@endtemplate} +class ChromeDinoAnchorRevoluteJointDef extends RevoluteJointDef { + /// {@macro chrome_dino_anchor_revolute_joint_def} + ChromeDinoAnchorRevoluteJointDef({ + required ChromeDino chromeDino, + required ChromeDinoAnchor anchor, + }) { + initialize( + chromeDino.body, + anchor.body, + anchor.body.position, + ); + enableLimit = true; + const halfAngle = _sweepingAngle / 2; + lowerAngle = -halfAngle; + upperAngle = halfAngle; + + enableMotor = true; + maxMotorTorque = 999; + motorSpeed = 999; } + + // TODO(alestiago): Refactor. + static void spin(RevoluteJoint joint, Completer completer) { + Future.doWhile(() async { + if (completer.isCompleted) return false; + + await Future.delayed(Duration(milliseconds: 1000)); + joint.setMotorSpeed(-joint.motorSpeed); + return true; + }); + } + + /// The total angle of the arc motion. + static const _sweepingAngle = math.pi / 3.5; }