How to Use Matter.Query.ray in Matter.js

Raycasting is an essential technique in 2D game development and physics simulations, commonly used for line-of-sight checks, weapon trajectories, and AI awareness. In the Matter.js physics engine, the Matter.Query.ray method provides a built-in way to cast a linear ray between two points and detect which bodies intersect that path. This guide explains the method signature, demonstrates how to execute a raycast query, and details how to handle the returned collision data.

Understanding the Method Signature

The Matter.Query.ray function takes a list of bodies and evaluates a segment defined by a start point and an end point:

Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])

Basic Implementation Example

To cast a ray, retrieve the active bodies in your engine world, define the start and end coordinates, and pass them to the query:

// 1. Get the list of bodies to test
const bodies = Matter.Composite.allBodies(engine.world);

// 2. Define the ray path
const startPoint = { x: 100, y: 100 };
const endPoint = { x: 500, y: 100 };

// 3. Perform the raycast
const collisions = Matter.Query.ray(bodies, startPoint, endPoint);

// 4. Process the results
if (collisions.length > 0) {
    collisions.forEach(collision => {
        // The body that was struck
        const hitBody = collision.body;
        console.log("Hit body ID:", hitBody.id);
    });
} else {
    console.log("No bodies intersected.");
}

Processing Collision Results

Matter.Query.ray returns an array of collision objects for every body intersecting the ray path. If no bodies are hit, it returns an empty array.

Each collision object in the array includes:

Note: Matter.Query.ray does not automatically sort hits by distance. If you need to find only the closest obstacle along the ray, calculate the distance between startPoint and each intersected body’s position or collision point, then pick the smallest value.

Using Thick Raycasting

To simulate a wider projectile or a detection beam, specify the optional rayWidth parameter:

const beamWidth = 20; // 20 pixels wide
const thickCollisions = Matter.Query.ray(bodies, startPoint, endPoint, beamWidth);

Using a wider ray detects bodies that pass close to the line segment even if the exact center line does not make contact.