Jump to content

How to correctly load many textures at runtime?


johhnyblagger
 Share

Recommended Posts

Hi all, I want to load many textures at runtime. I would not like to apply these to sprites at runtime as the texture of a sprite in my game changes based on user input. Based on this post, I did the following:

var loader = PIXI.loader                .add('GRASS_TOP','assets/grass_top.png')                .add('GRASS_TOP_LEFT','assets/grass_top_left.png')                .add('GRASS_TOP_RIGHT','assets/grass_top.png')                .once('complete', function(loader, resources) {		      init();                })	        .load();

I then made each texture a variable

var GRASS_TOP = PIXI.loader.resources.GRASS_TOP.texture;var GRASS_TOP_LEFT = PIXI.loader.resources.GRASS_TOP_LEFT.texture;var GRASS_TOP_RIGHT = PIXI.loader.resources.GRASS_TOP_RIGHT.texture;

At runtime sprites are declared

thing.sprite = new PIXI.Sprite(PIXI.Texture.EMPTY);

and later based on user input sprite textures are given

thing.sprite.texture = GRASS_TOP_RIGHT;

This is not working. Firefox give me the following error: TypeError: texture is undefined. It also seems that my game puts my browser under a heavy load.

 

Also, before I loaded textures like how I did above, I did the following:

var GRASS_TOP_RIGHT = PIXI.Texture.fromImage('assets/grass_top_right.png');

Is this any more or less efficient?

Link to comment
Share on other sites

Following ivan.popelyshev's advice:

var GRASS_TOP;var GRASS_TOP_LEFT;var GRASS_TOP_RIGHT;var loader = PIXI.loader                .add('GRASS_TOP','assets/grass_top.png')                .add('GRASS_TOP_LEFT','assets/grass_top_left.png')                .add('GRASS_TOP_RIGHT','assets/grass_top_right.png')                .once('complete', function(loader, resources) {		      init();		})	        .load();function init(){  GRASS_TOP = PIXI.loader.resources.GRASS_TOP.texture;  GRASS_TOP_LEFT = PIXI.loader.resources.GRASS_TOP_LEFT.texture;  GRASS_TOP_RIGHT = PIXI.loader.resources.GRASS_TOP_RIGHT.texture;}

Here is the error I receive now:

xF78sBB.png

 

Here is Creator.js:

var renderer = PIXI.autoDetectRenderer(REAL_WIDTH, REAL_HEIGHT);document.body.appendChild(renderer.view);renderer.view.style.position = 'absolute';renderer.view.style.left = '50%';renderer.view.style.top = '50%';renderer.view.style.transform = 'translate3d( -50%, -50%, 0 )';var stage = new PIXI.Container();var worldContainer = new PIXI.Container();var GUIContainer = new PIXI.Container();stage.addChild(worldContainer);stage.addChild(GUIContainer);animate();function animate() {    requestAnimationFrame(animate);    renderer.render(stage);            //this is line 24, the function call that results in the Uncaught TypeError}
Link to comment
Share on other sites

Dont call animate()  in Creator.js, it'll get called immediately, the loading is async so init() will get called later in time, however, animate() is causally linked to init() i.e. it needs init() to do its shizzle before animate() can call the render(), if you whack a console log in both functions you'll see that animate() gets called first.

 

The quick-fire solution is to simply call animate() at the end of your init() function, so long as the init() code (and hence those lovely global texture decs) lives 'above' (or is included in the page earlier) then all will be fine, actually, scratch that, due to hoisting and global vars as long as animate() gets called at the end of the init() function I suspect all will be ok.

 

The logic here is that you have 2 game states, load and then the render/game loop. The simplest way to handle these states is to linearly move from one to the other i.e. do the load() state stuff and load EVERYTHING! (this falls down later but for simple apps its simple, and simple is good) and then enter the game loop.

 

Your code has the load and game state firing at the same time, infact, your game loop runs before your load/init state. By whacking your global animate() function (which triggers your game state to start) at the end of the init() function (so long as the init function is synchronous, yours is currently) you implement a linear flow through game states i.e. load/init first then enter game/render loop.

 

If you add a finish() function that renders some lovely 'well done you win' text to the screen and on some condition within the animate() loop you cancel the raf call to animate and instead call finish() then you have 3 states in your game load -> render loop -> finish and you have a complete app!

Link to comment
Share on other sites

Hey mattstyles, thank you for your reply. What you wrote makes perfect sense and I completely agree with your logic. I did exactly as you said (called animate() once load() is finished) and I still receive the "Uncaught TypeError: Cannot read property '_uvs' of undefined" error.

 

Either

1. any other suggestions from anyone to fix this?

2. any other suggestions as to how to load textures at runtime?

 

Here is what I changed:

var GRASS_TOP;var GRASS_TOP_LEFT;var GRASS_TOP_RIGHT;var loader = PIXI.loader                .add('GRASS_TOP','assets/grass_top.png')                .add('GRASS_TOP_LEFT','assets/grass_top_left.png')                .add('GRASS_TOP_RIGHT','assets/grass_top_right.png')                .once('complete', function(loader, resources) {		      init();		})	        .load();function init(){  GRASS_TOP = PIXI.loader.resources.GRASS_TOP.texture;  GRASS_TOP_LEFT = PIXI.loader.resources.GRASS_TOP_LEFT.texture;  GRASS_TOP_RIGHT = PIXI.loader.resources.GRASS_TOP_RIGHT.texture;}animate();
var renderer = PIXI.autoDetectRenderer(REAL_WIDTH, REAL_HEIGHT);document.body.appendChild(renderer.view);var stage = new PIXI.Container();var worldContainer = new PIXI.Container();var GUIContainer = new PIXI.Container();stage.addChild(worldContainer);stage.addChild(GUIContainer);function animate() {    requestAnimationFrame(animate);    renderer.render(stage);            //this is line 24, the function call that results in the Uncaught TypeError}
Link to comment
Share on other sites

so I got it working

var renderer = PIXI.autoDetectRenderer(400, 300);document.body.appendChild(renderer.view);var GRASS_TOP;var stage;var loader = PIXI.loader                  .add('GRASS_TOP','assets/box.png')                  .once('complete', function(loader, resources) {                        initTextures();                        animate();                  })                  .load();function initTextures(){  GRASS_TOP = PIXI.loader.resources.GRASS_TOP.texture;  doRest();}function doRest(){  var sprite = new PIXI.Sprite(GRASS_TOP);  stage = new PIXI.Container();  stage.addChild(sprite);  animate();}function animate() {  requestAnimationFrame(animate);  renderer.render(stage);}
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...