From f1d0a51c3331b558faf40b820723821fb15cfd94 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 16:17:57 -0700 Subject: [PATCH 1/4] Added AngleProvider --- packages/flame/lib/effects.dart | 2 +- packages/flame/lib/src/components/position_component.dart | 4 +++- packages/flame/lib/src/effects/provider_interfaces.dart | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/flame/lib/effects.dart b/packages/flame/lib/effects.dart index acaf9fd2974..6cad4ede50e 100644 --- a/packages/flame/lib/effects.dart +++ b/packages/flame/lib/effects.dart @@ -22,7 +22,7 @@ export 'src/effects/move_along_path_effect.dart'; export 'src/effects/move_effect.dart'; export 'src/effects/opacity_effect.dart'; export 'src/effects/provider_interfaces.dart' - show PositionProvider, ScaleProvider; + show PositionProvider, ScaleProvider, AngleProvider; export 'src/effects/remove_effect.dart'; export 'src/effects/rotate_effect.dart'; export 'src/effects/scale_effect.dart'; diff --git a/packages/flame/lib/src/components/position_component.dart b/packages/flame/lib/src/components/position_component.dart index 4f0c3a26893..71aa0bfb7c2 100644 --- a/packages/flame/lib/src/components/position_component.dart +++ b/packages/flame/lib/src/components/position_component.dart @@ -59,7 +59,7 @@ import 'component.dart'; /// do not specify the size of a PositionComponent, then it will be /// equal to zero and the component won't be able to respond to taps. class PositionComponent extends Component - implements PositionProvider, ScaleProvider { + implements PositionProvider, ScaleProvider, AngleProvider { PositionComponent({ Vector2? position, Vector2? size, @@ -110,7 +110,9 @@ class PositionComponent extends Component /// Rotation angle (in radians) of the component. The component will be /// rotated around its anchor point in the clockwise direction if the /// angle is positive, or counterclockwise if the angle is negative. + @override double get angle => transform.angle; + @override set angle(double a) => transform.angle = a; /// The scale factor of this component. The scale can be different along diff --git a/packages/flame/lib/src/effects/provider_interfaces.dart b/packages/flame/lib/src/effects/provider_interfaces.dart index 65109bba373..c7716183d0e 100644 --- a/packages/flame/lib/src/effects/provider_interfaces.dart +++ b/packages/flame/lib/src/effects/provider_interfaces.dart @@ -11,3 +11,9 @@ abstract class ScaleProvider { Vector2 get scale; set scale(Vector2 value); } + +/// Interface for a component that can be affected by rotation effects. +abstract class AngleProvider { + double get angle; + set angle(double value); +} From 5c2f7cbcee64f9e1c1477808c91f2fe72a8b8faa Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 16:19:37 -0700 Subject: [PATCH 2/4] RotateEffect now uses AngleProvider --- packages/flame/lib/src/effects/rotate_effect.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/flame/lib/src/effects/rotate_effect.dart b/packages/flame/lib/src/effects/rotate_effect.dart index eee14fa9ec5..e3eaa7ad827 100644 --- a/packages/flame/lib/src/effects/rotate_effect.dart +++ b/packages/flame/lib/src/effects/rotate_effect.dart @@ -1,6 +1,8 @@ import 'controllers/effect_controller.dart'; +import 'effect.dart'; +import 'effect_target.dart'; import 'measurable_effect.dart'; -import 'transform2d_effect.dart'; +import 'provider_interfaces.dart'; /// Rotate a component around its anchor. /// @@ -16,7 +18,9 @@ import 'transform2d_effect.dart'; /// This effect applies incremental changes to the component's angle, and /// requires that any other effect or update logic applied to the same component /// also used incremental updates. -class RotateEffect extends Transform2DEffect implements MeasurableEffect { +class RotateEffect extends Effect + with EffectTarget + implements MeasurableEffect { RotateEffect.by(double angle, EffectController controller) : _angle = angle, super(controller); From dff3a5b9bf8b78b7170817a727c64a219c1e4169 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 16:24:55 -0700 Subject: [PATCH 3/4] Viewfinder implements AngleProvider --- packages/flame/lib/src/components/position_component.dart | 2 +- packages/flame/lib/src/experimental/viewfinder.dart | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/flame/lib/src/components/position_component.dart b/packages/flame/lib/src/components/position_component.dart index 71aa0bfb7c2..a63dc9ec011 100644 --- a/packages/flame/lib/src/components/position_component.dart +++ b/packages/flame/lib/src/components/position_component.dart @@ -59,7 +59,7 @@ import 'component.dart'; /// do not specify the size of a PositionComponent, then it will be /// equal to zero and the component won't be able to respond to taps. class PositionComponent extends Component - implements PositionProvider, ScaleProvider, AngleProvider { + implements AngleProvider, PositionProvider, ScaleProvider { PositionComponent({ Vector2? position, Vector2? size, diff --git a/packages/flame/lib/src/experimental/viewfinder.dart b/packages/flame/lib/src/experimental/viewfinder.dart index 7ca936d2739..caee1bd2e63 100644 --- a/packages/flame/lib/src/experimental/viewfinder.dart +++ b/packages/flame/lib/src/experimental/viewfinder.dart @@ -15,7 +15,8 @@ import 'camera_component.dart'; /// The viewfinder contains the game point that is currently at the /// "cross-hairs" of the viewport ([position]), the [zoom] level, and the /// [angle] of rotation of the camera. -class Viewfinder extends Component implements PositionProvider, ScaleProvider { +class Viewfinder extends Component + implements AngleProvider, PositionProvider, ScaleProvider { /// Internal transform matrix used by the viewfinder. final Transform2D _transform = Transform2D(); @@ -47,7 +48,9 @@ class Viewfinder extends Component implements PositionProvider, ScaleProvider { /// Rotation angle of the game world, in radians. /// /// The rotation is around the axis that is perpendicular to the screen. + @override double get angle => -_transform.angle; + @override set angle(double value) => _transform.angle = -value; /// The point within the viewport that is considered the "logical center" of From 10429d93d6d44d8484fbc9a32168fc4a9e88dcde Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 16:28:16 -0700 Subject: [PATCH 4/4] Add a test --- .../test/experimental/viewfinder_test.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/flame/test/experimental/viewfinder_test.dart b/packages/flame/test/experimental/viewfinder_test.dart index b1978c91634..366883fd1f2 100644 --- a/packages/flame/test/experimental/viewfinder_test.dart +++ b/packages/flame/test/experimental/viewfinder_test.dart @@ -179,6 +179,23 @@ void main() { } }, ); + + testWithFlameGame( + 'camera rotate effect', + (game) async { + final world = World()..addToParent(game); + final camera = CameraComponent(world: world)..addToParent(game); + camera.viewfinder.add( + RotateEffect.by(1, EffectController(duration: 1)), + ); + await game.ready(); + + for (var t = 0.0; t < 1.0; t += 0.1) { + expect(camera.viewfinder.angle, closeTo(t, 1e-15)); + game.update(0.1); + } + }, + ); }); }