LeCodesdocs

Scene2D

A 2D world: a draw set plus an orthographic Camera2D. Opening a scene brings up the 2D engine on the canvas and starts rendering; only one scene is active at a time. Not to be confused with Scene (the 3D world).

At a glance

TypeScript
const scene = new Scene2D({ background: '#10131a' })
scene.layer(1).ySort()                 // layer 1 sorts top-down by Y

const tex = await Texture2D.load(asset('./hero.png'))
const hero = new Sprite({ texture: tex, anchor: [0.5, 1], layer: 1 })
scene.add(hero)

scene.addEventListener('click', ev => {
  console.log('tapped', ev.target?.id ?? 'empty space', 'at world', ev.worldX, ev.worldY)
})
scene.open()

Creating

TypeScript
new Scene2D(options?: {
  background?: ColorInput          // clear color
  filter?: 'nearest' | 'linear'    // texture sampling; default nearest (crisp pixel art)
})

scene.background = '#10131a'       // settable later too
scene.camera                       // the scene's Camera2D (readonly)
Note

filter is a global renderer setting — one sampler for all textures, not per-texture. It is (re)applied on open(), so the currently-open scene's choice wins. Use 'linear' for hi-res / non-pixel-art assets; omit to leave the current setting.

Opening & closing

TypeScript
scene.open(): this          // make active: brings up the 2D engine, closes any other scene
scene.close(): this         // stop rendering this scene
scene.destroy(): void       // close + free the native scene
Scene2D.active              // static: the currently open Scene2D, or null

Nodes

TypeScript
scene.add(...nodes: Node2D[]): this
scene.remove(...nodes: Node2D[]): this

Adds/removes root-level Node2Ds. Child nodes come along with their parent — only roots need scene.add.

Layers & Y-sort

TypeScript
scene.layer(n).ySort(enabled = true): LayerHandle

Nodes pick their layer with node.layer (higher layers draw on top; within a layer, node.z orders). Calling .ySort() on a layer switches it to top-down depth sorting: sprites lower on screen overlap sprites higher up — the classic "characters walk behind trees" look.

Note

Y-sort compares node positions, i.e. anchor points. Give characters and props on a Y-sorted layer a bottom-center anchor (anchor: [0.5, 1] — the "feet") so depth sorts where they touch the ground.

Picking

TypeScript
scene.pick(worldPoint: Vec2Like): Node2D | null

Topmost visible sprite whose world bounds contain the point — a body-free hit-test, no physics needed. Pair with scene.camera.screenToWorld() to convert a tap position.

For automatic pointer dispatch to nodes, give the node a physics body instead — see picking in 2D physics.

Scene-level pointer events

TypeScript
scene.addEventListener('click', (ev: ClickEvent) => void)          // pointer-up anywhere in the scene
scene.addEventListener('touchstart', (ev: TouchStartEvent) => void) // pointer-down; ev.track() for drags
scene.removeEventListener(channel, callback)

The handler fires for every tap/press in the scene; ev.target is the hit physics-body node or null (empty space). ev.worldX / ev.worldY give the hit point in world space. On 'touchstart' call ev.track({...}) to capture the drag — see pointer events & gestures.

See also