How to Apply Continuous Force in Matter.js

This article explains how to apply a continuous force to a physics body using Matter.js. By leveraging the engine's internal update cycle and the Matter.Body.applyForce function, you can simulate constant physical effects such as custom gravity, jet propulsion, wind, or constant acceleration.

In Matter.js, the Body.applyForce(body, position, force) function applies a force vector to a body for a single engine update step. Because physics engines reset net forces each frame, calling this method only once results in an instantaneous impulse rather than continuous movement.

To apply a continuous force, you must invoke Body.applyForce inside the beforeUpdate event listener provided by the Matter.Events module. This ensures the force is reapplied before the engine calculates physics for the upcoming frame.

Here is a complete implementation:

const { Engine, Render, Runner, Bodies, Composite, Body, Events } = Matter;

// Create an engine and world
const engine = Engine.create();
const world = engine.world;

// Create a renderer
const render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        wireframes: false
    }
});

Render.run(render);

// Create runner
const runner = Runner.create();
Runner.run(runner, engine);

// Create a body to receive continuous force
const box = Bodies.rectangle(400, 500, 50, 50, {
    restitution: 0.5
});

Composite.add(world, box);

// Apply a continuous upward force (e.g., a thruster)
Events.on(engine, 'beforeUpdate', () => {
    const forceMagnitude = 0.002 * box.mass;
    
    Body.applyForce(
        box,
        box.position, // Point where the force is applied (center of mass)
        { x: 0, y: -forceMagnitude } // Direction and magnitude (negative Y is upward)
    );
});

Key Parameters and Considerations

  1. Application Point: The second argument defines where the force hits the body. Using box.position applies the force directly to the body's center of mass, moving it linearly without unintended rotation. Using an offset position will generate torque and cause the body to spin.
  2. Magnitude Scale: Forces in Matter.js must be relatively small. A force magnitude between 0.0005 and 0.05 is typical. Scaling the force relative to body.mass ensures predictable acceleration regardless of the object's weight.
  3. Cancellation: To stop applying the force, either remove the event listener using Events.off(engine, 'beforeUpdate', listenerCallback) or wrap the application logic within a conditional statement based on your application's state.