Skip to content

Commit

Permalink
docs: Add interactive example for Anchor (#2523)
Browse files Browse the repository at this point in the history
This PR add an interactive example to show the parent child relationship when their anchors are changed. It also elaborates the same in written docs as well.
  • Loading branch information
ufrshubham authored May 1, 2023
1 parent 01121c2 commit a4f60a8
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
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

0 comments on commit a4f60a8

Please sign in to comment.