Skip to content

Sprite Game (Coin Collector)

Open the editor and paste this code to fly a ship and collect coins with sprites.

The Code

javascript
if (!state.init) {
  state.init = true;
  state.px = w / 2;
  state.py = h / 2;
  state.angle = 0;
  state.coins = [];
  state.score = 0;
  state.cooldown = 0;
}

// Spawn coins up to a cap
state.cooldown -= dt;
if (state.cooldown <= 0 && state.coins.length < 5) {
  state.coins.push({
    x: 40 + Math.random() * (w - 80),
    y: 40 + Math.random() * (h - 80),
  });
  state.cooldown = 0.4;
}

// Move the player with WASD / arrows, face the direction of travel
let dx = 0, dy = 0;
if (keys.ArrowLeft || keys.a) dx -= 1;
if (keys.ArrowRight || keys.d) dx += 1;
if (keys.ArrowUp || keys.w) dy -= 1;
if (keys.ArrowDown || keys.s) dy += 1;
if (dx || dy) {
  const len = Math.hypot(dx, dy);
  state.px += (dx / len) * 220 * dt;
  state.py += (dy / len) * 220 * dt;
  state.angle = Math.atan2(dy, dx);
}
state.px = Math.max(24, Math.min(w - 24, state.px));
state.py = Math.max(24, Math.min(h - 24, state.py));

// Collect coins in range
state.coins = state.coins.filter((c) => {
  if (Math.hypot(c.x - state.px, c.y - state.py) < 28) {
    state.score++;
    return false;
  }
  return true;
});

// Build the sprite list back-to-front
const sprites = [
  { asset: 'starfield', x: w / 2, y: h / 2, w: w, h: h },                     // background
  ...assets.tiles('tile-0', { cols: 4, rows: 2, size: 32, x: w / 2, y: h - 32 }), // floor
];
for (const c of state.coins) sprites.push({ asset: 'coin', x: c.x, y: c.y, w: 32, h: 32 });
sprites.push({ asset: 'ship-0', x: state.px, y: state.py, w: 48, h: 48, rotation: state.angle });

const text = { Score: String(state.score) };
if (keys.r || keys.R) state.init = false;
return { sprites, text };

Key Concepts

ConceptHow It's Used
sprites primitiveArray of images drawn in order — background first, ship last
assets.tilesLays out a centered 4×2 grid of 32px tiles for a floor
Center originSprite x / y is the center, so rotation spins the ship in place
RotationMath.atan2(dy, dx) points the ship toward movement
CollectionDistance check (Math.hypot) between ship and coin
Scalingw / h override the natural 16px / 32px asset sizes

Sprite Sheets

Sheets crop one frame with assets.frame(id, index, cols). sheet-tiles is a 12-column sheet of 16px tiles:

javascript
return {
  sprites: [
    // frame 0 of the sheet, drawn at 32x32
    { asset: 'sheet-tiles', x: 100, y: 100, w: 32, h: 32, src: assets.frame('sheet-tiles', 0, 12) },
  ],
}

assets.frame returns null when the index is out of range, so you can safely step through animation frames with Math.floor(time * speed) % totalFrames.

Tile Maps

For a whole level instead of a few sprites, assets.tilemap(id, map, opts) turns a 2D array into a centered grid of sprites — numbers index sheet frames, 0 / null is empty space:

javascript
const MAP = [
  [1, 1, 1, 1, 1, 1],
  [1, 0, 0, 0, 0, 1],
  [1, 0, 2, 0, 0, 1],
  [1, 1, 1, 1, 1, 1],
]
return {
  sprites: [...assets.tilemap('sheet-tiles', MAP, { tileSize: 32, x: w / 2, y: h / 2 })],
}

In the games editor, the Level button opens a visual editor (Pro) that paints these maps and drops items onto the canvas, then exports to level.js — the generated buildLevel(state, w, h) spreads assets.tilemap(...) into your sprites array.

Building Your Own Games

  • Platformer — tile grid for the world, a character sprite, flipX to face left/right
  • Shooter — ship sprite with rotation, muzzle / spark effect sprites for shots
  • RPGitems sprites (chest, gem, key) as pickups, dungeon tiles for the map
  • Effects — the effects category has star, flame, smoke, and magic for juice

See the Assets global reference and the Output Schema for the full sprites API.

See Also