Class DestructibleTerrain

The user-facing destructible-terrain GameObject (Phase 3 minimum).

This first iteration owns:

Box2D physics integration (chunk colliders, debris bodies) is wired in by the next iteration. The renderer-only path in this iteration is useful on its own — for purely visual destructible terrain (no collision), or for early-development debugging while the physics setup is being staged.

Use update() from the scene's update loop. Carve/deposit operations mutate the bitmap synchronously; the renderer repaints dirty chunks on the next update().

Constructors

Properties

The underlying bitmap. Most users won't need direct access.

carve: {
    circle: ((cx: number, cy: number, r: number) => void);
    fromAlphaTexture: ((source: AlphaSource, dstX: number, dstY: number, threshold?: number) => void);
    polygon: ((points: readonly Point[]) => void);
} = ...

Carve facade: writes air into the bitmap.

deposit: {
    circle: ((cx: number, cy: number, r: number, materialId: number) => void);
    fromAlphaTexture: ((source: AlphaSource, dstX: number, dstY: number, materialId: number, threshold?: number) => void);
    polygon: ((points: readonly Point[], materialId: number) => void);
} = ...

Deposit facade: writes a material id into the bitmap.

originX: number

Top-left of the terrain in scene coordinates. Public-readable so consumers can convert between scene space and bitmap space (e.g. PixelPerfectSprite does this on overlap checks).

originY: number
physics: null | TerrainPhysics

Physics integration. null when no worldId was supplied at construction (visual-only terrain).

renderer: TerrainRenderer

The render layer. Exposed for advanced use (e.g. parallax).

Accessors

Methods

  • Detect every connected solid component that is not anchored, remove its cells from the bitmap, and (when physics is enabled) enqueue a dynamic body for each. Returns the detected debris with scene-coordinate contours and bounds so the caller can spawn visuals.

    Bodies appear on the next update() — the queue holds them until end-of-frame. The DestructibleTerrainOptions.onDebrisCreated callback fires once per body created.

    Parameters

    • anchor: undefined | AnchorStrategy = ...

      Flood-fill anchor strategy. Default: bottom row.

    • simplificationEpsilon: number = 1

      Douglas-Peucker epsilon for the extracted contours. Defaults to the terrain's simplificationEpsilon.

    Returns DebrisInfo[]

  • Runs one cellular-automaton tick over the bitmap. Materials with simulation: 'sand' (and any future fluid kinds) move; static materials don't. The tick counter is auto-incremented so successive calls alternate L/R bias.

    Cost: O(width × height) per call. For very large bitmaps, consider gating on a "are there any fluid pixels in flight?" flag.

    Returns void

  • Call once per frame from the scene's update(). Flushes pending collider rebuilds (if physics is enabled) and repaints any chunks carved / deposited since last frame.

    If autoSimulate was enabled at construction, runs one cellular-automaton tick BEFORE the rebuild flush so the static collider snapshot reflects the post-tick bitmap.

    The physics flush runs BEFORE the visual repaint because rebuilds only clear dirty (collider) and visuals only clear visualDirty — the order matters only insofar as it affects which dirty flag is read by which step. With both flushes per frame, the order is moot but documenting it for clarity.

    Returns void