How to replace a loaded spritesheet?

Hi. I want to replace the spritesheet. I load the spritesheet for the scene

import enemy from "../assets/sprEnemy.png";
...
preload() {
     this.load.spritesheet('enemy', enemy, {
         frameWidth: 34,
         frameHeight: 42
     });
}
create(){
        ...
        this.enemies = this.add.group();
}
update() {
        for (let i = 0; i < this.enemies.getChildren().length; i++) {
         
        }
}

After end of the stage I want to start this scene again but I want to change spritesheet. I try to make

import enemy2 from "../assets/sprEnemy2.png";
...
preload() {
      this.textures.remove('enemy')
      this.load.spritesheet('enemy', enemy2, {
         frameWidth: 34,
         frameHeight: 42
     });
}

but I have error in update() with this.enemies.getChildren()
Uncaught TypeError: Cannot read property 'entries' of undefined.

How to correct replace the spritesheet? I don’t want to preload all sprites.

This sounds like a problem with the group (this.enemies), not the texture. You may have destroyed the group and then tried to work on it in update() without recreating it.

I don’t destroy the group. It is the object of the group(this.enemies) in update() before the error

Also it happens when I load new spritesheet in this scene, when I start this scene again

this.load.spritesheet('enemyBoss', enemyBoss, {
       frameWidth: 94, 
       frameHeight: 85
})

Which things can help you? I will try to write them. I use phaser ^3.22.0

Did you stop or restart the scene?

I didn’t. When the stage ends I only call this.scene.start("GameEndStage"); When I want to start new stage I call this.scene.start("GameScene");

That will stop GameScene, if called from GameScene.

How is correct to switch between scenes in my case?

I think scene.start("GameEndStage") is probably correct. I don’t understand why the this.enemies reference is bad after restarting, because it should have been recreated in create().

Can you post the whole GameScene?

Unfortunately, I can’t post the whole GameScene. I debugged life cycle of the GameScene when the GameScene has this.textures.remove('enemy') in preload(). When the GameScene started first time, the sequence such preload() -> create() -> update() and console has warning No texture found matching key: enemy. When I started the GameScene second time, the sequence such preload() -> update() -> create() and console has error from my first post.

Why is update() being called before create()?

I don’t know. I will try to reproduce this issue in an empty Phaser 3 project tomorrow.

I reproduced this issue in an empty project. My code:
Start game

import First from './First.js';
import Second from './Second.js';

const config = {
            backgroundColor: '#000',
            parent: "Game",
            width: screenWidth,
            height: screenHeight,
            scene: [First, Second],
        };

        var game = new Phaser.Game(config);

First scene

export default class First extends Phaser.Scene{
    constructor (){
        super('First');
    }

    preload() {
        this.textures.remove('sprite');
        if(!this.textures.exists('sprite')){
            this.load.spritesheet('sprite', './assets/ActionBtnHelp.png', {
                frameWidth: 45,
                frameHeight: 45
            });
        }
    }

    pointerDown(){
        this.scene.start('Second');
    }

    create() {
        this.btn = this.add.text(10, 10, 'Second');
        this.btn.setInteractive();
        this.btn.on('pointerdown', this.pointerDown, this);
        this.add.sprite(100, 30, 'sprite');

        this.enemies = this.add.group();
    }

    update() {
        for (let i = 0; i < this.enemies.getChildren().length; i++) {

        }
    }
}

Second scene

export default class Second extends Phaser.Scene{
    constructor (){
        super('Second');
    }

    preload() {

    }

    pointerDown(){
        this.scene.start('First');
    }

    create() {
        this.btn = this.add.text(10, 10, 'First');
        this.btn.setInteractive();
        this.btn.on('pointerdown', this.pointerDown, this);
    }

    update() {

    }
}
1 Like

Thanks. I think this is a Phaser bug. A workaround is to add to First scene preload():

// <https://github.com/photonstorm/phaser/issues/5065>
this.sys.sceneUpdate = new Function;
2 Likes

Yes, this workaround works. Thank you!!!