Shall I get rid of Animation Events in v3.50?

As I’ve overhauled the Animation system extensively for Phaser 3.50, I’m wondering if I should also get rid of the Animation Events?

To be clear, I’m talking about the events that an Animation instance itself will emit. I would still keep the events that a Sprite emits. The result would be:

const animConfig = {
    key: 'walk',
    frames: 'walker',
    frameRate: 60,
    repeat: -1
};

const walkAnim = this.anims.create(animConfig);

const sprite = this.add.sprite(400, 484, 'walker', 'frame_0000');

sprite.play('walk');

//  By removing the events, the following will NOT work:

walkAnim.on('start', handler);

//  But, this WILL still work:

sprite.on('animationstart', handler);

The reasoning for this is that I’m not convinced anyone actually uses events that come directly from the Animations themselves.

So… do you? Would this break your games? And if so, what’s your use case?

Equally, if this change wouldn’t impact you at all, I’d like to know that too!

Cheers,

Rich

Jumping in to say that this will not affect me. I didn’t know that animation objects had event callbacks. I’ve written a sequencer utility class that returns thenable promises that resolve when a given animation has finished playing. Since the event “animationcomplete” callback takes the completed animation and lets you verify that it’s the animation you’re waiting to complete by checking the key, getting the event from the gameobject itself should be good enough in most cases. Example:

sequence(
        name: string,
        ignoreIfPlaying = false,
        force = false,
        setBusy = false,
        startFrame = 0,
        reverse = false
    ): Promise<string> {
        if (name === this.currentKey && ignoreIfPlaying) {
            return Promise.resolve(name);
        }
        if (this.busy && !force) {
            return Promise.resolve(name);
        }
        this.busy = setBusy;
        if (reverse) {
            this.entity.anims.playReverse(name, false, startFrame);
        } else {
            this.entity.anims.play(name, false, startFrame);
        }

        return new Promise((resolve) => {
            this.entity.on('animationcomplete', (anim: Animation) => {
                if (anim.key === name) { // verify what animation is complete
                    if (setBusy) this.busy = false;
                    resolve(name);
                }
            });
        });
    }

Thanks, yeah it won’t make any difference to your code above. There are new events in 3.50 (and lots of new features around animations) to making chaining and mixing easier, too.

2 Likes

Hi,
I think i always use sprite.on('animationstart…)
So no problem for me

I’m still a rookie, but I also only used the event from the sprite.

I only use the sprite events, too, so this wouldn’t affect me.

I’ll be fine as well.

No problem for me.

P.S. : I think you could add a poll to your post.

I also didn’t know that animation objects had event callbacks :smiley:
it is usually logical to use the sprite events for that, so no problem for me too.

So far I’ve not found a single person who even knew Animations could emit events, so I have removed them all :slight_smile:

I’ve also removed all of the _KEY events except the keyed complete event. But I may put the others back, I’ve not decided yet. I do now pass the key as the new 4th parameter in all other events.

2 Likes

PhaserSpineObject animation states:

spineObject.setAnimation(0, `upgradeBefore${bereik(1, 1)}`, false)
  spineObject.state.listeners[0].start = () => {
    spineObject.setSkinByName(skinName)
    spineObject.setColor(PLAYER_COLOR.PRIMARY, "TINT_1")
    spineObject.state.listeners[0].start = () => {} //clear listener after 1
  }
  spineObject.addAnimation(0, `upgradeAfter${bereik(1, 1)}`, false, 0)
  spineObject.addAnimation(0, "idlePassive1", true, 0)
}

Yeah I also only use the general
this.on(‘animationcomplete’, this.animComplete, this);

the one thing I wanted from animations, was to be able to tell it to send off an event on a specific frame. So for example, if I have a 20 frame attack animation, but at the 10th frame I need something to happen, I would split it up into 2 animations.

It looks like 3.5 might have something to solve that… an event on each frame? thats not bad cause I can then jsut check if its the 10th frame. But would still be cool, if when defining your animation, you could set a “key frame” to trigger an event

I could do this, but please be aware that animations will skip frames if they’re running faster than the game clock can keep up with. So what would be the desired outcome if your key frame was skipped?

oh that is interesting.
Seems like a more complex answer to solve for everyone then - but in all my personal cases, just sending the event as soon as it can to that keyframe (on it, or as soon as it can after if it was skipped) would have the same results. Anything that helps breaking up animations into multiple parts.

I would assume, even if it skips the frame due to game clock, it still knows it would have gone off in that tick, but skipped because it couldnt?

I just started exploring phaser and I’m really happy until now.
So for me it’s not relevant. But may I ask why animations had events when the Sprite also has?