How to Change Gravity Scale on the Fly in Matter.js

This guide explains how to dynamically change the gravity scale and direction during runtime in a Matter.js physics simulation. You can manipulate global gravity at any moment without reinitializing the engine, enabling interactive mechanics such as zero-gravity zones, gravity inversion, and dynamic environmental forces.

Yes, Gravity Can Be Modified on the Fly

Matter.js supports real-time updates to its physics parameters. The simulation calculates gravitational force on each tick based on the properties stored in the engine.gravity object. By directly reassigning these properties during runtime, the physics world updates immediately on the next step.

Key Gravity Properties

The engine.gravity object controls both the intensity and direction of gravity across the entire world:

Code Examples

1. Changing the Gravity Scale

To make gravity twice as strong or completely turn it off, update the scale property directly:

// Disable gravity (Zero-G)
engine.gravity.scale = 0;

// Restore standard gravity
engine.gravity.scale = 0.001;

// Double standard gravity
engine.gravity.scale = 0.002;

2. Inverting or Redirecting Gravity

You can also change the direction on the fly by updating the x and y properties:

// Reverse gravity so objects fall upward
engine.gravity.y = -1;

// Pull objects to the right
engine.gravity.x = 1;
engine.gravity.y = 0;

3. Dynamic Runtime Trigger

Here is how you can toggle gravity dynamically using an event listener, such as a key press:

window.addEventListener('keydown', (event) => {
  if (event.code === 'Space') {
    // Toggle between standard gravity and zero-gravity
    engine.gravity.scale = engine.gravity.scale === 0 ? 0.001 : 0;
  }

  if (event.code === 'KeyR') {
    // Invert vertical gravity
    engine.gravity.y *= -1;
  }
});

Considerations for Individual Bodies

Modifying engine.gravity impacts every dynamic body in the world simultaneously. If you want a specific body to ignore global gravity changes, set its ignoreGravity property:

const body = Matter.Bodies.rectangle(400, 200, 50, 50);
body.ignoreGravity = true;

For fine-grained, per-body directional gravity, keep engine.gravity.scale = 0 and manually apply directed forces using Matter.Body.applyForce() inside a beforeUpdate event listener.