From 5af198a9a0e71f80448cbde8c9b1b56a9e221963 Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Tue, 3 May 2022 21:48:09 +0200 Subject: [PATCH] fix: physics are FPS depended (#316) * fix: physics are FPS depended * fix: physics are FPS depended --- lib/game/pinball_game.dart | 3 +- .../lib/src/components/ball/ball.dart | 3 +- .../lib/src/components/initial_position.dart | 2 +- .../lib/src/components/layer.dart | 2 +- packages/pinball_flame/lib/pinball_flame.dart | 1 + .../lib/src/pinball_forge2d_game.dart | 44 ++++++++++++++++ .../test/src/pinball_forge2d_game_test.dart | 51 +++++++++++++++++++ .../game/components/controlled_ball_test.dart | 3 +- 8 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 packages/pinball_flame/lib/src/pinball_forge2d_game.dart create mode 100644 packages/pinball_flame/test/src/pinball_forge2d_game_test.dart diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index f9018ee5..bd29e4e8 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -5,7 +5,6 @@ import 'package:flame/components.dart'; import 'package:flame/game.dart'; import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; -import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:pinball/game/game.dart'; @@ -14,7 +13,7 @@ import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_theme/pinball_theme.dart'; -class PinballGame extends Forge2DGame +class PinballGame extends PinballForge2DGame with FlameBloc, HasKeyboardHandlerComponents, diff --git a/packages/pinball_components/lib/src/components/ball/ball.dart b/packages/pinball_components/lib/src/components/ball/ball.dart index dea4c0b4..12b1c877 100644 --- a/packages/pinball_components/lib/src/components/ball/ball.dart +++ b/packages/pinball_components/lib/src/components/ball/ball.dart @@ -12,8 +12,7 @@ import 'package:pinball_flame/pinball_flame.dart'; /// {@template ball} /// A solid, [BodyType.dynamic] sphere that rolls and bounces around. /// {@endtemplate} -class Ball extends BodyComponent - with Layered, InitialPosition, ZIndex { +class Ball extends BodyComponent with Layered, InitialPosition, ZIndex { /// {@macro ball} Ball({ required this.baseColor, diff --git a/packages/pinball_components/lib/src/components/initial_position.dart b/packages/pinball_components/lib/src/components/initial_position.dart index d79f8d64..4265a3a7 100644 --- a/packages/pinball_components/lib/src/components/initial_position.dart +++ b/packages/pinball_components/lib/src/components/initial_position.dart @@ -5,7 +5,7 @@ import 'package:flame_forge2d/flame_forge2d.dart'; /// /// Note: If the [initialPosition] is set after the [BodyComponent] has been /// loaded it will have no effect; defaulting to [Vector2.zero]. -mixin InitialPosition on BodyComponent { +mixin InitialPosition on BodyComponent { final Vector2 _initialPosition = Vector2.zero(); set initialPosition(Vector2 value) { diff --git a/packages/pinball_components/lib/src/components/layer.dart b/packages/pinball_components/lib/src/components/layer.dart index a39ad837..8418fac1 100644 --- a/packages/pinball_components/lib/src/components/layer.dart +++ b/packages/pinball_components/lib/src/components/layer.dart @@ -9,7 +9,7 @@ import 'package:flutter/material.dart'; /// ignoring others. This compatibility depends on bit masking operation /// between layers. For more information read: https://en.wikipedia.org/wiki/Mask_(computing). /// {@endtemplate} -mixin Layered on BodyComponent { +mixin Layered on BodyComponent { Layer _layer = Layer.all; /// {@macro layered} diff --git a/packages/pinball_flame/lib/pinball_flame.dart b/packages/pinball_flame/lib/pinball_flame.dart index 66d34b14..8d458574 100644 --- a/packages/pinball_flame/lib/pinball_flame.dart +++ b/packages/pinball_flame/lib/pinball_flame.dart @@ -4,5 +4,6 @@ export 'src/component_controller.dart'; export 'src/contact_behavior.dart'; export 'src/keyboard_input_controller.dart'; export 'src/parent_is_a.dart'; +export 'src/pinball_forge2d_game.dart'; export 'src/sprite_animation.dart'; export 'src/z_canvas_component.dart'; diff --git a/packages/pinball_flame/lib/src/pinball_forge2d_game.dart b/packages/pinball_flame/lib/src/pinball_forge2d_game.dart new file mode 100644 index 00000000..118baad9 --- /dev/null +++ b/packages/pinball_flame/lib/src/pinball_forge2d_game.dart @@ -0,0 +1,44 @@ +import 'dart:math'; + +import 'package:flame/game.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_forge2d/world_contact_listener.dart'; + +// NOTE(wolfen): This should be removed when https://github.com/flame-engine/flame/pull/1597 is solved. +/// {@template pinball_forge2d_game} +/// A [Game] that uses the Forge2D physics engine. +/// {@endtemplate} +class PinballForge2DGame extends FlameGame implements Forge2DGame { + /// {@macro pinball_forge2d_game} + PinballForge2DGame({ + required Vector2 gravity, + }) : world = World(gravity), + super(camera: Camera()) { + camera.zoom = Forge2DGame.defaultZoom; + world.setContactListener(WorldContactListener()); + } + + @override + final World world; + + @override + void update(double dt) { + super.update(dt); + world.stepDt(min(dt, 1 / 60)); + } + + @override + Vector2 screenToFlameWorld(Vector2 position) { + throw UnimplementedError(); + } + + @override + Vector2 screenToWorld(Vector2 position) { + throw UnimplementedError(); + } + + @override + Vector2 worldToScreen(Vector2 position) { + throw UnimplementedError(); + } +} diff --git a/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart b/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart new file mode 100644 index 00000000..872f8b97 --- /dev/null +++ b/packages/pinball_flame/test/src/pinball_forge2d_game_test.dart @@ -0,0 +1,51 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame/extensions.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +void main() { + final flameTester = FlameTester( + () => PinballForge2DGame(gravity: Vector2.zero()), + ); + + group('PinballForge2DGame', () { + test('can instantiate', () { + expect( + () => PinballForge2DGame(gravity: Vector2.zero()), + returnsNormally, + ); + }); + + flameTester.test( + 'screenToFlameWorld throws UnimpelementedError', + (game) async { + expect( + () => game.screenToFlameWorld(Vector2.zero()), + throwsUnimplementedError, + ); + }, + ); + + flameTester.test( + 'screenToWorld throws UnimpelementedError', + (game) async { + expect( + () => game.screenToWorld(Vector2.zero()), + throwsUnimplementedError, + ); + }, + ); + + flameTester.test( + 'worldToScreen throws UnimpelementedError', + (game) async { + expect( + () => game.worldToScreen(Vector2.zero()), + throwsUnimplementedError, + ); + }, + ); + }); +} diff --git a/test/game/components/controlled_ball_test.dart b/test/game/components/controlled_ball_test.dart index 17178e87..cfb3e157 100644 --- a/test/game/components/controlled_ball_test.dart +++ b/test/game/components/controlled_ball_test.dart @@ -2,7 +2,6 @@ import 'package:bloc_test/bloc_test.dart'; import 'package:flame/extensions.dart'; -import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -15,7 +14,7 @@ import '../../helpers/helpers.dart'; // TODO(allisonryan0002): remove once // https://github.com/flame-engine/flame/pull/1520 is merged class _WrappedBallController extends BallController { - _WrappedBallController(Ball ball, this._gameRef) : super(ball); + _WrappedBallController(Ball ball, this._gameRef) : super(ball); final PinballGame _gameRef;