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

docs: Add interactive example for Anchor #2523

Merged
merged 10 commits into from
May 1, 2023
36 changes: 36 additions & 0 deletions doc/flame/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,48 @@ Right/East| pi/2 | 90

### Anchor

```{flutter-app}
:sources: ../flame/examples
:page: anchor
:show: widget code infobox
This example shows effect of changing `anchor` point of parent (red) and child (blue)
components. Tap on them to cycle through the anchor points. Note that the local
position of the child component is (0, 0) at all times.
```

The `anchor` is where on the component that the position and rotation should be defined from (the
default is `Anchor.topLeft`). So if you have the anchor set as `Anchor.center` the component's
position on the screen will be in the center of the component and if an `angle` is applied, it is
rotated around the anchor, so in this case around the center of the component. You can think of it
as the point within the component by which Flame "grabs" it.

When `position` or `absolutePosition` of a component is queried, the returned coordinates are that of
the `anchor` of the component. In case if you want to find the position of a specific anchor point
of a component which is not actually the `anchor` of that component, you can use the `positionOfAnchor`
and `absolutePositionOfAnchor` method.

```dart
final comp = PositionComponent(
size: Vector2.all(20),
anchor: Anchor.center,
);

// Returns (0,0)
final p1 = component.position;

// Returns (10, 10)
final p2 = component.positionOfAnchor(Anchor.bottomRight);
```

A common pitfall when using `anchor` is confusing it for as being the attachment point for children
components. For example, setting `anchor` to `Anchor.center` for a parent component does not mean
that the children components will be placed w.r.t the center of parent.

```{note}
Local origin for a child component is always the top-left corner of its parent component,
irrespective of their `anchor` values.
```


### PositionComponent children

Expand Down
69 changes: 69 additions & 0 deletions doc/flame/examples/lib/anchor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'dart:async';

import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/palette.dart';

class AnchorGame extends FlameGame {
final _parentAnchorText = TextComponent(position: Vector2.all(5));
final _childAnchorText = TextComponent(position: Vector2(5, 30));

late _AnchoredRectangle _redComponent;
late _AnchoredRectangle _blueComponent;

@override
Future<void> onLoad() async {
_redComponent = _AnchoredRectangle(
size: size / 4,
position: size / 2,
paint: BasicPalette.red.paint(),
);

_blueComponent = _AnchoredRectangle(
size: size / 8,
paint: BasicPalette.blue.paint(),
);

await _redComponent.addAll([
_blueComponent,
CircleComponent(radius: 2, anchor: Anchor.center),
]);

await addAll([
_redComponent,
_parentAnchorText,
_childAnchorText,
CircleComponent(
radius: 4,
position: size / 2,
anchor: Anchor.center,
)
]);
}

@override
void update(double dt) {
_parentAnchorText.text = 'Parent: ${_redComponent.anchor}';
_childAnchorText.text = 'Child: ${_blueComponent.anchor}';
super.update(dt);
}
}

class _AnchoredRectangle extends RectangleComponent with TapCallbacks {
_AnchoredRectangle({
super.position,
super.size,
super.paint,
});

@override
void onTapDown(TapDownEvent event) {
var index = Anchor.values.indexOf(anchor) + 1;
if (index == Anchor.values.length) {
index = 0;
}
anchor = Anchor.values.elementAt(index);
super.onTapDown(event);
}
}
2 changes: 2 additions & 0 deletions doc/flame/examples/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:html'; // ignore: avoid_web_libraries_in_flutter

import 'package:doc_flame_examples/anchor.dart';
import 'package:doc_flame_examples/anchor_by_effect.dart';
import 'package:doc_flame_examples/anchor_to_effect.dart';
import 'package:doc_flame_examples/collision_detection.dart';
Expand Down Expand Up @@ -73,6 +74,7 @@ void main() {
'remove_effect': RemoveEffectGame.new,
'color_effect': ColorEffectExample.new,
'time_scale': TimeScaleGame.new,
'anchor': AnchorGame.new,
};
final game = routes[page]?.call();
if (game != null) {
Expand Down