Creating sprites from a loaded texture atlas
Pixi gives you three general ways to create a sprite from a texture atlas:
- Using
TextureCache
:
let texture = TextureCache["frameId.png"],
sprite = new Sprite(texture);
- If you’ve used Pixi’s
loader
to load the texture atlas, use the loader’sresources
:
let sprite = new Sprite(
resources["images/treasureHunter.json"].textures["frameId.png"]
);
- That’s way too much typing to do just to create a sprite! So I suggest you create an alias called
id
that points to texture’s altas’stextures
object, like this:
let id = PIXI.loader.resources["images/treasureHunter.json"].textures;
Then you can just create each new sprite like this:
let sprite = new Sprite(id["frameId.png"]);
Much better!
Here’s how you could use these three different sprite creation techniques in the setup
function to create and display the dungeon
, explorer
, and treasure
sprites.
//Define variables that might be used in more
//than one function
let dungeon, explorer, treasure, id;
function setup() {
//There are 3 ways to make sprites from textures atlas frames
//1. Access the `TextureCache` directly
let dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
app.stage.addChild(dungeon);
//2. Access the texture using through the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;
//Center the explorer vertically
explorer.y = app.stage.height / 2 - explorer.height / 2;
app.stage.addChild(explorer);
//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;
//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
app.stage.addChild(treasure);
//Position the treasure next to the right edge of the canvas
treasure.x = app.stage.width - treasure.width - 48;
treasure.y = app.stage.height / 2 - treasure.height / 2;
app.stage.addChild(treasure);
}
Here’s what this code displays:
The stage dimensions are 512 by 512 pixels, and you can see in the code above that the app.stage.height
and app.stage.width
properties are used to align the sprites. Here’s how the explorer
‘s y
position is vertically centered:
explorer.y = app.stage.height / 2 - explorer.height / 2;
Learning to create and display sprites using a texture atlas is an important benchmark. So before we continue, let’s take a look at the code you could write to add the remaining sprites: the blob
s and exit
door, so that you can produce a scene that looks like this:
Here’s the entire code that does all this. I’ve also included the HTML code so you can see everything in its proper context. (You’ll find this working code in the examples/spriteFromTextureAtlas.html
file in this repository.) Notice that the blob
sprites are created and added to the stage in a loop, and assigned random positions.
<!doctype html>
<meta charset="utf-8">
<title>Make a sprite from a texture atlas</title>
<body>
<script src="../pixi/pixi.min.js"></script>
<script>
//Aliases
let Application = PIXI.Application,
Container = PIXI.Container,
loader = PIXI.loader,
resources = PIXI.loader.resources,
TextureCache = PIXI.utils.TextureCache,
Sprite = PIXI.Sprite,
Rectangle = PIXI.Rectangle;
//Create a Pixi Application
let app = new Application({
width: 512,
height: 512,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
//load a JSON file and run the `setup` function when it's done
loader
.add("images/treasureHunter.json")
.load(setup);
//Define variables that might be used in more
//than one function
let dungeon, explorer, treasure, door, id;
function setup() {
//There are 3 ways to make sprites from textures atlas frames
//1. Access the `TextureCache` directly
let dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
app.stage.addChild(dungeon);
//2. Access the texture using throuhg the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;
//Center the explorer vertically
explorer.y = app.stage.height / 2 - explorer.height / 2;
app.stage.addChild(explorer);
//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;
//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
app.stage.addChild(treasure);
//Position the treasure next to the right edge of the canvas
treasure.x = app.stage.width - treasure.width - 48;
treasure.y = app.stage.height / 2 - treasure.height / 2;
app.stage.addChild(treasure);
//Make the exit door
door = new Sprite(id["door.png"]);
door.position.set(32, 0);
app.stage.addChild(door);
//Make the blobs
let numberOfBlobs = 6,
spacing = 48,
xOffset = 150;
//Make as many blobs as there are `numberOfBlobs`
for (let i = 0; i < numberOfBlobs; i++) {
//Make a blob
let blob = new Sprite(id["blob.png"]);
//Space each blob horizontally according to the `spacing` value.
//`xOffset` determines the point from the left of the screen
//at which the first blob should be added.
let x = spacing * i + xOffset;
//Give the blob a random y position
//(`randomInt` is a custom function - see below)
let y = randomInt(0, app.stage.height - blob.height);
//Set the blob's position
blob.x = x;
blob.y = y;
//Add the blob sprite to the stage
app.stage.addChild(blob);
}
}
//The `randomInt` helper function
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
</body>
You can see in the code above that all the blobs are created using a for
loop. Each blob
is spaced evenly along the x
axis like this:
let x = spacing * i + xOffset;
blob.x = x;
spacing
has a value 48, and xOffset
has a value of 150. What this means is the first blob
will have an x
position of 150. This offsets it from the left side of the stage by 150 pixels. Each subsequent blob
will have an x
value that’s 48 pixels greater than the blob
created in the previous iteration of the loop. This creates an evenly spaced line of blob monsters, from left to right, along the dungeon floor.
Each blob
is also given a random y
position. Here’s the code that does this:
let y = randomInt(0, stage.height - blob.height);
blob.y = y;
The blob
‘s y
position could be assigned any random number between 0 and 512, which is the value of stage.height
. This works with the help of a custom function called randomInt
. randomInt
returns a random number that’s within a range between any two numbers you supply.
randomInt(lowestNumber, highestNumber)
That means if you want a random number between 1 and 10, you can get one like this:
let randomNumber = randomInt(1, 10);
Here’s the randomInt
function definition that does all this work:
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
randomInt
is a great little function to keep in your back pocket for making games - I use it all the time.