Create Multiple Sprites from a Spritesheet in Pixi.js

Using a single spritesheet is an efficient way to manage game assets and improve rendering performance in Pixi.js. This article provides a straightforward guide on how to load a spritesheet and extract multiple independent sprites from it. You will learn both the standard method using a JSON atlas and the manual cropping method using texture rectangles, allowing you to control and animate each sprite individually.

The most efficient and common way to handle spritesheets in Pixi.js is by using a JSON atlas file alongside your image. The JSON file defines the coordinates and dimensions of each sprite frame.

1. Load the Spritesheet

Use the Pixi.js Assets utility to load the JSON file. Pixi.js automatically parses the JSON and generates the individual textures for you.

import { Assets, Sprite, Application } from 'pixi.js';

// Initialize PixiJS Application
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);

// Load the spritesheet JSON
const spritesheet = await Assets.load('assets/spritesheet.json');

2. Create Independent Sprites

Once loaded, you can access the pre-cut textures directly from the spritesheet object and assign them to new, independent sprite instances.

// Create independent sprites using the texture keys defined in the JSON
const heroSprite = new Sprite(spritesheet.textures['hero_idle.png']);
const enemySprite = new Sprite(spritesheet.textures['enemy_walk.png']);

// Position and modify them independently
heroSprite.x = 100;
heroSprite.y = 150;

enemySprite.x = 300;
enemySprite.y = 150;
enemySprite.scale.set(1.5);

// Add them to the stage
app.stage.addChild(heroSprite);
app.stage.addChild(enemySprite);

Method 2: Manual Texture Cropping (No JSON)

If you do not have a JSON file and only have a grid-based image, you can manually slice the base texture into individual textures using Pixi.js Rectangle geometry.

1. Load the Base Texture

First, load the entire image as a base texture.

import { Texture, Rectangle, Sprite, Application } from 'pixi.js';

const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);

// Load the master image texture
const baseTexture = await Assets.load('assets/grid_spritesheet.png');

2. Crop and Instantiate independent Sprites

Define the rectangular regions (x, y, width, height) of the sprites on the sheet and create new Texture instances from them.

// Define frame dimensions
const frameWidth = 64;
const frameHeight = 64;

// Create textures for specific regions of the master image
const textureRegion1 = new Texture({
    source: baseTexture.source,
    frame: new Rectangle(0, 0, frameWidth, frameHeight) // Row 1, Col 1
});

const textureRegion2 = new Texture({
    source: baseTexture.source,
    frame: new Rectangle(frameWidth, 0, frameWidth, frameHeight) // Row 1, Col 2
});

// Create independent sprites
const spriteA = new Sprite(textureRegion1);
const spriteB = new Sprite(textureRegion2);

// Position them independently
spriteA.position.set(50, 50);
spriteB.position.set(150, 50);

app.stage.addChild(spriteA);
app.stage.addChild(spriteB);

By utilizing either of these two methods, every sprite created operates as a separate object in the display list. You can change their positions, scales, rotations, and alpha properties independently without affecting the other sprites sharing the same source image.