Displaying sprites

After you’ve loaded an image, and used it to make a sprite, you need to add the sprite to Pixi’s stage with the stage.addChild method, like this:

  1. app.stage.addChild(cat);

Remember that the stage is the main container that holds all of your sprites.

Important: you won’t be able to see any of your sprites sprites unless you add them to the stage!

Before we continue, let’s look at a practical example of how to use what you’ve just learnt to display a single image. In the examples/images folder you’ll find a 64 by 64 pixel PNG image of a cat.

Basic display

Here’s all the JavaScript code you need to load the image, create a sprite, and display it on Pixi’s stage:

  1. //Create a Pixi Application
  2. let app = new PIXI.Application({
  3. width: 256,
  4. height: 256,
  5. antialias: true,
  6. transparent: false,
  7. resolution: 1
  8. }
  9. );
  10. //Add the canvas that Pixi automatically created for you to the HTML document
  11. document.body.appendChild(app.view);
  12. //load an image and run the `setup` function when it's done
  13. PIXI.loader
  14. .add("images/cat.png")
  15. .load(setup);
  16. //This `setup` function will run when the image has loaded
  17. function setup() {
  18. //Create the cat sprite
  19. let cat = new PIXI.Sprite(PIXI.loader.resources["images/cat.png"].texture);
  20. //Add the cat to the stage
  21. app.stage.addChild(cat);
  22. }

When this code runs, here’s what you’ll see:

Cat on the stage

Now we’re getting somewhere!

If you ever need to remove a sprite from the stage, use the removeChild method:

  1. app.stage.removeChild(anySprite)

But usually setting a sprite’s visible property to false will be a simpler and more efficient way of making sprites disappear.

  1. anySprite.visible = false;

Using aliases

You can save yourself a little typing and make your code more readable by creating short-form aliases for the Pixi objects and methods that you use frequently. For example, is prefixing PIXI to all of Pixi’s objects starting to bog you down? If you think so, create a shorter alias that points to it. For example, here’s how you can create an alias to the TextureCache object:

  1. let TextureCache = PIXI.utils.TextureCache

Then, use that alias in place of the original, like this:

  1. let texture = TextureCache["images/cat.png"];

In addition to letting you write more slightly succinct code, using aliases has an extra benefit: it helps to buffer you from Pixi’s frequently changing API. If Pixi’s API changes in future versions - which it will! - you just need to update these aliases to Pixi objects and methods in one place, at the beginning of your program, instead of every instance where they’re used throughout your code. So when Pixi’s development team decides they want to rearrange the furniture a bit, you’ll be one step ahead of them!

To see how to do this, let’s re-write the code we wrote to load an image and display it, using aliases for all the Pixi objects and methods.

  1. //Aliases
  2. let Application = PIXI.Application,
  3. loader = PIXI.loader,
  4. resources = PIXI.loader.resources,
  5. Sprite = PIXI.Sprite;
  6. //Create a Pixi Application
  7. let app = new Application({
  8. width: 256,
  9. height: 256,
  10. antialias: true,
  11. transparent: false,
  12. resolution: 1
  13. }
  14. );
  15. //Add the canvas that Pixi automatically created for you to the HTML document
  16. document.body.appendChild(app.view);
  17. //load an image and run the `setup` function when it's done
  18. loader
  19. .add("images/cat.png")
  20. .load(setup);
  21. //This `setup` function will run when the image has loaded
  22. function setup() {
  23. //Create the cat sprite
  24. let cat = new Sprite(resources["images/cat.png"].texture);
  25. //Add the cat to the stage
  26. app.stage.addChild(cat);
  27. }

Most of the examples in this tutorial will use aliases for Pixi objects that follow this same model. Unless otherwise stated, you can assume that all the code examples that follow use aliases like these.

This is all you need to know to start loading images and creating sprites.

A little more about loading things

The format I’ve shown you above is what I suggest you use as your standard template for loading images and displaying sprites. So, you can safely ignore the next few paragraphs and jump straight to the next section, “Positioning sprites.” But Pixi’s loader object is quite sophisticated and includes a few features that you should be aware of, even if you don’t use them on a regular basis. Let’s look at some of the most useful.

Make a sprite from an ordinary JavaScript Image object or Canvas

For optimization and efficiency it’s always best to make a sprite from a texture that’s been pre-loaded into Pixi’s texture cache. But if for some reason you need to make a texture from a regular JavaScript Image object, you can do that using Pixi’s BaseTexture and Texture classes:

  1. let base = new PIXI.BaseTexture(anyImageObject),
  2. texture = new PIXI.Texture(base),
  3. sprite = new PIXI.Sprite(texture);

You can use BaseTexture.fromCanvas if you want to make a texture from any existing canvas element:

  1. let base = new PIXI.BaseTexture.fromCanvas(anyCanvasElement),

If you want to change the texture the sprite is displaying, use the texture property. Set it to any Texture object, like this:

  1. anySprite.texture = PIXI.utils.TextureCache["anyTexture.png"];

You can use this technique to interactively change the sprite’s appearance if something significant happens to it in the game.

Assigning a name to a loading file

It’s possible to assign a unique name to each resource you want to load. Just supply the name (a string) as the first argument in the add method. For example, here’s how to name an image of a cat as catImage.

  1. PIXI.loader
  2. .add("catImage", "images/cat.png")
  3. .load(setup);

This creates an object called catImage in loader.resources. That means you can create a sprite by referencing the catImage object, like this:

  1. let cat = new PIXI.Sprite(PIXI.loader.resources.catImage.texture);

However, I recommend you don’t use this feature! That’s because you’ll have to remember all names you gave each loaded files, as well as make sure you don’t accidentally use the same name more than once. Using the file path name, as we’ve done in previous examples is simpler and less error prone.

Monitoring load progress

Pixi’s loader has a special progress event that will call a customizable function that will run each time a file loads. progress events are called by the loader‘s on method, like this:

  1. PIXI.loader.on("progress", loadProgressHandler);

Here’s how to include the on method in the loading chain, and call a user-definable function called loadProgressHandler each time a file loads.

  1. PIXI.loader
  2. .add([
  3. "images/one.png",
  4. "images/two.png",
  5. "images/three.png"
  6. ])
  7. .on("progress", loadProgressHandler)
  8. .load(setup);
  9. function loadProgressHandler() {
  10. console.log("loading");
  11. }
  12. function setup() {
  13. console.log("setup");
  14. }

Each time one of the files loads, the progress event calls loadProgressHandler to display “loading” in the console. When all three files have loaded, the setup function will run. Here’s the output of the above code in the console:

  1. loading
  2. loading
  3. loading
  4. setup

That’s neat, but it gets better. You can also find out exactly which file has loaded and what percentage of overall files are have currently loaded. You can do this by adding optional loader and resource parameters to the loadProgressHandler, like this:

  1. function loadProgressHandler(loader, resource) { /*...*/ }

You can then use resource.url to find the file that’s currently loaded. (Use resource.name if you want to find the optional name that you might have assigned to the file, as the first argument in the add method.) And you can use loader.progress to find what percentage of total resources have currently loaded. Here’s some code that does just that.

  1. PIXI.loader
  2. .add([
  3. "images/one.png",
  4. "images/two.png",
  5. "images/three.png"
  6. ])
  7. .on("progress", loadProgressHandler)
  8. .load(setup);
  9. function loadProgressHandler(loader, resource) {
  10. //Display the file `url` currently being loaded
  11. console.log("loading: " + resource.url);
  12. //Display the percentage of files currently loaded
  13. console.log("progress: " + loader.progress + "%");
  14. //If you gave your files names as the first argument
  15. //of the `add` method, you can access them like this
  16. //console.log("loading: " + resource.name);
  17. }
  18. function setup() {
  19. console.log("All files loaded");
  20. }

Here’s what this code will display in the console when it runs:

  1. loading: images/one.png
  2. progress: 33.333333333333336%
  3. loading: images/two.png
  4. progress: 66.66666666666667%
  5. loading: images/three.png
  6. progress: 100%
  7. All files loaded

That’s really cool, because you could use this as the basis for creating a loading progress bar.

(Note: There are additional properties you can access on the resource object. resource.error will tell you of any possible error that happened while trying to load a file. resource.data lets you access the file’s raw binary data.)

More about Pixi’s loader

Pixi’s loader is ridiculously feature-rich and configurable. Let’s take a quick bird’s-eye view of its usage to get you started.

The loader’s chainable add method takes 4 basic arguments:

  1. add(name, url, optionObject, callbackFunction)

Here’s what the loader’s source code documentation has to say about these parameters:

name (string): The name of the resource to load. If it’s not passed, the urlis used.
url (string): The url for this resource, relative to the baseUrl of the loader.
options (object literal): The options for the load.
options.crossOrigin (Boolean): Is the request cross-origin? The default is to determine automatically.
options.loadType: How should the resource be loaded? The default value is Resource.LOAD_TYPE.XHR.
options.xhrType: How should the data being loaded be interpreted when using XHR? The default value is Resource.XHR_RESPONSE_TYPE.DEFAULT
callbackFunction: The function to call when this specific resource completes loading.

The only one of these arguments that’s required is the url (the file that you want to load.)

Here are some examples of some ways you could use the add method to load files. These first ones are what the docs call the loader’s “normal syntax”:

  1. .add('key', 'http://...', function () {})
  2. .add('http://...', function () {})
  3. .add('http://...')

And these are examples of the loader’s “object syntax”:

  1. .add({
  2. name: 'key2',
  3. url: 'http://...'
  4. }, function () {})
  5. .add({
  6. url: 'http://...'
  7. }, function () {})
  8. .add({
  9. name: 'key3',
  10. url: 'http://...'
  11. onComplete: function () {}
  12. })
  13. .add({
  14. url: 'https://...',
  15. onComplete: function () {},
  16. crossOrigin: true
  17. })

You can also pass the add method an array of objects, or urls, or both:

  1. .add([
  2. {name: 'key4', url: 'http://...', onComplete: function () {} },
  3. {url: 'http://...', onComplete: function () {} },
  4. 'http://...'
  5. ]);

(Note: If you ever need to reset the loader to load a new batch of files, call the loader’s reset method: PIXI.loader.reset();)

Pixi’s loader has many more advanced features, including options to let you load and parse binary files of all types. This is not something you’ll need to do on a day-to-day basis, and way outside the scope of this tutorial, so make sure to check out the loader’s GitHub repository for more information.