"Cannot read property 'frame' of undefined" on basic animation

This feels so basic I almost hate to even have to ask. But I am having an issue trying to make a simple animation work with almost no other code. I keep getting an exception of “Cannot read property ‘frame’ of undefined”. I tried debugging into Phaser 3’s source to see if I could get some hints about what is wrong, and it seems like the issue is being caused by the animations’ “frames” array property being empty. So when Phaser determines the frame to display as the animation starts, it tries to access the key of the frame in the empty frames array and the result is undefined, at which point everything obviously goes wrong. So I can see this problem, but I am not sure what it is hinting at.

The “ranger” spritesheet I am using is from this pack. You can see an example of what it looks like as well, so you don’t have to download it:

If someone can help me with where I have gone wrong here, I would greatly appreciate it!

Here is the very simple code:

let config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        update: update
    },
    physics: {
        default: 'arcade',
        arcade: {
            debug: false
        }
    }
};

let game = new Phaser.Game(config);

let sprite = null;
let hasCalledAnim = false;

function preload ()
{
    this.load.spritesheet('ranger', 'assets/ranger_f.png',
        {frameWidth: 32, frameHeight: 36});
    const RANGER_FRAME_RATE = 10;

    let upAnimConfig = {
        key: 'up',
        frames: this.anims.generateFrameNumbers('ranger', {start: 0, end: 2}),
        frameRate: RANGER_FRAME_RATE,
        repeat: -1
    };
    this.anims.create(upAnimConfig);
    this.anims.create({
        key: 'right',
        frames: this.anims.generateFrameNumbers('ranger', {start: 3, end: 5}),
        frameRate: RANGER_FRAME_RATE,
        repeat: -1
    });
    this.anims.create({
        key: 'down',
        frames: this.anims.generateFrameNumbers('ranger', {start: 6, end: 8}),
        frameRate: RANGER_FRAME_RATE,
        repeat: -1
    });
    this.anims.create({
        key: 'left',
        frames: this.anims.generateFrameNumbers('ranger', {start: 9, end: 11}),
        frameRate: RANGER_FRAME_RATE,
        repeat: -1
    });
}

function create ()
{
    sprite = this.physics.add.sprite(100, 100, 'ranger', 7);
    // sprite.anims.play('up', true);
}

function update ()
{
    if (!hasCalledAnim) {
        sprite.anims.play('right', true);
        hasCalledAnim = true;
    }
}

Try moving the animation creation into create().

2 Likes

Oh crap! Haha! I was staring at this for so long and didn’t realize I did that in preload. That did it! Thank you!

EDIT: Wow, I was using the preload as the create and the create as the update. I looked over this code for hours and didn’t see that. It is amazing what an assumption can do to your brain. Thanks again!

I’m surprised that generateFrameNumbers() didn’t give a warning.

Me too. It seems like the state of the scene could be used to throw a more descriptive error, because this one was pretty cryptic. That said, this was a pretty basic mistake of the fundamentals, so maybe a descriptive error message for this case is not a high priority.

1 Like

here i sit … after x + x² times of phaser , for hours … and yes

you are either the god of phaser or Davey in disguise trying not to be conspicuous :100: