johhnyblagger Posted November 6, 2015 Share Posted November 6, 2015 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 variablevar 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 declaredthing.sprite = new PIXI.Sprite(PIXI.Texture.EMPTY);and later based on user input sprite textures are giventhing.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? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 6, 2015 Share Posted November 6, 2015 You need to declare GRASS_TOP and other things in the init(), when all resources are initialized properly. Just after .load() they dont have textures yet, so its all null. If you want to use unitialized resources, then use fromImage, it works just fine johhnyblagger 1 Quote Link to comment Share on other sites More sharing options...
xerver Posted November 6, 2015 Share Posted November 6, 2015 The code you posted seems fine, I would need more context as to what is causing your error. The line "thing.sprite.texture = GRASS_TOP_RIGHT;" will not throw the error you described, so can you give more context or share a running example? johhnyblagger 1 Quote Link to comment Share on other sites More sharing options...
johhnyblagger Posted November 6, 2015 Author Share Posted November 6, 2015 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: 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} Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 6, 2015 Share Posted November 6, 2015 And when exactly do you create sprites? before or after init() call? Quote Link to comment Share on other sites More sharing options...
mattstyles Posted November 7, 2015 Share Posted November 7, 2015 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! johhnyblagger 1 Quote Link to comment Share on other sites More sharing options...
johhnyblagger Posted November 8, 2015 Author Share Posted November 8, 2015 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. Either1. 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} Quote Link to comment Share on other sites More sharing options...
johhnyblagger Posted November 8, 2015 Author Share Posted November 8, 2015 so I got it workingvar 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);} Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 8, 2015 Share Posted November 8, 2015 .once('complete', function(loader, resources) {initTextures();animate();}).load();is the same as .load(function(loader, resources) { initTextures(); animate();}); johhnyblagger 1 Quote Link to comment Share on other sites More sharing options...
johhnyblagger Posted November 9, 2015 Author Share Posted November 9, 2015 thanks ivan, that works! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.