Rats! WebGL hit a snag when creating (and destroying) many AnimatedSprites during app lifetime
See original GitHub issueI am creating new AnimatedSprites on pointerdown event (and deleting them on next pointerdown event) over the course if application lifetime. At some point around 20 clicks, the app crashes with an error: Rats! webGl crashed. At that point no error is displayed in console. Crash happens on a mobile device, and would probably also happen on desktop, if someone perform plenty of clicks. You can anticipate the crash. Few clicks before the final crash, animations become really stuttering.
Code that is repeatedly used is below. I also include live example at http://forwardingsolutions.club/. Can someone please point out what am I doing wrong?
function setupNextSpritesAnimation(){
setupNextAnimation();
console.log("next color: "+nextColor);
switch (nextColor) {
case "red":
var newLoader = new PIXI.loaders.Loader()
.add('nextSprite', '/assets/sprite/red.png.png')
.load(function (loader, resources){
var interval = setInterval(function(){
if (!isAnimating){
clearInterval(interval);
createNewAnimatedSprite(resources,newLoader);
}
},50);
});
break;
case "aqua":
var newLoader = new PIXI.loaders.Loader()
.add('nextSprite', '/assets/sprite/aqua.png.png')
.load(function (loader, resources){
var interval = setInterval(function(){
if (!isAnimating){
clearInterval(interval);
createNewAnimatedSprite(resources,newLoader);
}
},50);
});
break;
case "green":
var newLoader = new PIXI.loaders.Loader()
.add('nextSprite', '/assets/sprite/blue.png.png')
.load(function (loader, resources){
var interval = setInterval(function(){
if (!isAnimating){
clearInterval(interval);
createNewAnimatedSprite(resources,newLoader);
}
},50);
});
break;
case "purple":
var newLoader = new PIXI.loaders.Loader()
.add('nextSprite', '/assets/sprite/purple.png.png')
.load(function (loader, resources){
var interval = setInterval(function(){
if (!isAnimating){
clearInterval(interval);
createNewAnimatedSprite(resources,newLoader);
}
},50);
});
break;
}
}
function createNewAnimatedSprite(resources,newLoader){
var tmpSprite = new PIXI.extras.AnimatedSprite(setupFrames(resources["nextSprite"].texture.baseTexture));
app.stage.addChild(tmpSprite);
spritesArray.push(tmpSprite);
setupNextSprites(tmpSprite);
app.renderer.plugins.prepare.upload(tmpSprite, function(){
console.log("updoaded now");
canRunNext = true;
newLoader.reset();
//console.log("kill");
delete tmpSprite;
});
}
function setupNextSprites(nextSprite){
nextSprite.x = app.renderer.width / 2;
nextSprite.y = app.renderer.height / 2;
nextSprite.anchor.set(0.5);
nextSprite.loop = false;
nextSprite.animationSpeed = 0.5;
nextSprite.visible = false;
nextSprite.onComplete = function (){
console.log("animation finished");
isAnimating = false;
};
}
function setupNextAnimation(){
var randomNumber = getRandomInt(0,3);
switch (randomNumber) {
case 0:
nextColor = "red";
break;
case 1:
nextColor = "aqua";
break;
case 2:
nextColor = "green";
break;
case 3:
nextColor = "purple";
break;
}
}
app.stage.on("pointerdown", function () {
if (firstRun && !isAnimating) {
firstRun = false;
isAnimating = true;
currentSprite.gotoAndPlay(0);
}else{
if (canRunNext && !isAnimating){
isAnimating=true;
if (currentSprite.visible){
currentSprite.visible = false;
currentSprite.destroy(true);
}
spritesArray[spritesArray.length-1].visible = true;
spritesArray[spritesArray.length-1].gotoAndPlay(0);
app.stage.removeChild(spritesArray[spritesArray.length-2]);
spritesArray[spritesArray.length-2].destroy({ children:true, texture:true, baseTexture:true});
canRunNext = false;
setupNextSpritesAnimation();
}
}
});
function setupSpritesAnimation(){
//created currentSprite just once at the start of app
spritesArray.push(currentSprite);
}
Issue Analytics
- State:
- Created 6 years ago
- Comments:10 (2 by maintainers)
Top Results From Across the Web
Rats! WebGL hit a snag when creating (and destroying) many ...
I am creating new AnimatedSprites on pointerdown event (and deleting them on next pointerdown event) over the course if application lifetime ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
You need to call
loader.reset()
when you are done with it. The loader is made to have resources added, load them, and be done. If you call reset it goes back to step one (clearing the.resources
property of the things previously loaded). This is how you can resuse a single loader instance for all loading done in your app, just call.reset()
when you plan to use it again. The only reason you would ever need to create multiple instances of the loader is if you want different middleware on different loaders. Otherwise just use one and.reset()
.This is similar to how you call
destroy
on sprites when you are done with them.This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.