Removing images and tweens

#1

This is my code for a simple explosion animation:

let explosion = game.scene.getAt(0).add.image(x, y, 'explosion');

game.scene.getAt(0).tweens.add({
    targets: explosion,
    scaleX: scale,
    scaleY: scale,
    alpha: 0
});

It looks well enough for me. At the end of the tween animation, nothing is visible anymore. However, I’m thinking about whether I should remove the explosion image game object as well as the tween to keep the scene clean. There will be a lot of explosions in my game and I’m worried that a lot of invisible images and tweens might slow down the game at some point.

If so, what is the most elegant way of removing both the image and the tween when the tween animation finishes?

I’m also worried about whether creating and removing lots of images and tweens is rather inefficient. Would it be better to maintain some sort of pool for the images and tweens and reuse them?

#2

Interesting way of accessing your scene. Are you using game.scene.getAt becuase there are multiple scenes active in your game at once? If you only have one scene active at a time, I would suggest just creating scenes and adding your code to the individual scene so you can simply type this.scene.add.image();

As far as removing the images, you will definitely want to do that. You can easily do that like so:

game.scene.getAt(0).tweens.add({
    targets: explosion,
    scaleX: scale,
    scaleY: scale,
    alpha: 0,
    onComplete: ()=>{explosion.destroy();}
});

Don’t worry about the tweens though. As long as you aren’t storing a unique reference to each tween, they should be garbage collected on their own.

2 Likes
#3

Thanks Jake. I have two follow up questions:

Where is the onComplete() function documented? I couldn’t find this in the docs.

The second question is about accessing the scene with this. I have my code structured with functions and this particular function is pretty much down the call hierarchy. I didn’t want to pass the scene through all these functions, that’s why I access the scene via the global game variable. I’m open to suggestions on how to structure my code better though. This is my first large JavaScript project.

#4

Phaser.Tweens.Tween#callbacks

#5

As far as structuring your project, there are quite a few ways to do it. I use es6 and what I do, is I create a main.js class which simply has the following code:

import FirstScene from './scenes/FirstScene.js';

class Main
{
    constructor()
    {
        let config = {
            type: Phaser.WEBGL,
            width: 768,
            height: 1024,
	        scale: {
                mode: Phaser.Scale.FIT,
                autoCenter: Phaser.Scale.CENTER_VERTICALLY
            }
        };

        this.game = new Phaser.Game(config);

        let firstScene= new FirstScene();
        this.game.scene.add('FirstScene', firstScene);
        this.game.scene.start('FirstScene');
    }
}

var main = new Main();

As you can see above, I have a “FirstScene” class, which I create a new file for and that simply extends Phaser.Scene. Now in that FirstScene.js file, I can add a create(){} method and access the scene directly by using the this keyword. ex: this.add.image(). It’s a pretty nice way of keeping all of your code encapsulated into their individual files.