Creating sprites from a loaded texture atlas

Pixi gives you three general ways to create a sprite from a texture atlas:

  1. Using TextureCache:
  1. let texture = TextureCache["frameId.png"],
  2. sprite = new Sprite(texture);
  1. If you’ve used Pixi’s loader to load the texture atlas, use the loader’s resources:
  1. let sprite = new Sprite(
  2. resources["images/treasureHunter.json"].textures["frameId.png"]
  3. );
  1. 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’s textures object, like this:
  1. let id = PIXI.loader.resources["images/treasureHunter.json"].textures;

Then you can just create each new sprite like this:

  1. 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.

  1. //Define variables that might be used in more
  2. //than one function
  3. let dungeon, explorer, treasure, id;
  4. function setup() {
  5. //There are 3 ways to make sprites from textures atlas frames
  6. //1. Access the `TextureCache` directly
  7. let dungeonTexture = TextureCache["dungeon.png"];
  8. dungeon = new Sprite(dungeonTexture);
  9. app.stage.addChild(dungeon);
  10. //2. Access the texture using through the loader's `resources`:
  11. explorer = new Sprite(
  12. resources["images/treasureHunter.json"].textures["explorer.png"]
  13. );
  14. explorer.x = 68;
  15. //Center the explorer vertically
  16. explorer.y = app.stage.height / 2 - explorer.height / 2;
  17. app.stage.addChild(explorer);
  18. //3. Create an optional alias called `id` for all the texture atlas
  19. //frame id textures.
  20. id = PIXI.loader.resources["images/treasureHunter.json"].textures;
  21. //Make the treasure box using the alias
  22. treasure = new Sprite(id["treasure.png"]);
  23. app.stage.addChild(treasure);
  24. //Position the treasure next to the right edge of the canvas
  25. treasure.x = app.stage.width - treasure.width - 48;
  26. treasure.y = app.stage.height / 2 - treasure.height / 2;
  27. app.stage.addChild(treasure);
  28. }

Here’s what this code displays:

Explorer, dungeon and treasure

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:

  1. 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 blobs and exit door, so that you can produce a scene that looks like this:

All the texture atlas sprites

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.

  1. <!doctype html>
  2. <meta charset="utf-8">
  3. <title>Make a sprite from a texture atlas</title>
  4. <body>
  5. <script src="../pixi/pixi.min.js"></script>
  6. <script>
  7. //Aliases
  8. let Application = PIXI.Application,
  9. Container = PIXI.Container,
  10. loader = PIXI.loader,
  11. resources = PIXI.loader.resources,
  12. TextureCache = PIXI.utils.TextureCache,
  13. Sprite = PIXI.Sprite,
  14. Rectangle = PIXI.Rectangle;
  15. //Create a Pixi Application
  16. let app = new Application({
  17. width: 512,
  18. height: 512,
  19. antialias: true,
  20. transparent: false,
  21. resolution: 1
  22. }
  23. );
  24. //Add the canvas that Pixi automatically created for you to the HTML document
  25. document.body.appendChild(app.view);
  26. //load a JSON file and run the `setup` function when it's done
  27. loader
  28. .add("images/treasureHunter.json")
  29. .load(setup);
  30. //Define variables that might be used in more
  31. //than one function
  32. let dungeon, explorer, treasure, door, id;
  33. function setup() {
  34. //There are 3 ways to make sprites from textures atlas frames
  35. //1. Access the `TextureCache` directly
  36. let dungeonTexture = TextureCache["dungeon.png"];
  37. dungeon = new Sprite(dungeonTexture);
  38. app.stage.addChild(dungeon);
  39. //2. Access the texture using throuhg the loader's `resources`:
  40. explorer = new Sprite(
  41. resources["images/treasureHunter.json"].textures["explorer.png"]
  42. );
  43. explorer.x = 68;
  44. //Center the explorer vertically
  45. explorer.y = app.stage.height / 2 - explorer.height / 2;
  46. app.stage.addChild(explorer);
  47. //3. Create an optional alias called `id` for all the texture atlas
  48. //frame id textures.
  49. id = PIXI.loader.resources["images/treasureHunter.json"].textures;
  50. //Make the treasure box using the alias
  51. treasure = new Sprite(id["treasure.png"]);
  52. app.stage.addChild(treasure);
  53. //Position the treasure next to the right edge of the canvas
  54. treasure.x = app.stage.width - treasure.width - 48;
  55. treasure.y = app.stage.height / 2 - treasure.height / 2;
  56. app.stage.addChild(treasure);
  57. //Make the exit door
  58. door = new Sprite(id["door.png"]);
  59. door.position.set(32, 0);
  60. app.stage.addChild(door);
  61. //Make the blobs
  62. let numberOfBlobs = 6,
  63. spacing = 48,
  64. xOffset = 150;
  65. //Make as many blobs as there are `numberOfBlobs`
  66. for (let i = 0; i < numberOfBlobs; i++) {
  67. //Make a blob
  68. let blob = new Sprite(id["blob.png"]);
  69. //Space each blob horizontally according to the `spacing` value.
  70. //`xOffset` determines the point from the left of the screen
  71. //at which the first blob should be added.
  72. let x = spacing * i + xOffset;
  73. //Give the blob a random y position
  74. //(`randomInt` is a custom function - see below)
  75. let y = randomInt(0, app.stage.height - blob.height);
  76. //Set the blob's position
  77. blob.x = x;
  78. blob.y = y;
  79. //Add the blob sprite to the stage
  80. app.stage.addChild(blob);
  81. }
  82. }
  83. //The `randomInt` helper function
  84. function randomInt(min, max) {
  85. return Math.floor(Math.random() * (max - min + 1)) + min;
  86. }
  87. </script>
  88. </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:

  1. let x = spacing * i + xOffset;
  2. 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:

  1. let y = randomInt(0, stage.height - blob.height);
  2. 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.

  1. randomInt(lowestNumber, highestNumber)

That means if you want a random number between 1 and 10, you can get one like this:

  1. let randomNumber = randomInt(1, 10);

Here’s the randomInt function definition that does all this work:

  1. function randomInt(min, max) {
  2. return Math.floor(Math.random() * (max - min + 1)) + min;
  3. }

randomInt is a great little function to keep in your back pocket for making games - I use it all the time.