From 9d98ff37fbe9961244e607167d45c82e3137933d Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Thu, 5 May 2022 15:42:55 +0200 Subject: [PATCH] fix: `Plunger`'s pull not correctly working on some devices (#321) * fix: plunger's pull not correctly working on some devices * fix: plunger's pull not correctly working on some devices * fix: plunger's pull not correctly working on some devices Co-authored-by: Tom Arra --- .../lib/src/components/plunger.dart | 2 +- .../test/src/components/plunger_test.dart | 6 +++++- .../pinball_flame/lib/src/pinball_forge2d_game.dart | 12 +++++++++++- .../test/src/pinball_forge2d_game_test.dart | 12 ++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/pinball_components/lib/src/components/plunger.dart b/packages/pinball_components/lib/src/components/plunger.dart index 79b370a0..040c3287 100644 --- a/packages/pinball_components/lib/src/components/plunger.dart +++ b/packages/pinball_components/lib/src/components/plunger.dart @@ -97,7 +97,7 @@ class Plunger extends BodyComponent with InitialPosition, Layered, ZIndex { void update(double dt) { // Ensure that we only pull or release when the time is greater than zero. if (_pullingDownTime > 0) { - _pullingDownTime -= dt; + _pullingDownTime -= PinballForge2DGame.clampDt(dt); if (_pullingDownTime <= 0) { release(); } else { diff --git a/packages/pinball_components/test/src/components/plunger_test.dart b/packages/pinball_components/test/src/components/plunger_test.dart index abb42d68..fd759f8d 100644 --- a/packages/pinball_components/test/src/components/plunger_test.dart +++ b/packages/pinball_components/test/src/components/plunger_test.dart @@ -141,7 +141,11 @@ void main() { expect(plunger.body.linearVelocity.y, isPositive); - await tester.pump(const Duration(seconds: 2)); + // Call game update at 120 FPS, so that the plunger will act as if it + // was pulled for 2 seconds. + for (var i = 0.0; i < 2; i += 1 / 120) { + game.update(1 / 20); + } expect(plunger.body.linearVelocity.y, isZero); }, diff --git a/packages/pinball_flame/lib/src/pinball_forge2d_game.dart b/packages/pinball_flame/lib/src/pinball_forge2d_game.dart index 118baad9..0013dd26 100644 --- a/packages/pinball_flame/lib/src/pinball_forge2d_game.dart +++ b/packages/pinball_flame/lib/src/pinball_forge2d_game.dart @@ -24,7 +24,7 @@ class PinballForge2DGame extends FlameGame implements Forge2DGame { @override void update(double dt) { super.update(dt); - world.stepDt(min(dt, 1 / 60)); + world.stepDt(clampDt(dt)); } @override @@ -41,4 +41,14 @@ class PinballForge2DGame extends FlameGame implements Forge2DGame { Vector2 worldToScreen(Vector2 position) { throw UnimplementedError(); } + + /// Clamp the [dt] in such a way that it would never exceed the minimal of + /// 1/60th of a second. + /// + /// Note: this is a static method because composing this class as a generic + /// on `BodyComponent` and mixins for that class will crash the Dart analyzer + /// server. + static double clampDt(double dt) { + return min(dt, 1 / 60); + } } diff --git a/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart b/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart index 872f8b97..b8dc9fcc 100644 --- a/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart +++ b/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart @@ -47,5 +47,17 @@ void main() { ); }, ); + + group('clampDt', () { + test('returns dt', () { + const dt = 0.0001; + expect(PinballForge2DGame.clampDt(dt), equals(dt)); + }); + + test('returns result of 1/60 as dt is to high', () { + const dt = 1.0; + expect(PinballForge2DGame.clampDt(dt), equals(1 / 60)); + }); + }); }); }