componentsAtPoint method

Iterable<Component> componentsAtPoint(
  1. Vector2 point, [
  2. List<Vector2>? nestedPoints
])

An iterable of descendant components intersecting the given point. The point is in the local coordinate space.

More precisely, imagine a ray originating at a certain point (x, y) on the screen, and extending perpendicularly to the screen's surface into your game's world. The purpose of this method is to find all components that intersect with this ray, in the order from those that are closest to the user to those that are farthest.

The return value is an Iterable of components. If the nestedPoints parameter is given, then it will also report the points of intersection for each component in its local coordinate space. Specifically, the last element in the list is the point in the coordinate space of the returned component, the element before the last is in that component's parent's coordinate space, and so on. The nestedPoints list must be growable and modifiable.

The default implementation relies on the CoordinateTransform interface to translate from the parent's coordinate system into the local one. Make sure that your component implements this interface if it alters the coordinate system when rendering.

If your component overrides renderTree, then it almost certainly needs to override this method as well, so that this method can find all rendered components wherever they are.

Implementation

Iterable<Component> componentsAtPoint(
  Vector2 point, [
  List<Vector2>? nestedPoints,
]) sync* {
  nestedPoints?.add(point);
  if (_children != null) {
    for (final child in _children!.reversed()) {
      Vector2? childPoint = point;
      if (child is CoordinateTransform) {
        childPoint = (child as CoordinateTransform).parentToLocal(point);
      }
      if (childPoint != null) {
        yield* child.componentsAtPoint(childPoint, nestedPoints);
      }
    }
  }
  if (containsLocalPoint(point)) {
    yield this;
  }
  nestedPoints?.removeLast();
}