Raycasting with Flame

Lim Chee Keen
2 min readFeb 27, 2024

--

This article is part of the series Building a 2d-top down RPG with Flutter and Flame.

The idea of a Raycast in Flame is straightforward(pun intended) — a straight line from a point is ‘shot out’ at a specific vector and returns the first hitbox it meets. You can check out the docs here.

If your game needs any of these, you need a raycast:

  1. Dectect the object that the player is ‘looking’ at in 2d space.
  2. Distance between a point of interest and a dynamic point. The dynamic point could be null or objects that is undetermined at compile time.
  3. Determining the angle of reflection when an object bounces off a surface.
  4. Detecting objects that are x distance away from a point.

For Gomiland, the player can interact with 3 objects, namely, non-player characters (NPCs), trash on the ground and signs. Below is the method for the raycast. Note that the Gomiland player also has a hitbox. If the raycast is send from the centre of the player, the player hitbox will be returned everytime. Thus, we must ignore that specific hitbox.

class GomilandGame extends FlameGame
with HasCollisionDetection, // this mixin is required for the raycast
HasKeyboardHandlerComponents {
...
void castRay() {
...
Vector2 origin = playerPosition;
final ray = Ray2(
origin: origin,
direction: playerDirection,
);
final RaycastResult<ShapeHitbox>? result = collisionDetection.raycast(
ray,
maxDistance: maxRaycastDist,
// player's own hitbox is ignored
ignoreHitboxes: playerHitbox != null ? [playerHitbox] : null,
);
// check if ray has hit a hitbox
if (result != null && result.hitbox != null) {
// do something if a hitbox is detected
_onRaycastHit(result.hitbox!, playerPosition);
}
}
...
}

Simple enough but during development I could not detect hitboxes with my raycast. I made a no-so-obvious mistake and the developers of the Flame engine kindly explain why in this thread. Basically, only classes with the HasCollisionDetection mixin has access to the method collisionDetection.raycast() . Do NOT add this mixin to multiple classes to get this method. The reason is hitboxes that are added in that component’s tree will only be compared to other hitboxes in that subtree as stated in the docs.

The result will look like this. (Red line is to visualise the ray only. It does not appear in the actual game.)

A ray is cast when the A button is pressed

That’s it! For more features in an RPG, check out the main article here. Good luck!

--

--

Lim Chee Keen

Former Navy Captain Turned Software Engineer | Flutter & React developer | ML & AI programmer | Co-founder for Group Buy service