← Examples · Ship Pack · How this page works

PixiJS 8

Arrow keys: ← → turn, ↑ thrust, ↓ brake. One texture per frame, cut from the sheet.

Ships from the Yodacon Ship Pack by Paul Richeson (ConEx, 1997), GPL-2.0-or-later — github.com/yodacon/yodacon-ship-pack

Yodacon Ship Pack · Tutorial Note 7 · October 2026

Thirty-Six Textures on One Image: How the PixiJS Example Uses the Pack

Abstract—The PixiJS example loads a pack ship's sheet-alpha.png once, cuts it into 36 textures that share one source using the library's frameRect(), and flies a sprite by swapping its texture each tick. This note follows the page's source.

Index Terms—PixiJS, texture atlases, sprite sheets, pixel art.

I. Introduction

PixiJS draws sprites from textures, and a texture can frame part of a shared image. The PixiJS example uses that to turn the pack's sheet into 36 textures over one GPU upload, then flies a sprite by swapping its texture. PixiJS 8.6.6 is imported from a pinned URL (index.html:32).

II. Assets Used

Table I. What the page takes from the pack
AssetRead atUsed for
ship.jsonindex.html:36Frame grid, stats, name
sheet-alpha.pngindex.html:50One texture source
frameRect(), frameIndex()index.html:33Cells and frame choice

III. Pixel Art First

Before any texture exists, the default sampling is set to nearest-neighbour (index.html:41), and the application is created without antialiasing (index.html:45). Every texture made afterwards keeps the 1997 pixels square.

IV. Thirty-Six Textures, One Source

Assets.load loads the sheet once. Each frame is then a Texture that shares the sheet's source and frames one cell, with the rectangle from the library's frameRect() (Listing 1):

(x, y, w, h) = ((f mod 6) · w, ⌊f / 6⌋ · h, w, h)(1)

Listing 1. Cutting the sheet, index.html:50–54
50const sheet = await Assets.load(ship.urls.sheet);51const frames = Array.from({ length: 36 }, (_, i) => {52  const r = frameRect(ship, i);53  return new Texture({ source: sheet.source, frame: new Rectangle(r.x, r.y, r.w, r.h) });54});

Because all 36 share one source, the GPU holds one image, and switching frames costs nothing but a pointer.

V. The Sprite

The sprite starts on frame 0 with its anchor at the centre, so it turns about its middle, and a whole-number scale (index.html:61–63).

VI. Each Tick

The ticker turns the heading, picks f = frameIndex(θ) and assigns frames[f] to the sprite (Listing 2). As in every example, sprite.rotation stays 0. Thrust follows the frame shown, along (sin a, −cos a) with a = 10f°.

Listing 2. The ticker, index.html:75–84
75app.ticker.add((ticker) => {76  const dt = Math.min(ticker.deltaMS / 1000, 0.1);77  if (keys.ArrowLeft) heading -= TURN * dt;78  if (keys.ArrowRight) heading += TURN * dt;79  heading = (heading + 360) % 360;80  const frame = frameIndex(heading);81  sprite.texture = frames[frame];                  // swap the frame; never set sprite.rotation8283  const a = (frame * 10 * Math.PI) / 180;            // heading 0 = up, clockwise84  if (keys.ArrowUp) { vx += Math.sin(a) * ACCEL * dt; vy -= Math.cos(a) * ACCEL * dt; }

VII. Using It in Your Project

  1. Set scaleMode = "nearest" before loading.
  2. Assets.load the sheet; build the 36 frame textures once per ship type.
  3. Give every ship its own Sprite and assign frames[frameIndex(heading)].

Pixi's AnimatedSprite takes the same array if you want a ship that simply spins.

VIII. Conclusion

The sheet becomes an array of textures indexed by Equation (1)'s frame number; from there the pack ship is an ordinary Pixi sprite.

References

  1. Yodacon Ship Pack, “From sprite sheet to moving ship,” Tutorial Note 1, examples/, 2026. examples/#tutorial
  2. Yodacon Ship Pack, lib/yodacon-ship-pack.js, v2.0.0, 2026.
  3. PixiJS authors, PixiJS v8.6.6, 2024. [Online]. Available: pixijs.com