Skip to content

Commit

Permalink
Add optional world input to canSee
Browse files Browse the repository at this point in the history
  • Loading branch information
ufrshubham committed Jul 21, 2023
1 parent 2ee0282 commit 76c1dae
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 44 deletions.
41 changes: 18 additions & 23 deletions packages/flame/lib/src/camera/camera_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,29 +284,24 @@ class CameraComponent extends Component {
}

/// Returns true if this camera is able to see the [component].
///
/// Will return false if the component does not belong to the [world] this
/// camera is looking at.
///
/// For components deeply nested in the world, consider use the [HasAncestor]
/// or [ParentIsA] mixin with [World] type to make the world lookup faster.
bool canSee(PositionComponent component) {
if (world == null || !component.isMounted) {
return false;
}

World? componentWorld;

// Try to find which world the given component belongs to.
if (component is ParentIsA<World>) {
componentWorld = (component as ParentIsA<World>).parent;
} else if (component is HasAncestor<World>) {
componentWorld = (component as HasAncestor<World>).ancestor;
} else {
componentWorld = component.findParent<World>();
}

if (world != componentWorld) {
///
/// Will always return false if
/// - [world] is null or
/// - [world] is not mounted or
/// - [component] is not mounted or
/// - [componentWorld] is non-null and does not match with [world]
///
/// If [componentWorld] is null, this method does not take into consideration
/// the world to which the given [component] belongs (if any). This means, in
/// such cases, any component overlapping the [visibleWorldRect] will be
/// reported as visible, even if it is not part of the [world] this camera is
/// currently looking at. This can be changed by passing the the component's
/// world as [componentWorld].
bool canSee(PositionComponent component, {World? componentWorld}) {
if (world == null ||
!world!.isMounted ||
!component.isMounted ||
(componentWorld != null && componentWorld != world)) {
return false;
}

Expand Down
41 changes: 20 additions & 21 deletions packages/flame/test/camera/camera_component_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -326,45 +326,48 @@ void main() {
expect(camera.canSee(player), true);
});

testWithFlameGame('unmounted component', (game) async {
testWithFlameGame('unmounted world', (game) async {
final player = PositionComponent();
final world = World();
final world = World(children: [player]);
final camera = CameraComponent(world: world);

await game.addAll([camera, world]);
await game.addAll([camera]);
await game.ready();
expect(camera.canSee(player), false);

await world.add(player);
await game.add(world);
await game.ready();
expect(camera.canSee(player), true);
});

testWithFlameGame('component with parent world', (game) async {
final player = _ParentIsAWorld();
final world = World(children: [player]);
final camera = CameraComponent();
testWithFlameGame('unmounted component', (game) async {
final player = PositionComponent();
final world = World();
final camera = CameraComponent(world: world);

await game.addAll([camera, world]);
await game.ready();
expect(camera.canSee(player), false);

camera.world = world;
await world.add(player);
await game.ready();
expect(camera.canSee(player), true);
});

testWithFlameGame('component with ancestor world', (game) async {
final player = _HasAncestorWorld();
final level = PositionComponent(children: [player]);
final world = World(children: [level]);
final camera = CameraComponent();
testWithFlameGame('component from another world', (game) async {
final player = PositionComponent();
final world1 = World(children: [player]);
final world2 = World();
final camera = CameraComponent(world: world2);

await game.addAll([camera, world]);
await game.addAll([camera, world1, world2]);
await game.ready();
expect(camera.canSee(player), false);

camera.world = world;
// can see when player world is not known.
expect(camera.canSee(player), true);

// can't see when the player world is known.
expect(camera.canSee(player, componentWorld: world1), false);
});
});
}
Expand All @@ -375,7 +378,3 @@ class _SolidBackground extends Component with HasPaint {
@override
void render(Canvas canvas) => canvas.drawColor(color, BlendMode.src);
}

class _HasAncestorWorld extends PositionComponent with HasAncestor<World> {}

class _ParentIsAWorld extends PositionComponent with ParentIsA<World> {}

0 comments on commit 76c1dae

Please sign in to comment.