LeCodesdocs

Sprite

A textured 2D node — the workhorse of a 2D scene. Extends Node2D, so it has the full transform, hierarchy, events, and aspect surface. Sprite-sheet animation is not built in: attach the SpriteAnimation aspect.

At a glance

TypeScript
const tex = await Texture2D.load(asset('./hero.png'))

const hero = new Sprite({ texture: tex, anchor: [0.5, 1], layer: 1 })
  .aspect(SpriteAnimation, { size: [32, 48], fps: 10, clips: { idle: [0], walk: [1, 2, 3, 4] } })
hero.position = [120, 64]
hero.anim.play('walk')
scene.add(hero)

Creating

TypeScript
new Sprite(options?: {
  texture?: Texture2D | Canvas   // a Canvas bakes to a texture on assign
  anchor?: Vec2Like              // pivot: [0,0] top-left … [1,1] bottom-right; default [0.5, 0.5]
  size?: Vec2Like                // world size; default = the texture's pixel dimensions
  frame?: [u0, v0, u1, v1]       // normalized UV sub-rect
  color?: ColorInput             // tint, multiplied with the texture
  opacity?: number               // 0..1
  layer?: number                 // draw layer (see Scene2D layers)
  position?: Vec2Like
})
Note

anchor space is Y-down even though the world is Y-up: [0.5, 1] is the sprite's bottom-center ("feet"). Use it for anything on a Y-sorted layer so depth sorts by feet.

Texture & size

TypeScript
sprite.texture = tex             // Texture2D, or a Canvas (baked on assign)
sprite.size = [w, h]             // world units; resets native default when texture changes
  • Default size is the texture's pixel dimensions — 1 texel = 1 world unit = 1 logical px at zoom 1.
  • A Canvas-backed sprite defaults to the canvas's logical size, so pixelRatio on the canvas affects crispness only, never on-screen size. See Canvas.

Frames (atlases / spritesheets)

TypeScript
sprite.frame = [u0, v0, u1, v1]        // normalized UV sub-rect
sprite.setFramePx(x, y, w, h): this    // sub-rect in texture pixels — chainable

setFramePx is the one to use with an atlas: coordinates match what an image editor shows. Changing the frame does not change size — set size once to the frame's pixel dimensions if you want unscaled output.

For frame-by-frame animation, don't drive frame yourself — attach SpriteAnimation and define clips.

Appearance

TypeScript
sprite.color = '#ff8800'    // tint (multiplied); default white = untinted
sprite.opacity = 0.5        // 0..1
sprite.flipX = true         // mirror horizontally (facing left/right without negative scale)
sprite.flipY = true

Pitfalls

TypeScript
// ✗ expecting scale to affect physics — Shape2D extents are raw world units, unscaled
sprite.scale = 2   // draws 2×, but its physics box stays the size you declared

// ✗ per-frame texture swaps for animation
setLoop(() => sprite.setFramePx(...))   // works, but re-implements SpriteAnimation poorly

See also