How do Phaser animations work in a class?

Hi all,

I’m really stuck trying to make heads or tails out of Phaser animations. So here is my play class.

I’ve created an animation called shiproll and there are 3 frames in it. I’m just trying to play the animation but it’s just not working. Also I’m not sure if this is the best way to do it too as my code seems a little verbose. Can anyone help please?

import Phaser, { Input, Scene, Math } from 'phaser'

export default class PlayerShip extends Phaser.Physics.Arcade.Sprite {

playerSpeed : number = 3;
scene : Scene;

constructor(scene : Scene, x : number, y : number) {
    super(scene, x, y, 'shooter_graphics', 'PlayerRed_Frame_01')

    scene.add.existing(this)
    scene.physics.add.existing(this)
    this.setScale(.5)
    
    scene.anims.create({
        key: 'shiproll',
        frames: scene.anims.generateFrameNames('shooter_graphics', {
            start: 1,
            end: 3,
            prefix: 'PlayerRed_Frame_0'
        }),
    })
}

preUpdate() {
    this.playerControl()
}

private playerControl() {

    if (Input.Keyboard.JustDown(this.scene.input.keyboard.addKey('SPACE'))) {
        this.scene.events.emit("PLAYER_SHOOT")
    }

    if (Input.Keyboard.JustDown(this.scene.input.keyboard.addKey('A'))) {
        this.flipX = false;
        this.anims.play('shiproll')            
    }
    if (Input.Keyboard.JustUp(this.scene.input.keyboard.addKey('A'))) {
        this.flipX = false;
        this.anims.playReverse('shiproll')
    }

    if (Input.Keyboard.JustDown(this.scene.input.keyboard.addKey('D'))) {
        this.flipX = true;
        this.anims.play('shiproll')
    }
    if (Input.Keyboard.JustUp(this.scene.input.keyboard.addKey('D'))) {
        this.flipX = true;
        this.anims.playReverse('shiproll')
    }

    if (this.scene.input.keyboard.addKey('A').isDown) {
        this.x -= this.playerSpeed
    }
    if (this.scene.input.keyboard.addKey('D').isDown) {
        this.x += this.playerSpeed
    }

    this.x = Math.Clamp(this.x, this.width / 2, 800 - this.width / 2)
}

}

Hi,
You need to change your preUpdate method to:

preUpdate(time, delta) {
    super.preUpdate(time, delta)
    this.playerControl();
}
2 Likes

Oh my goodness, thank you!!! I thought I was going insane. Out of curiosity though, why is that super call needed? Is there any more info on preUpdate?

Phaser.GameObjects.Sprite#preUpdate

1 Like

Create the animations just once, in scene preload().

You probably want to create Key objects only once per sprite instance. So in the constructor, add

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

Then in the update method use this.keys.SPACE etc.

1 Like

Oh that’s is awesome too mate. Thanks for that! Didn’t know about the addKeys method either.

This Arcade Sprite is just going to have 1 one the stage so should be OK, it’s just the player.
But I’m doing the same thing for my enemyShip.ts file. Is it a reasonable performance hit creating animations on a new instantiation?

I would avoid that. You’d just be recreating and then discarding the same animation for each instance.

If you still want to put it in the class somewhere, you could add a static method, e.g. EnemyShip.createAnims(scene), and call it (just once) from scene create().

I think the 2nd instanciation will send an error or warning to the console if the anim key already exists, as samme said, scene preload is the good place to create all the animations.

1 Like