Skip to content

Commit

Permalink
feat: Camera's Viewfinder can now be affected by rotation effects (#1527
Browse files Browse the repository at this point in the history
)
  • Loading branch information
st-pasha authored Apr 9, 2022
1 parent 403b6e6 commit f46cae0
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/flame/lib/effects.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 3 additions & 1 deletion packages/flame/lib/src/components/position_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 AngleProvider, PositionProvider, ScaleProvider {
PositionComponent({
Vector2? position,
Vector2? size,
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions packages/flame/lib/src/effects/provider_interfaces.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
8 changes: 6 additions & 2 deletions packages/flame/lib/src/effects/rotate_effect.dart
Original file line number Diff line number Diff line change
@@ -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.
///
Expand All @@ -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<AngleProvider>
implements MeasurableEffect {
RotateEffect.by(double angle, EffectController controller)
: _angle = angle,
super(controller);
Expand Down
5 changes: 4 additions & 1 deletion packages/flame/lib/src/experimental/viewfinder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions packages/flame/test/experimental/viewfinder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
},
);
});
}

Expand Down

0 comments on commit f46cae0

Please sign in to comment.