Sprite animation stuck on first frame?

(Also posted on Stack Overflow, see https://stackoverflow.com/questions/61035598/sprite-animation-stuck-on-first-frame)

Working with Phaser 3, I’ve preloaded a spritesheet and created a few animations…

import {Scene} from 'phaser';

class BootScene extends Scene {
  constructor() {
    super("scene-boot");
  }

  preload() {
    this.load.spritesheet('px-hero', 'assets/sprites/px-hero.png', {
      frameWidth: 16,
      frameHeight: 16
    });
    // ...
  }

  create() {
    // ...
    this.anims.create({
      key: 'px-hero-idle',
      frames: this.anims.generateFrameNumbers('px-hero', {
        start: 0,
        end: 2
      }),
      frameRate: 10,
      repeat: -1
    });

    this.anims.create({
      key: 'px-hero-run',
      frames: this.anims.generateFrameNumbers('px-hero', {
        start: 3,
        end: 6
      }),
      frameRate: 10,
      repeat: -1
    });
    // ...
  }
}

export default BootScene;

Then inside my Sprite class (which is being instantiated in another scene that the BootScene links to), I’m trying to play the animations…

import {GameObjects} from 'phaser';
const {Sprite} = GameObjects;

class PxHero extends Sprite {
  constructor(config) {
    super(config.scene, config.x, config.y, "px-hero");

    // Add self to scene's physics
    config.scene.physics.world.enable(this);
    config.scene.add.existing(this);

    this.scene = config.scene;

    this.keys = this.scene.input.keyboard.addKeys('W,S,A,D');

    this.speed = 100;
    this.jumpHeight = 300;
  }

  preUpdate(time, delta) {
    const {W, S, A, D} = this.keys;
    const {speed, jumpHeight, body} = this;
    const touchingGround = body.blocked.down;

    if (A.isDown) {
      this.body.setVelocityX(-speed);
      this.setFlipX(true);
    }
    else if (D.isDown) {
      this.body.setVelocityX(speed);
      this.setFlipX(false);
    }
    else {
      this.body.setVelocityX(0);
    }

    if (W.isDown && touchingGround) {
      this.body.setVelocityY(-jumpHeight);
    }

    // Animations
    if (touchingGround) {
      if (body.velocity.x !== 0) {
        this.anims.play('px-hero-run', true); // here
      }
      else {
        this.anims.play('px-hero-idle', true); // and here
      }
    }
  }
}

export default PxHero;

But for some reason they just play the first frame of the animation then get stuck there.

Has anyone encountered this before? I haven’t been able to find any solutions thus far.

:wave: If you override Sprite#preUpdate you need to call it yourself to ensure animations are played.

1 Like

Thanks @samme,

That worked for me, I just created an update function in the Sprite class and called it in the parent scene’s update function instead of relying on overriding.

Is it generally bad practice to override Sprite#preUpdate?