Table of Contents
这里记录的是 Phaser3.50 示例中的 Animation 部分 api 的用法。详情还是看 Phaser api 文档比较好。
Animation
60 fps Animation Test
class FpsAnimationTest extends Phaser.Scene {
  constructor() {
    super()
  }
  preload() {
    this.load.baseURL = globalConfig.baseUrl
    this.load.atlas('walker', 'assets/animations/walker.png', 'assets/animations/walker.json')
    this.load.image('sky', 'assets/skies/ms3-sky.png')
    this.load.image('trees', 'assets/skies/ms3-trees.png')
  }
  create() {
    this.bg = this.add.tileSprite(0, 38, 800, 296, 'sky')
      .setOrigin(0, 0)
    this.trees = this.add.tileSprite(0, 280, 800, 320, 'trees')
      .setOrigin(0, 0)
    
    const animConfig = {
      key: 'walk',
      frames: 'walker',
      frameRate: 60,
      repeat: -1
    }
    this.anims.create(animConfig)
    const sprite = this.add.sprite(400, 484, 'walker', 'frame_0000')
    sprite.play('walk')
  }
  update() {
    this.bg.tilePositionX -= 2
    this.trees.tilePositionX -= 6
  }
}
const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  backgroundColor: '#304858',
  parent: 'demo',
  scene: [FpsAnimationTest]
}
const game = new Phaser.Game(config)
this.add.tileSprite(x, y, width, height, texture [, frame])
创建瓦片精灵游戏对象(TileSprite Game Object)并添加到场景。宽高如果设置为 0,会默认使用纹理帧自身宽高。TileSprite 是可以移动的。移动后的空缺会自动平铺填充。比如 update 里设置 tilePositionX ,TileSprite 对象内部会对精灵图进行偏移,空缺部分会自动填充。TileSprite 可以用来制作动态背景。
this.anims.create(config)
创建动画并添加到动画管理器。动画是全局的,不属于具体的场景。每个场景都可以调用。
| 配置项 | 说明 | 
|---|---|
| key | 动画的名称。 | 
| frames | 动画帧数据来源。 | 
| frameRate | 动画帧率。如果没有指定持续时间(duration)则默认 24。 | 
| duration | 动画持续时间。毫秒。默认根据帧率计算。 | 
| repeat | 重复次数。-1 无限制。默认 0 | 
sprite.play(key [, ignoreIfPlaying] [, startFrame])
播放指定动画。
| 参数 | 说明 | 
|---|---|
| key | 动画名称。 | 
| ignoreIfPlaying | 如果动画已经播放,忽略这次调用。默认 false | 
| startFrame | 开始帧。默认 0 | 
Add Animation Event
class AddAnimationEvent extends Phaser.Scene {
  constructor() {
    super()
  }
  preload() {
    this.load.baseURL = globalConfig.baseUrl
    this.load.atlas('gems', 'assets/tests/columns/gems.png', 'assets/tests/columns/gems.json')
    this.y = 160
  }
  create() {
    this.add.text(400, 32, '点击创建动画', { color: '#00ff00' })
      .setOrigin(0.5, 0)
    // 每当往动画管理器里添加一个动画的时候都会调用下面的函数
    this.anims.on(Phaser.Animations.Events.ADD_ANIMATION, this.addAnimation, this)
    this.i = 0
    
    this.input.on('pointerup', function() {
      switch(this.i) {
        case 0:
          this.anims.create({
            key: 'diamond',
            frames: this.anims.generateFrameNames(
              'gems',
              {
                prefix: 'diamond_',
                end: 15,
                zeroPad: 4
              }
            ),
            repeat: -1
          })
          break
        case 1:
          this.anims.create({
            key: 'prism',
            frames: this.anims.generateFrameNames(
              'gems',
              {
                prefix: 'prism_',
                end: 6,
                zeroPad: 4
              }
            ),
            repeat: -1
          })
          break
        case 2:
          this.anims.create({
            key: 'ruby',
            frames: this.anims.generateFrameNames(
              'gems',
              {
                prefix: 'ruby_',
                end: 6,
                zeroPad: 4
              }
            ),
            repeat: -1
          })
          break
        case 3:
          this.anims.create({
            key: 'square',
            frames: this.anims.generateFrameNames(
              'gems',
              {
                prefix: 'square_',
                end: 14,
                zeroPad: 4
              }
            ),
            repeat: -1
          })
          break
      }
      this.i++
    }, this)
  }
  addAnimation(key) {
    this.add.sprite(400, this.y, 'gems')
      .play(key)
    this.y += 100
  }
}
this.anims.on(event, fn [, context])
添加动画事件。可用事件在 Phaser.Animations.Events 部分。
this.anims.generateFrameNames(key [, config])
根据纹理键名和配置对象生成动画帧对象。config 部分配置项如下:
| 配置项 | 说明 | 
|---|---|
| prefix | 名称前缀 | 
| end | 最后帧数字 | 
| zeroPad | 帧数字长度。不足的左侧补零 | 
比如有名为 gems 的纹理集包含 ruby_0001, ruby_0002 等帧,可以通过 this.anims.generateFrameNames(‘gems’, { prefix: ‘ruby_’, end: 6, zeroPad: 4 }) 来生产配置。
Add Frames To Existing Animation
class AddFramesToExistingAnimation extends Phaser.Scene {
  constructor() {
    super()
  }
  preload() {
    this.load.baseURL = globalConfig.baseUrl
    this.load.atlas('gems', 'assets/tests/columns/gems.png', 'assets/tests/columns/gems.json')
    this.y = 160
  }
  create() {
    this.add.text(400, 32, '点击添加动画帧', { color: '#00ff00' })
      .setOrigin(0.5, 0)
    this.anims.create({
      key: 'diamond',
      frames: this.anims.generateFrameNames(
        'gems',
        {
          prefix: 'diamond_',
          end: 15,
          zeroPad: 4
        }
      ),
      repeat: -1
    })
    
    const group = this.add.group({
      key: 'gems',
      frame: 'diamond_0000',
      frameQuantity: 6 * 6
    })
    Phaser.Actions.GridAlign(
      group.getChildren(),
      {
        width: 6,
        height: 6,
        cellWidth: 64,
        cellHeight: 64,
        x: 240,
        y: 160
      }
    )
    group.playAnimation('diamond')
    
    this.input.once('pointerup', function() {
      const diamond = this.anims.get('diamond')
      // 添加新的动画帧到当前动画
      const newFrames = this.anims.generateFrameNames(
        'gems',
        {
          prefix: 'square_',
          end: 14,
          zeroPad: 4
        }
      )
      diamond.addFrame(newFrames)
    }, this)
  }
}
group.playAnimation(key [, startFrame])
每一个游戏对象都(按照指定帧数)播放指定的动画。
this.input.once(event, fn [, context])
一次事件监听。
this.anims.get(key)
返回指定动画。
diamond.addFrame(config)
根据帧配置对象数组追加动画帧。
AnimationProgress
class AnimationProgress extends Phaser.Scene {
  constructor() {
    super()
  }
  preload() {
    this.load.baseURL = globalConfig.baseUrl
    this.load.atlas('gems', 'assets/animations/diamond.png', 'assets/animations/diamond.json')
  }
  create() {
    this.anims.create({
      key: 'diamond',
      frames: this.anims.generateFrameNames(
        'gems',
        {
          prefix: 'diamond_',
          end: 15,
          zeroPad: 4
        }
      ),
      frameRate: 16,
      yoyo: true,
      repeat: -1,
      repeatDelay: 300
    })
    this.gem = this.add.sprite(400, 480, 'gems')
      .play('diamond')
      .setScale(4)
    
    this.debug = this.add.graphics()
  }
  update() {
    this.debug.clear()
    const size = 672
    this.debug.fillStyle(0x2d2d2d)
    this.debug.fillRect(64, 64, size, 48)
    this.debug.fillStyle(0x2dff2d)
    this.debug.fillRect(64, 64, size * this.gem.anims.getProgress(), 48)
  }
}
this.debug.fillRect(x, y, width, height)
this.gem.anims.getProgress()
this.gem 是精灵游戏对象,.anims 是该对象的动画控制器,.getProgress() 可以获取动画进度(0 ~ 1)。该方法不考虑 repeat 非零和 yoyo 为 true 的情况。如果 repeat 非零,想获取全局进度,需要使用 getTotalProgress() 方法。
Aesprite Animation
const config = {
  type: Phaser.AUTO,
  parent: 'demo',
  width: 800,
  height: 600,
  pixelArt: true,
  scene: {
    preload,
    create
  }
}
const game = new Phaser.Game(config)
function preload() {
  this.load.baseURL = globalConfig.baseUrl + 'assets/animations/aseprite/'
  this.load.aseprite('paladin', 'paladin.png', 'paladin.json')
}
function create() {
  const tags = this.anims.createFromAseprite('paladin')
  const sprite = this.add.sprite(500, 300).play({
    key: 'Magnum Break',
    repeat: -1
  }).setScale(6)
  for (let i = 0; i < tags.length; i++) {
    const label = this.add.text(32, 32 + i * 16, tags[i].key, { color: '#00ff00' })
    label.setInteractive()
  }
  this.input.on('gameobjectdown', function(pointer, obj) {
    console.log(obj)
    sprite.play({
      key: obj.text,
      repeat: -1
    })
  })
  this.input.on('gameobjectover', function(pointer, obj) {
    obj.setColor('#ff00ff')
  })
  this.input.on('gameobjectout', function(pointer, obj) {
    obj.setColor('#00ff00')
  })
}
3.24 文档里暂无关于 aseprite 的 api。可能要等 3.25 的文档。
游戏配置项里的 pixelArt
控制缩放模糊算法。如果为 true,则为线性过滤模式,图片放大会表现出锐利的像素风。否则会模糊。
label.setInteractive([shape] [, callback] [, dropZone])
将此游戏对象添加到 Input 管理器中,并支持相关事件。如果不传参数,默认事件区域为游戏对象的矩形包围框。如果是图形对象(Graphics)或者位图文字对象(BitmapText),必须提供 shape 参数和 callback 参数。
| 参数 | 说明 | 
|---|---|
| shape | 响应事件的区域。默认矩形。 | 
| callback | 事件回调。如果提供了 shape 参数,此参数也许提供。 | 
| dropZone | 是否作为 drop 目标。默认 false。 | 
Chained Animation
lancelot.anims.getName()
3.24 文档暂无。获取当前动画名称。
lancelot.playAfterRepeat(key [, repeatCount])
3.50 新增的方法。完成指定次数的当前动画后开始指定的动画。如果当前没有动画,立即开始指定的动画。
| 参数 | 说明 | 
|---|---|
| key | 指定的动画。 | 
| repeatCount | 当前动画重复次数。默认 1. | 
lancelot.chain([key])
当前动画完成后开始指定的系列动画。
Create Animation From Canvas
this.textures.createCanvas(key [, width] [, height])
使用空白 canvas 创建纹理。宽高默认 256。
canvasFrame.add(name, sourceIndex, x, y, width, height)
给纹理(Phaser.Textures.Texture)加帧。
| 参数 | 说明 | 
|---|---|
| key | 帧名称 | 
| sourceIndex | 属于纹理中的哪一个纹理资源(TextureSource) | 
| x | 帧的横坐标 | 
| y | 帧的纵坐标 | 
| width | 帧宽 | 
| height | 帧高 | 
Create Animation From Sprite Sheet
this.add.grid([x] [, y] [, width] [, height] [, cellWidth] [, cellHeight] [, fillColor] [, fillAlpha] [, outlineFillColor] [, outlineFillAlpha])
创建网格对象。
| 参数 | 说明 | 
|---|---|
| x | 左上角横坐标。默认 0 | 
| y | 左上角纵坐标.默认 0 | 
| width | 网格宽度。默认 128 | 
| height | 网格高度。默认 128 | 
| cellWidth | 网格单元宽度。默认 32 | 
| cellHeight | 网格单元高度。默认 32 | 
| fillColor | 网格单元填充颜色。可选 | 
| fillAlpha | 网格单元填充透明度。可选 | 
| outlineFillColor | 网格单元之间线条颜色。可选 | 
| outlineFillAlpha | 网格单元之间线条颜色透明度。可选 | 
Animation Create Animation On Sprite
Phaser.GameObjects.Sprite.anims.create()
直接在精灵对象上创建动画,此时创建的动画只属于这个精灵,不能全局调用。
Animation Cubes
Phaser.GameObjects.Group.children
群组的 children 属性是一个 Phaser.Structs.Set 类。该类有 iterate、each 等遍历方法。entries 属性为游戏对象合集。size 表示游戏对象数量。详情见 Phaser.Structs.Set 部分
this.anims.staggerPlay(key, children [, stagger])
对拥有动画组件的游戏对象适应给定的动画。每个动画按照 stagger 进行延迟播放。
| 参数 | 说明 | 
|---|---|
| key | 动画名称 | 
| children | 游戏对象数组 | 
Animation Export
获取动画的 json 字符串。
// 获取某个动画的 json 字符串 console.log(JSON.stringify(this.anims.get(key))) // 这个返回的是一个对象 console.log(this.anims.get(key).toJSON()) // json 字符串 console.log(JSON.stringify(this.anims.toJSON(key))) // 所有动画的 json 字符串 console.log(JSON.stringify(this.anims))
From Animation JSON
this.load.animation(key [, url] [, dataKey] [, xhrSettings])
添加动画配置 json 文件到当前加载队列。文件加载完成后会自动传给全局动画管理器的 fromJSON 方法。这个过程会在所有文件加载完毕后发生。
Mixed Animation
this.anims.addMix(animA, animB, delay)
从动画 animA 到动画 animB 时延迟 delay 毫秒。
Multi Atalas Animation
this.load.multiatlas(key [, atlasURL] [, path] [, baseURL] [, atlasXhrSettings])
加载多个纹理图集。纹理图集的图片地址在图集 json 文件中指定。path 是加载指定图片时的路径。
Pause All Animations
Phaser.GameObjects.Sprite.setDepth(value)
设置层级。也就是 z-index。
Phaser.GameObjects.Sprite.playAfterDelay(config, delay)
延迟指定时间后播放指定动画。
| 配置项 | 说明 | 
|---|---|
| key | 动画的名称。 | 
| repeatDelay | 重复延迟。 | 
this.anims.pauseAll()、this.anims.resumeAll()
暂停所有动画、继续所以动画。
Pause Animation Instances
// ……
const square = this.anims.create({ key: 'square', frames: this.anims.generateFrameNames('gems', { prefix: 'square_', end: 14, zeroPad: 4 }), repeat: -1 });
// ……
square.pause()
square.resume()
Phaser.Animations.Animation.pause()、Phaser.Animations.Animation.resume()
暂停此类型动画的实例、继续此类型动画的实例。
Play After Delay
Phaser.GameObjects.Sprite.anims.playAfterDelay(key, delay)
Reverse Animation
Phaser.GameObjects.Sprite.playReverse(key)
this.anims.reverse()
Phaser.GameObjects.Text.setText(value)
设置文本。字符串数组会自动添加 \n 换行。
Show Animation Play Through
Phaser.GameObjects.Sprite.anims.restart()
重新开始动画。
Tween Timescale
this.tweens.add(config)
config 里有个 timeScale 的配置。{ from: 0.5, to: 2 }。但 3.24 文档里未找到说明,3.50-beta-11 的代码里也未发现。