Sprite Game (Coin Collector)
Open the editor and paste this code to fly a ship and collect coins with sprites.
The Code
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
| Concept | How It's Used |
|---|---|
sprites primitive | Array of images drawn in order — background first, ship last |
assets.tiles | Lays out a centered 4×2 grid of 32px tiles for a floor |
| Center origin | Sprite x / y is the center, so rotation spins the ship in place |
| Rotation | Math.atan2(dy, dx) points the ship toward movement |
| Collection | Distance check (Math.hypot) between ship and coin |
| Scaling | w / 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:
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:
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,
flipXto face left/right - Shooter — ship sprite with rotation,
muzzle/sparkeffect sprites for shots - RPG —
itemssprites (chest, gem, key) as pickups,dungeontiles for the map - Effects — the
effectscategory hasstar,flame,smoke, andmagicfor juice
See the Assets global reference and the Output Schema for the full sprites API.
See Also
- Assets API -
assets.image,assets.frame,assets.tiles,assets.tilemap - Sprites primitive - all sprite options
- Keyboard Input - controlling your game
- Snake Game - a grid-based game without sprites