Introduction

Game Status: Not Started

Lesson

Spline Barriers

A SplineBarrier is a curved wall you can place anywhere in your scene. Unlike a normal rectangle Barrier, a SplineBarrier follows a smooth curve defined by a list of control points — letting you build slopes, arches, winding paths, and organic terrain boundaries.


How It Works

1 Defining the Curve with Control Points

When you create a SplineBarrier, you pass in a splinePoints array — a list of { x, y } coordinates that act as anchors along the path:

jsconst barrier = new SplineBarrier({
    id: 'cliff_edge',
    color: '#8B4513',
    lineWidth: 5,
    splinePoints: [
        { x: 50,  y: 400 },
        { x: 200, y: 300 },
        { x: 400, y: 350 },
        { x: 600, y: 200 },
    ]
}, gameEnv);

These points are not connected with straight lines. Instead, the barrier computes a smooth curve through them using Catmull-Rom spline interpolation.


2 Catmull-Rom Interpolation

The magic behind the smooth curve is the catmullRom() static method. It generates a point on the curve between two anchors (P1P2), using their neighbors (P0, P3) as tension guides:

t = 0.0  →  start of segment (at P1)
t = 1.0  →  end of segment   (at P2)

By sampling this function many times per segment (default: 50 samples), getCurvePoints() builds a dense array of positions that forms the rendered and collidable curve. The more segments, the smoother and more collision-accurate the barrier.

You define anchors (ie key points) and the engine fills in the curve between them automatically!!

3 Rendering

Each SplineBarrier owns its own dedicated <canvas> element, layered above the game background (z-index: 15). On every frame, draw() clears that canvas and redraws the full curve using the computed points.

This is intentionally separate from the main game canvas so the barrier doesn’t interfere with other rendering layers and can be toggled via visible. This is for debugging purposes — you can set visible: false to hide the curve while keeping its collision active.


4 Collision Detection

SplineBarrier does not use the engine’s standard rectangular hitbox. Both collisionChecks() and isCollision() are overridden to do nothing — rectangular collision is irrelevant for a curved boundary.

Instead, update() runs its own proximity check every frame:

  1. Finds the Player object in gameEnv.gameObjects
  2. Gets the player’s center position
  3. Iterates over all curve points
  4. If the player is within 20 pixels of any curve point, a collision is triggered

On collision, the player is pushed away from the nearest curve point along the vector between them:

push direction = normalize(playerCenter − collisionPoint) × pushStrength

This gives the illusion of a solid wall without needing a polygon collider.


Configuration Options

Property Type Default Description
splinePoints Array<{x,y}> simple fallback curve The control points defining the path
color string '#8B4513' Stroke color of the rendered curve
lineWidth number 5 Width of the rendered line in pixels
visible boolean true Whether the curve is drawn each frame
id string 'spline_barrier' Canvas element ID