Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Camera's Viewfinder can now be affected by rotation effects #1527

Merged
merged 4 commits into from
Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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