Jump to content

How Does Asset Loading Work With Pixi.js?


Mr.Fisty
 Share

Recommended Posts

Okay, so a lot of the tutorials for Pixi.js seem a bit outdated. Most of the information out there still uses the old way of creating a new Pixi application by not using the newer 'convenient' Application class and setting up the renderer, container, and ticker by hand.

A lot of the guides and articles also seem to be written before Pixi adopted and extended on a third-party loader module.

Anyway, could someone explain to me how loading assets works, and what it means exactly?

Normally, to start displaying some visuals with Pixi, you need to create a texture, and then a sprite from that texture, yes? Example:

var texture = PIXI.utils.TextureCache["images/anySpriteImage.png"];
var sprite = new PIXI.Sprite(texture);

But then comes the 'loader' to the rescue. From my understanding, the Pixi loader is an object that simplifies handling assets because it creates the textures for you? For example:

const loader = PIXI.loader
  .add('image1', '/assets/images/image1.png')

Am I correct? I can't wrap my head around this. Here's my code altogether (it doesn't work by the way):

const app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
document.body.appendChild(app.view);

const sprites = [];

const loader = PIXI.loader
  .add('image1', 'assets/images/image1.png')

.load(function(loader, resources) {
    sprites.image1 = new PIXI.Sprite(resources.image1.texture);
    init();
});

function init() {
    app.stage.addChild(sprites);
}

Do I need to render the stage in the 'init' function as well? Do I have to call 'load()' at some point? I'm so confused!


However, this code works and I'm not sure why:

const app = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb});
document.body.appendChild(app.view);

const loader = PIXI.loader;

loader.add('image1', '/assets/images/image1.png');

loader.once('complete', function(loader, resources) {
    init();
})

loader.load();

function init() {
    let sprite1 = new PIXI.Sprite(PIXI.loader.resources.image1.texture);
    app.stage.addChild(sprite1);
}

EDIT

Okay, it's making a lot more sense to me now. Here is the cleanest way I've come up with when using loader:
 

const app = new PIXI.Application(800, 600);
document.body.appendChild(app.view);

const loader = PIXI.loader;

loader
  .add('image1', '/assets/images/image1.png');

loader.on('complete', function(loader, resources) {
  let sprite1 = new PIXI.Sprite(loader.resources.image1.texture);
  app.stage.addChild(image1);
});

loader.load();
Link to comment
Share on other sites

I'd recommend taking a look at the official Pixi examples page: https://pixijs.github.io/examples

 

They all use the new PIXI.Application style, and if assets are required to be prepared, like the animated sprite demo (https://pixijs.github.io/examples/#/demos/animatedsprite-demo.js), you'll see how the loader can be used, though you've already cracked that i see :)

 

 

Link to comment
Share on other sites

On 5/6/2017 at 7:33 PM, Mr.Fisty said:

Normally, to start displaying some visuals with Pixi, you need to create a texture, and then a sprite from that texture, yes? Example:

- yes, you need texture first. In your example you are assuming that texture already exists in PIXI.utils.TextureCache (that it has been previously loaded)

PIXI.Application has been added to PIXI for simplicity reasons and it saves you some time while quick testing stuff.
It does few things automatically for you, see http://pixijs.download/release/docs/PIXI.Application.html

Example on how to create PIXI application, load an texture (see the notes in code), assign it to sprite and show it on the screen : https://jsfiddle.net/EneaEntertainment/9tfx8sq2/

Other approach without using built-in PIXI.Application is here : https://jsfiddle.net/EneaEntertainment/2rpuxbg0/

 

On 5/6/2017 at 7:33 PM, Mr.Fisty said:

Do I need to render the stage in the 'init' function as well?

- not when using PIXI.Application

 

On 5/6/2017 at 7:33 PM, Mr.Fisty said:

Do I have to call 'load()' at some point? I'm so confused!

- yes. First you need to feed loader with assets you want to load, then run it by calling load()

 

On 5/6/2017 at 7:33 PM, Mr.Fisty said:

From my understanding, the Pixi loader is an object that simplifies handling assets because it creates the textures for you?

- no, main purpose of loader is to load assets for you and as an addition it will create textures from them

 

Usually you want to preload your assets before using them in scene and that's when loader steps in.

Using the loader - https://jsfiddle.net/EneaEntertainment/5x6c3h4s/

Link to comment
Share on other sites

Thanks guys! Okay, so a couple of more questions he-he! 

1. So the real purpose of the loader object is for pre-loading resources? To avoid the jarring effect of sprites loading one-by-one or slowly on run-time?

2. If you're creating a game with lots of different assets (images and sprites), that can be broken down into categories such as "enemies", "players", "items", would it make sense to load them in separate arrays in the loader? For example:
 

const assets = [ ];

const loader = PIXI.loader();

loader
  .add (const enemies = [
     ('assets/images/monster.png'),
     ('assets/images/badguy.png');
    ]),
   .add (const items = [
      ('assets/images/sword.png'),
      ('assets/images/shield.png');
    ]),
   .add (const players = [
      ('assets/images/hero.png');
    ]);

 

Link to comment
Share on other sites

Use the Texture Atlas. I bought the Texture Packer application for it. You can use a free version. I read about the usage of the Texture Packer in this book: Learn Pixi.js. It is from the book:

Quote

Using a Texture Atlas

If you’re working on a big, complex game or application, you’ll want a fast and efficient 
way to create sprites from tilesets. This is where a texture atlas becomes really useful. 
A texture atlas is a JSON data file that contains the positions and sizes of sub-images on 
a matching tileset PNG image. If you use a texture atlas, all you need to know about the 
sub-image you want to display is its name. You can arrange your tileset images in any 
order, and the JSON file will keep track of their sizes and positions for you. This is really 
convenient, because it means the sizes and positions of tileset images aren’t hard-coded 
into your game program. If you make changes to the tileset, such as adding images, 
resizing them, or removing them, just republish the JSON file, and your game will use that 
data to display the correct images. You won’t have to make any changes to your game code.

Pixi is compatible with a standard JSON texture atlas format that is output by a 
popular software tool called Texture Packer (www.codeandweb.com/texturepacker). 
Texture Packer’s “Essential” license is free. Let’s find out how to use it to make a texture 
atlas and then load the atlas into Pixi.

 

Link to comment
Share on other sites

14 hours ago, Mr.Fisty said:

1. So the real purpose of the loader object is for pre-loading resources? To avoid the jarring effect of sprites loading one-by-one or slowly on run-time?

- you want to preload as much resources as possible before game starts (keep in mind that there are some memory limits). Not only because you can push already loaded assets to gpu mem and thus avoid lags but often you need to place one sprites next to each other based on their sizes. And you can not determine sprite size until it's texture has loaded

- as mentioned above, you should be packing textures into atlases (TexturePacker is in my opinion the best one to use but there are alternatives you can check : ShoeBox and I'm sure you can google tons of others).
Loading texture atlas is 2 http requests (json file and corresponding png file) comparing to X requests when loading textures separately. What's more important it's more performant way to show them on screen.

14 hours ago, Mr.Fisty said:

2. If you're creating a game with lots of different assets (images and sprites), that can be broken down into categories such as "enemies", "players", "items", would it make sense to load them in separate arrays in the

- makes no sense to group assets to categories for loader, it will just help you with code readability.

You should be grouping them into atlases by appereance on screen. 

If your game will be having followig layers  :
- background
- player + enemies
- UI elements

group your textures accordingly. Ideally into single texture atlas and if that's not possible group them by layers so PIXI can make less draw calls. Remember that different devices can handle only certain texture resolution, see : http://webglstats.com/webgl/parameter/MAX_TEXTURE_SIZE
2048x2048 texture resolution is safe bet. Also using POT textures helps a lot in terms of performance - GPU's love them and mipmaps

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...