From e6dca1ed7fca5a9ef50d9eab6db26b7938fcded4 Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Fri, 25 Mar 2022 08:00:35 -0500 Subject: [PATCH 1/3] refactor: dimension and position `Plunger` (#96) * refactor: dimension plunger * refactor: adjust launch ramp and ball size * refactor: use board center for positioning Co-authored-by: Erick --- lib/game/components/launcher_ramp.dart | 23 ++++++++----------- lib/game/components/plunger.dart | 18 ++++++++++----- lib/game/pinball_game.dart | 13 +++++------ .../lib/src/components/ball.dart | 2 +- .../test/src/components/ball_test.dart | 2 +- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index aae9265f..61b9e26f 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -27,33 +27,30 @@ class LauncherRamp extends Component with HasGameRef { RampOpeningBallContactCallback<_LauncherRampOpening>(), ); - final launcherRampRotation = - -math.atan(18.6 / PinballGame.boardBounds.height); - 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, + start: position + Vector2(-4.5, -10), + end: position + Vector2(-4.5, 117), + width: 4, + rotation: PinballGame.boardPerspectiveAngle, ) ..initialPosition = position ..layer = layer; final curvedPath = Pathway.arc( color: const Color.fromARGB(255, 251, 255, 0), - center: position + Vector2(-2.8, 87.2), + center: position + Vector2(-7, 87.2), radius: 16.3, angle: math.pi / 2, - width: 5, + width: 4, rotation: 3 * math.pi / 2, )..layer = layer; final leftOpening = _LauncherRampOpening(rotation: math.pi / 2) - ..initialPosition = position + Vector2(-11.8, 66.3) + ..initialPosition = position + Vector2(-13.8, 66.7) ..layer = Layer.opening; final rightOpening = _LauncherRampOpening(rotation: 0) - ..initialPosition = position + Vector2(-4.9, 59.4) + ..initialPosition = position + Vector2(-6.8, 59.4) ..layer = Layer.opening; await addAll([ @@ -81,9 +78,9 @@ class _LauncherRampOpening extends RampOpening { final double _rotation; - // TODO(ruialonso): Avoid magic number 3, should be propotional to + // TODO(ruialonso): Avoid magic number 2.5, should be propotional to // [JetpackRamp]. - static final Vector2 _size = Vector2(3, .1); + static final Vector2 _size = Vector2(2.5, .1); @override Shape get shape => PolygonShape() diff --git a/lib/game/components/plunger.dart b/lib/game/components/plunger.dart index 9791ec66..d9137457 100644 --- a/lib/game/components/plunger.dart +++ b/lib/game/components/plunger.dart @@ -21,9 +21,15 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { @override Body createBody() { - final shape = PolygonShape()..setAsBoxXY(2, 0.75); + final shape = PolygonShape() + ..setAsBox( + 1.35, + 0.5, + Vector2.zero(), + PinballGame.boardPerspectiveAngle, + ); - final fixtureDef = FixtureDef(shape)..density = 5; + final fixtureDef = FixtureDef(shape)..density = 20; final bodyDef = BodyDef() ..position = initialPosition @@ -36,7 +42,7 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { /// Set a constant downward velocity on the [Plunger]. void _pull() { - body.linearVelocity = Vector2(0, -3); + body.linearVelocity = Vector2(0, -7); } /// Set an upward velocity on the [Plunger]. @@ -44,7 +50,7 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { /// The velocity's magnitude depends on how far the [Plunger] has been pulled /// from its original [initialPosition]. void _release() { - final velocity = (initialPosition.y - body.position.y) * 9; + final velocity = (initialPosition.y - body.position.y) * 4; body.linearVelocity = Vector2(0, velocity); } @@ -121,12 +127,12 @@ class PlungerAnchorPrismaticJointDef extends PrismaticJointDef { plunger.body, anchor.body, anchor.body.position, - Vector2(0, -1), + Vector2(18.6, PinballGame.boardBounds.height), ); enableLimit = true; lowerTranslation = double.negativeInfinity; enableMotor = true; - motorSpeed = 50; + motorSpeed = 80; maxMotorForce = motorSpeed; collideConnected = true; } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 39cecb61..057809be 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -1,5 +1,7 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; +import 'dart:math' as math; + import 'package:flame/extensions.dart'; import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; @@ -24,6 +26,8 @@ class PinballGame extends Forge2DGame width: boardSize.x, height: -boardSize.y, ); + static final boardPerspectiveAngle = + -math.atan(18.6 / PinballGame.boardBounds.height); @override void onAttach() { @@ -60,13 +64,8 @@ class PinballGame extends Forge2DGame } Future _addPlunger() async { - plunger = Plunger(compressionDistance: 2); - - plunger.initialPosition = boardBounds.bottomRight.toVector2() + - Vector2( - -5, - 10, - ); + plunger = Plunger(compressionDistance: 29) + ..initialPosition = boardBounds.center.toVector2() + Vector2(41.5, -49); await add(plunger); } diff --git a/packages/pinball_components/lib/src/components/ball.dart b/packages/pinball_components/lib/src/components/ball.dart index ec51cb47..674cdbf3 100644 --- a/packages/pinball_components/lib/src/components/ball.dart +++ b/packages/pinball_components/lib/src/components/ball.dart @@ -22,7 +22,7 @@ class Ball extends BodyComponent } /// The size of the [Ball] - final Vector2 size = Vector2.all(2); + final Vector2 size = Vector2.all(3); /// The base [Color] used to tint this [Ball] final Color baseColor; diff --git a/packages/pinball_components/test/src/components/ball_test.dart b/packages/pinball_components/test/src/components/ball_test.dart index 682f1f73..14a3de35 100644 --- a/packages/pinball_components/test/src/components/ball_test.dart +++ b/packages/pinball_components/test/src/components/ball_test.dart @@ -86,7 +86,7 @@ void main() { final fixture = ball.body.fixtures[0]; expect(fixture.shape.shapeType, equals(ShapeType.circle)); - expect(fixture.shape.radius, equals(1)); + expect(fixture.shape.radius, equals(1.5)); }, ); From de963cbc862e4c5c9953203c59a8f9ec83e018fe Mon Sep 17 00:00:00 2001 From: Erick Date: Fri, 25 Mar 2022 10:19:35 -0300 Subject: [PATCH 2/3] feat: adds ball turbocharge effect (#66) * feat: adding ball boost effect * fix: lint --- .../lib/src/components/ball.dart | 26 ++++ .../lib/src/components/components.dart | 1 + .../lib/src/components/fire_effect.dart | 113 ++++++++++++++++++ .../sandbox/lib/common/common.dart | 13 +- .../sandbox/lib/common/games.dart | 74 ++++++++++++ .../sandbox/lib/common/methods.dart | 3 + .../pinball_components/sandbox/lib/main.dart | 2 + .../sandbox/lib/stories/ball/ball.dart | 28 +++-- .../lib/stories/ball/ball_booster.dart | 16 +++ .../sandbox/lib/stories/ball/basic.dart | 6 +- .../sandbox/lib/stories/effects/effects.dart | 13 ++ .../lib/stories/effects/fire_effect.dart | 46 +++++++ .../test/helpers/helpers.dart | 1 + .../test/helpers/mocks.dart | 5 + .../test/src/components/ball_test.dart | 24 ++++ .../test/src/components/fire_effect_test.dart | 55 +++++++++ 16 files changed, 403 insertions(+), 23 deletions(-) create mode 100644 packages/pinball_components/lib/src/components/fire_effect.dart create mode 100644 packages/pinball_components/sandbox/lib/common/games.dart create mode 100644 packages/pinball_components/sandbox/lib/common/methods.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/ball/ball_booster.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/effects/effects.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/effects/fire_effect.dart create mode 100644 packages/pinball_components/test/helpers/mocks.dart create mode 100644 packages/pinball_components/test/src/components/fire_effect_test.dart diff --git a/packages/pinball_components/lib/src/components/ball.dart b/packages/pinball_components/lib/src/components/ball.dart index 674cdbf3..2ceb56d7 100644 --- a/packages/pinball_components/lib/src/components/ball.dart +++ b/packages/pinball_components/lib/src/components/ball.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:ui'; import 'package:flame/components.dart'; @@ -27,6 +28,9 @@ class Ball extends BodyComponent /// The base [Color] used to tint this [Ball] final Color baseColor; + double _boostTimer = 0; + static const _boostDuration = 2.0; + @override Future onLoad() async { await super.onLoad(); @@ -69,4 +73,26 @@ class Ball extends BodyComponent void resume() { body.setType(BodyType.dynamic); } + + @override + void update(double dt) { + super.update(dt); + if (_boostTimer > 0) { + _boostTimer -= dt; + final direction = body.linearVelocity.normalized(); + final effect = FireEffect( + burstPower: _boostTimer, + direction: direction, + position: body.position, + ); + + unawaited(gameRef.add(effect)); + } + } + + /// Applies a boost on this [Ball] + void boost(Vector2 impulse) { + body.applyLinearImpulse(impulse); + _boostTimer = _boostDuration; + } } diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 677bbd0c..c1ef3e14 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -1,3 +1,4 @@ export 'ball.dart'; +export 'fire_effect.dart'; export 'initial_position.dart'; export 'layer.dart'; diff --git a/packages/pinball_components/lib/src/components/fire_effect.dart b/packages/pinball_components/lib/src/components/fire_effect.dart new file mode 100644 index 00000000..0a7cef2b --- /dev/null +++ b/packages/pinball_components/lib/src/components/fire_effect.dart @@ -0,0 +1,113 @@ +import 'dart:math' as math; + +import 'package:flame/extensions.dart'; +import 'package:flame/particles.dart'; +import 'package:flame_forge2d/flame_forge2d.dart' hide Particle; +import 'package:flutter/material.dart'; + +const _particleRadius = 0.25; + +// TODO(erickzanardo): This component could just be a ParticleComponet, +/// unfortunately there is a Particle Component is not a PositionComponent, +/// which makes it hard to be used since we have camera transformations and on +// top of that, PositionComponent has a bug inside forge 2d games +/// +/// https://github.com/flame-engine/flame/issues/1484 +/// https://github.com/flame-engine/flame/issues/1484 + +/// {@template fire_effect} +/// A [BodyComponent] which creates a fire trail effect using the given +/// parameters +/// {@endtemplate} +class FireEffect extends BodyComponent { + /// {@macro fire_effect} + FireEffect({ + required this.burstPower, + required this.position, + required this.direction, + }); + + /// A [double] value that will define how "strong" the burst of particles + /// will be + final double burstPower; + + /// The position of the burst + final Vector2 position; + + /// Which direction the burst will aim + final Vector2 direction; + late Particle _particle; + + @override + Body createBody() { + final bodyDef = BodyDef()..position = position; + + final fixtureDef = FixtureDef(CircleShape()..radius = 0)..isSensor = true; + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } + + @override + Future onLoad() async { + await super.onLoad(); + + final children = [ + ...List.generate(4, (index) { + return CircleParticle( + radius: _particleRadius, + paint: Paint()..color = Colors.yellow.darken((index + 1) / 4), + ); + }), + ...List.generate(4, (index) { + return CircleParticle( + radius: _particleRadius, + paint: Paint()..color = Colors.red.darken((index + 1) / 4), + ); + }), + ...List.generate(4, (index) { + return CircleParticle( + radius: _particleRadius, + paint: Paint()..color = Colors.orange.darken((index + 1) / 4), + ); + }), + ]; + final rng = math.Random(); + final spreadTween = Tween(begin: -0.2, end: 0.2); + + _particle = Particle.generate( + count: (rng.nextDouble() * (burstPower * 10)).toInt(), + generator: (_) { + final spread = Vector2( + spreadTween.transform(rng.nextDouble()), + spreadTween.transform(rng.nextDouble()), + ); + final finalDirection = Vector2(direction.x, -direction.y) + spread; + final speed = finalDirection * (burstPower * 20); + + return AcceleratedParticle( + lifespan: 5 / burstPower, + position: Vector2.zero(), + speed: speed, + child: children[rng.nextInt(children.length)], + ); + }, + ); + } + + @override + void update(double dt) { + super.update(dt); + _particle.update(dt); + + if (_particle.shouldRemove) { + removeFromParent(); + } + } + + @override + void render(Canvas canvas) { + super.render(canvas); + + _particle.render(canvas); + } +} diff --git a/packages/pinball_components/sandbox/lib/common/common.dart b/packages/pinball_components/sandbox/lib/common/common.dart index b7ee5a4a..578c9b38 100644 --- a/packages/pinball_components/sandbox/lib/common/common.dart +++ b/packages/pinball_components/sandbox/lib/common/common.dart @@ -1,11 +1,2 @@ -import 'package:flame_forge2d/flame_forge2d.dart'; - -String buildSourceLink(String path) { - return 'https://github.com/VGVentures/pinball/tree/main/packages/pinball_components/sandbox/lib/stories/$path'; -} - -class BasicGame extends Forge2DGame { - BasicGame() { - images.prefix = ''; - } -} +export 'games.dart'; +export 'methods.dart'; diff --git a/packages/pinball_components/sandbox/lib/common/games.dart b/packages/pinball_components/sandbox/lib/common/games.dart new file mode 100644 index 00000000..bce1ff90 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/common/games.dart @@ -0,0 +1,74 @@ +import 'dart:async'; + +import 'package:flame/components.dart'; +import 'package:flame/input.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flutter/material.dart'; + +class BasicGame extends Forge2DGame { + BasicGame() { + images.prefix = ''; + } +} + +abstract class LineGame extends BasicGame with PanDetector { + Vector2? _lineEnd; + + @override + Future onLoad() async { + await super.onLoad(); + + camera.followVector2(Vector2.zero()); + unawaited(add(_PreviewLine())); + } + + @override + void onPanStart(DragStartInfo info) { + _lineEnd = info.eventPosition.game; + } + + @override + void onPanUpdate(DragUpdateInfo info) { + _lineEnd = info.eventPosition.game; + } + + @override + void onPanEnd(DragEndInfo info) { + if (_lineEnd != null) { + final line = _lineEnd! - Vector2.zero(); + onLine(line); + _lineEnd = null; + } + } + + void onLine(Vector2 line); +} + +class _PreviewLine extends PositionComponent with HasGameRef { + static final _previewLinePaint = Paint() + ..color = Colors.pink + ..strokeWidth = 0.2 + ..style = PaintingStyle.stroke; + + Vector2? lineEnd; + + @override + void update(double dt) { + super.update(dt); + + lineEnd = gameRef._lineEnd?.clone()?..multiply(Vector2(1, -1)); + } + + @override + void render(Canvas canvas) { + super.render(canvas); + + if (lineEnd != null) { + canvas.drawLine( + Vector2.zero().toOffset(), + lineEnd!.toOffset(), + _previewLinePaint, + ); + } + } +} diff --git a/packages/pinball_components/sandbox/lib/common/methods.dart b/packages/pinball_components/sandbox/lib/common/methods.dart new file mode 100644 index 00000000..35198922 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/common/methods.dart @@ -0,0 +1,3 @@ +String buildSourceLink(String path) { + return 'https://github.com/VGVentures/pinball/tree/main/packages/pinball_components/sandbox/lib/stories/$path'; +} diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index 0cfd6f7f..dd6aeafe 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -6,11 +6,13 @@ // https://opensource.org/licenses/MIT. import 'package:dashbook/dashbook.dart'; import 'package:flutter/material.dart'; +import 'package:sandbox/stories/effects/effects.dart'; import 'package:sandbox/stories/stories.dart'; void main() { final dashbook = Dashbook(theme: ThemeData.dark()); addBallStories(dashbook); + addEffectsStories(dashbook); runApp(dashbook); } diff --git a/packages/pinball_components/sandbox/lib/stories/ball/ball.dart b/packages/pinball_components/sandbox/lib/stories/ball/ball.dart index f8e49a57..35b29499 100644 --- a/packages/pinball_components/sandbox/lib/stories/ball/ball.dart +++ b/packages/pinball_components/sandbox/lib/stories/ball/ball.dart @@ -2,17 +2,27 @@ import 'package:dashbook/dashbook.dart'; import 'package:flame/game.dart'; import 'package:flutter/material.dart'; import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/ball/ball_booster.dart'; import 'package:sandbox/stories/ball/basic.dart'; void addBallStories(Dashbook dashbook) { - dashbook.storiesOf('Ball').add( - 'Basic', - (context) => GameWidget( - game: BasicBallGame( - color: context.colorProperty('color', Colors.blue), - ), + dashbook.storiesOf('Ball') + ..add( + 'Basic', + (context) => GameWidget( + game: BasicBallGame( + color: context.colorProperty('color', Colors.blue), ), - codeLink: buildSourceLink('ball/basic.dart'), - info: BasicBallGame.info, - ); + ), + codeLink: buildSourceLink('ball/basic.dart'), + info: BasicBallGame.info, + ) + ..add( + 'Booster', + (context) => GameWidget( + game: BallBoosterExample(), + ), + codeLink: buildSourceLink('ball/ball_booster.dart'), + info: BallBoosterExample.info, + ); } diff --git a/packages/pinball_components/sandbox/lib/stories/ball/ball_booster.dart b/packages/pinball_components/sandbox/lib/stories/ball/ball_booster.dart new file mode 100644 index 00000000..9f78953a --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/ball/ball_booster.dart @@ -0,0 +1,16 @@ +import 'package:flame/components.dart'; +import 'package:flutter/material.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; + +class BallBoosterExample extends LineGame { + static const info = ''; + + @override + void onLine(Vector2 line) { + final ball = Ball(baseColor: Colors.transparent); + add(ball); + + ball.mounted.then((value) => ball.boost(line * -1 * 20)); + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/ball/basic.dart b/packages/pinball_components/sandbox/lib/stories/ball/basic.dart index 78948666..f133ee3f 100644 --- a/packages/pinball_components/sandbox/lib/stories/ball/basic.dart +++ b/packages/pinball_components/sandbox/lib/stories/ball/basic.dart @@ -4,7 +4,7 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; class BasicBallGame extends BasicGame with TapDetector { - BasicBallGame({ required this.color }); + BasicBallGame({required this.color}); static const info = ''' Basic example of how a Ball works, tap anywhere on the @@ -15,8 +15,8 @@ class BasicBallGame extends BasicGame with TapDetector { @override void onTapUp(TapUpInfo info) { - add(Ball(baseColor: color) - ..initialPosition = info.eventPosition.game, + add( + Ball(baseColor: color)..initialPosition = info.eventPosition.game, ); } } diff --git a/packages/pinball_components/sandbox/lib/stories/effects/effects.dart b/packages/pinball_components/sandbox/lib/stories/effects/effects.dart new file mode 100644 index 00000000..3a89c73b --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/effects/effects.dart @@ -0,0 +1,13 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:flame/game.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/effects/fire_effect.dart'; + +void addEffectsStories(Dashbook dashbook) { + dashbook.storiesOf('Effects').add( + 'Fire Effect', + (context) => GameWidget(game: FireEffectExample()), + codeLink: buildSourceLink('effects/fire_effect.dart'), + info: FireEffectExample.info, + ); +} diff --git a/packages/pinball_components/sandbox/lib/stories/effects/fire_effect.dart b/packages/pinball_components/sandbox/lib/stories/effects/fire_effect.dart new file mode 100644 index 00000000..9f066952 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/effects/fire_effect.dart @@ -0,0 +1,46 @@ +import 'package:flame/components.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; + +class FireEffectExample extends LineGame { + static const info = 'Demonstrate the fire trail effect ' + 'drag a line to define the trail direction'; + + @override + void onLine(Vector2 line) { + add(_EffectEmitter(line)); + } +} + +class _EffectEmitter extends Component { + _EffectEmitter(this.line) { + _direction = line.normalized(); + _force = line.length; + } + + static const _timerLimit = 2.0; + var _timer = _timerLimit; + + final Vector2 line; + + late Vector2 _direction; + late double _force; + + @override + void update(double dt) { + super.update(dt); + + if (_timer > 0) { + add( + FireEffect( + burstPower: (_timer / _timerLimit) * _force, + position: Vector2.zero(), + direction: _direction, + ), + ); + _timer -= dt; + } else { + removeFromParent(); + } + } +} diff --git a/packages/pinball_components/test/helpers/helpers.dart b/packages/pinball_components/test/helpers/helpers.dart index a8b9f7ff..312f42ec 100644 --- a/packages/pinball_components/test/helpers/helpers.dart +++ b/packages/pinball_components/test/helpers/helpers.dart @@ -1 +1,2 @@ +export 'mocks.dart'; export 'test_game.dart'; diff --git a/packages/pinball_components/test/helpers/mocks.dart b/packages/pinball_components/test/helpers/mocks.dart new file mode 100644 index 00000000..67df9918 --- /dev/null +++ b/packages/pinball_components/test/helpers/mocks.dart @@ -0,0 +1,5 @@ +import 'dart:ui'; + +import 'package:mocktail/mocktail.dart'; + +class MockCanvas extends Mock implements Canvas {} diff --git a/packages/pinball_components/test/src/components/ball_test.dart b/packages/pinball_components/test/src/components/ball_test.dart index 14a3de35..a9eb05ad 100644 --- a/packages/pinball_components/test/src/components/ball_test.dart +++ b/packages/pinball_components/test/src/components/ball_test.dart @@ -158,5 +158,29 @@ void main() { ); }); }); + + group('boost', () { + flameTester.test('applies an impulse to the ball', (game) async { + final ball = Ball(baseColor: Colors.blue); + await game.ensureAdd(ball); + + expect(ball.body.linearVelocity, equals(Vector2.zero())); + + ball.boost(Vector2.all(10)); + expect(ball.body.linearVelocity.x, greaterThan(0)); + expect(ball.body.linearVelocity.y, greaterThan(0)); + }); + + flameTester.test('adds fire effect components to the game', (game) async { + final ball = Ball(baseColor: Colors.blue); + await game.ensureAdd(ball); + + ball.boost(Vector2.all(10)); + game.update(0); + await game.ready(); + + expect(game.children.whereType().length, greaterThan(0)); + }); + }); }); } diff --git a/packages/pinball_components/test/src/components/fire_effect_test.dart b/packages/pinball_components/test/src/components/fire_effect_test.dart new file mode 100644 index 00000000..bc6baa4b --- /dev/null +++ b/packages/pinball_components/test/src/components/fire_effect_test.dart @@ -0,0 +1,55 @@ +// ignore_for_file: cascade_invocations + +import 'dart:ui'; + +import 'package:flame/components.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball_components/pinball_components.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(TestGame.new); + + setUpAll(() { + registerFallbackValue(Offset.zero); + registerFallbackValue(Paint()); + }); + + group('FireEffect', () { + flameTester.test('is removed once its particles are done', (game) async { + await game.ensureAdd( + FireEffect( + burstPower: 1, + position: Vector2.zero(), + direction: Vector2.all(2), + ), + ); + await game.ready(); + expect(game.children.whereType().length, equals(1)); + game.update(5); + + await game.ready(); + expect(game.children.whereType().length, equals(0)); + }); + + flameTester.test('render circles on the canvas', (game) async { + final effect = FireEffect( + burstPower: 1, + position: Vector2.zero(), + direction: Vector2.all(2), + ); + await game.ensureAdd(effect); + await game.ready(); + + final canvas = MockCanvas(); + effect.render(canvas); + + verify(() => canvas.drawCircle(any(), any(), any())) + .called(greaterThan(0)); + }); + }); +} From e6eacfa9e76ec7929e46279d14a3ad7d14dc1168 Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Fri, 25 Mar 2022 08:42:35 -0500 Subject: [PATCH 3/3] fix: sort scores in descending order (#100) --- .../lib/src/leaderboard_repository.dart | 4 ++-- .../test/src/leaderboard_repository_test.dart | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/leaderboard_repository/lib/src/leaderboard_repository.dart b/packages/leaderboard_repository/lib/src/leaderboard_repository.dart index d75a88b3..30f6810f 100644 --- a/packages/leaderboard_repository/lib/src/leaderboard_repository.dart +++ b/packages/leaderboard_repository/lib/src/leaderboard_repository.dart @@ -91,7 +91,7 @@ class LeaderboardRepository { try { final querySnapshot = await _firebaseFirestore .collection('leaderboard') - .orderBy('score') + .orderBy('score', descending: true) .limit(10) .get(); documents = querySnapshot.docs; @@ -130,7 +130,7 @@ class LeaderboardRepository { try { final querySnapshot = await _firebaseFirestore .collection('leaderboard') - .orderBy('score') + .orderBy('score', descending: true) .get(); // TODO(allisonryan0002): see if we can find a more performant solution. diff --git a/packages/leaderboard_repository/test/src/leaderboard_repository_test.dart b/packages/leaderboard_repository/test/src/leaderboard_repository_test.dart index 592425ec..1341d3f4 100644 --- a/packages/leaderboard_repository/test/src/leaderboard_repository_test.dart +++ b/packages/leaderboard_repository/test/src/leaderboard_repository_test.dart @@ -82,7 +82,7 @@ void main() { when(() => firestore.collection('leaderboard')) .thenAnswer((_) => collectionReference); - when(() => collectionReference.orderBy('score')) + when(() => collectionReference.orderBy('score', descending: true)) .thenAnswer((_) => query); when(() => query.limit(10)).thenAnswer((_) => query); when(query.get).thenAnswer((_) async => querySnapshot); @@ -173,7 +173,7 @@ void main() { .thenAnswer((_) => collectionReference); when(() => collectionReference.add(any())) .thenAnswer((_) async => documentReference); - when(() => collectionReference.orderBy('score')) + when(() => collectionReference.orderBy('score', descending: true)) .thenAnswer((_) => query); when(query.get).thenAnswer((_) async => querySnapshot); when(() => querySnapshot.docs).thenReturn(queryDocumentSnapshots); @@ -203,7 +203,8 @@ void main() { test( 'throws FetchPlayerRankingException when Exception occurs ' 'when trying to retrieve information from firestore', () async { - when(() => collectionReference.orderBy('score')).thenThrow(Exception()); + when(() => collectionReference.orderBy('score', descending: true)) + .thenThrow(Exception()); expect( () => leaderboardRepository.addLeaderboardEntry(leaderboardEntry),