为了制作冷却动画,我加载了一堆图像。在 Phaser 3 中使用 crop 或 tweens 来完成这项工作是否可行?

To make a cool-down animation I loaded a bunch of images. Is it feasible to use crop or tweens in Phaser 3 to do the job?

我正在尝试使用 Phaser 3 制作一个带有冷却动画的按钮。这是代码。

class BootScene extends Phaser.Scene {
  constructor() {
    super();
  }
  
  preload() {
    this.load.path = 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/cooldown/';
    for (var i = 0; i < 16; i++) {
      this.load.image("cooldown" + i, "cooldown" + i + ".png");
    }
    this.load.image('magicAttack', 'magicAttack.png');

  }
  create() {
    this.add.image(100, 100, 'magicAttack').setScale(1)
    var cd = this.add.sprite(100, 100, 'cooldown1').setFlipX(false).setScale(1.5)
    let ani_frames = [];
    for (var i = 0; i < 16; i++) {
      ani_frames.push({ key: "cooldown" + i })
    }
    this.anims.create({
      key: 'right',
      frames: ani_frames,
      frameRate: 11,
      repeat: 0
    });
    cd.play('right');
        let circle2 = this.add.circle(100, 100, 150, 0x000000, 0).setScale(.2)
    cd.on('animationcomplete', () => {
      cd.setVisible(false)
    });
    // circle.lineStyle(10, 0xffffff, 0.9);
    circle2.setStrokeStyle(50, 0x000000, 1);
  }
  
}

var config = {
  width: 400,
  height: 300,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 0
      },
      debug: false // set to true to view zones
    }
  },
  backgroundColor: 0x000000,
  scene: [BootScene]
}

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

上面的代码按预期工作,但可能有点重量级。

我知道我可以制作一个精灵-sheet但它仍然是图像方式。在 Phaser 3 中使用 crop or tweens 来完成这项工作是否可行?

我知道我也可以在场景中放置一个 DOM,因为使用 div 可以使动画看起来更容易。不过,好像少了Phaser的风格吧?

此解决方案中的代码并没有短多少,而是多了一点cleaner/reuseable。
我会使用 Phaser Masks (here is the link to the documentation)
并且创建一个助手class,将整个遮罩和补间逻辑从场景中抽象出来。

这个助手 class 使得按钮也可以重复使用(助手的名字 class 可能不是最好的)。

大意是:

  • 为图像的“遮罩”部分创建遮罩
  • 用补间改变蒙版,补间只改变可见/隐藏的圆的百分比。
  • 在 Tween Update Methode 上,Phaser 图形对象(蒙版)被重新渲染。

次要更新:更正了蒙版起始角度,使其与您的示例相匹配。

class Button {
    constructor(scene, gameObject){
        this.scene = scene;
        this.mask = scene.add.graphics().setVisible(false);
        this.mask.x = gameObject.x;
        this.mask.y = gameObject.y;
        gameObject.mask = new Phaser.Display.Masks.BitmapMask(scene, this.mask);
    }

    play(){
        this.scene.tweens.add({
            targets: this,
            hiddenPercent: { from: 0, to: 1 },
            ease: 'Power0',
            repeat: 0,
            duraton: 300,
            onUpdate: _ => this.render()
        });
    }

    render(){
        this.mask.clear();
        this.mask.fillStyle(0, 1);
        this.mask.beginPath();
        this.mask.slice(0, 0, 24, -Math.PI/2, (2 * Math.PI * this.hiddenPercent) -Math.PI/2 , false);
        this.mask.fillPath();
    }
}

class BootScene extends Phaser.Scene {
  preload() {
    this.load.image('magicAttack', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/cooldown/magicAttack.png');
  }
  create() {
    let hand = this.add.image(100, 100, 'magicAttack').setScale(1);
    let button = new Button(this, hand);
    button.play();
  }
}

var config = {
  width: 400,
  height: 300,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 0
      },
      debug: false // set to true to view zones
    }
  },
  backgroundColor: 0x000000,
  scene: [BootScene]
}

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