似乎 Phaser 3 会为单个动画抛出两次 "animationcomplete" 通知,我该如何将其设为一个?

It seems Phaser 3 throws "animationcomplete" notification twice for a single animation, how do I make it one?

我对 'animationcomplete' 通知感到困惑。我以为当我听的动画结束时我会收到一次通知。原来我会收到n次通知。这是代码。

class BootScene extends Phaser.Scene {
  constructor() {
    super({ key: 'BootScene' });
  }
  preload() {
    this.load.spritesheet('brawler', 'https://raw.githubusercontent.com/photonstorm/phaser3-examples/master/public/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
  }
  create() {

    this.anims.create({
      key: 'win',
      frames: this.anims.generateFrameNumbers('brawler', { frames: [ 30, 31 ] }),
      frameRate: 8,
      repeat: 0,
    });
    const cody = this.add.sprite(200, 70);
    cody.setScale(8);

    let btn = this.add.rectangle(500, 70, 200, 150, '#000')
    this.add.text(500, 70, 'click')

    btn.setInteractive();
    btn.on('pointerdown', () => {
      console.log('pointerdown');
      cody.play('win');
      cody.on('animationcomplete', (e) => {
        console.log(e.key);
      });
    });
  }
}

var config = {
  width: 800,
  height: 500,
  backgroundColor: '#555',
  scene: [BootScene]
}

var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

我放了两个console.log,一个用于pointerdown,另一个用于animationcomplete

我第一次点击 btn,我得到一个 pointerdown 和一个 animationcomplete。第二次单击 btn,我得到一个 pointerdown 和两个 animationcomplete

我第n次点击btn怎么只得到一个animationcomplete

正如 @Ourobours 提到的,您在每次点击时附加了 animationcomplete 的新事件处理程序。
由于您可以为同一事件附加多个 event-handlers,所有这些都将在下次触发时执行,依此类推。

您只需要将 animationcomplete event-handler 移出 pointerdown 事件处理程序函数,一切都会如您所愿。

这是一个工作演示:

class BootScene extends Phaser.Scene {
  constructor() {
    super({ key: 'BootScene' });
  }
  preload() {
    this.load.spritesheet('brawler', 'https://raw.githubusercontent.com/photonstorm/phaser3-examples/master/public/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
  }
  create() {

    this.anims.create({
      key: 'win',
      frames: this.anims.generateFrameNumbers('brawler', { frames: [ 30, 31 ] }),
      frameRate: 8,
      repeat: 0,
    });
    const cody = this.add.sprite(200, 70);
    cody.setScale(8);

    let btn = this.add.rectangle(500, 70, 200, 150, '#000')
    this.add.text(500, 70, 'click')

    btn.setInteractive();
    
    cody.on('animationcomplete', (e) => {
        console.log(e.key);
    });
      
    btn.on('pointerdown', () => {
      console.log('pointerdown');
      cody.play('win');

    });
  }
}

var config = {
  width: 800,
  height: 500,
  backgroundColor: '#555',
  scene: [BootScene],
  banner:false
}

var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>