Buernortey – Assignment 10

Concept

Erosion is a physics simulation of a rocky mesa breaking apart under falling debris. The idea came from thinking about how landscapes that look permanent are always being shaped by small, repeated impacts over time. I wanted to use Matter.js not just to show objects falling but to model a process. The terrain starts whole and breaks down based on how hard things hit it.

Code I Am Proud Of

The collision event handler is the center of the piece. It does not react to every contact. It reads the speed of the incoming rock and only shatters a terrain block when the impact crosses a threshold. This makes the simulation feel grounded. Slow rocks bounce off. Fast rocks break things.

 

Events.on(engine, 'collisionStart', function(event) {
  for (let pair of event.pairs) {
    let { bodyA, bodyB } = pair;
    let rock = null, ter = null;

    if (bodyA.label === 'rock' && bodyB.label === 'terrain') { rock = bodyA; ter = bodyB; }
    if (bodyB.label === 'rock' && bodyA.label === 'terrain') { rock = bodyB; ter = bodyA; }

    if (rock && ter) {
      let impactSpeed = Vector.magnitude(rock.velocity);
      if (impactSpeed > 3.5) {
        let idx = terrain.findIndex(t => t.body === ter && !t.broken);
        if (idx !== -1) shatterTerrain(idx, impactSpeed);
      }
    }
  }
});

 

I am also proud of the shatterTerrain function because it does three things at once when a block breaks. It triggers a screen shake scaled to the impact force, spawns a flash at the contact point, and sends out a burst of dust particles that drift upward and fade out. Each of those effects runs from the same impact speed value, so they all feel connected.

 

Embedded Sketch

Milestones and Challenges

The first milestone was drawing the terrain. I wrote a heightmap function that builds a mesa shape, peaks in the center, and slopes toward the edges, with small random offsets per column to roughen the silhouette. I added a sky gradient and a highlight strip on the top face of each block so the structure looked like real layered rock before any physics was involved.

The second milestone was loading that terrain into Matter.js as static bodies. Each block became a rectangle body placed at the correct position. Drawing them back from their body positions confirmed the physics world and the visual layer matched.

The third milestone was getting rocks to fall with physical variety. Rocks now vary in size, fall speed, bounciness, friction, and spin. Density scales with size so large boulders hit harder. Wind drifts slowly over time toward a random target every three seconds, and the visual rain streaks angle to match. This step exposed the first real challenge: collision filters. Without explicit category and mask values set on each body type, rocks passed straight through the terrain. Setting category: 0x0002 on terrain and mask: 0x0001 on terrain fixed which bodies could interact with which.

The fourth milestone was the full shattering system with visual feedback. When a collision event fires and the impact speed clears the threshold, the terrain block is removed, fragments spawn and tumble, dust particles burst outward, a flash appears at the contact point, and the canvas shakes. The main challenge here was performance. Without cleanup, thousands of fragment, dust, and rock bodies built up below the canvas over time and slowed the simulation. Adding a per-frame filter that removes any body or particle whose position exceeds the canvas height solved the problem completely.

Reflection

The piece works well as a slow process. Dropping one rock at a time and watching the terrain wear down has a satisfying quality. The storm mode makes the erosion visible in seconds and shows how the system handles high load. The wind system adds unpredictability without feeling random because it drifts gradually rather than jumping between values.

For future work I want to add water. Fragments that collect at the bottom could be slowly submerged as a rising water level fills the valleys left behind by the erosion. I also want to track how many blocks have been destroyed and show it as a live counter so the viewer has a sense of scale over the life of the simulation.

References

The Nature of Code, Chapter 6: Physics Libraries Matter.js documentation on collision events and body properties

Leave a Reply

Your email address will not be published. Required fields are marked *