动画精灵PIXI.AnimatedSprite

405 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

一、前言

接上期,我们完成了一个由pixi完成的小demo,但感觉还不够动态,所以今天我们用动画精灵来补救补救吧,源码我就放最后了,码上掘金的在线版本还需要等一段时间,等我琢磨明白那个是怎么用的才能放出来链接。

二、过程

1、本期思路

构思了一下本期思路:

1、创建两个tom,一个是静止的,一个是动画精灵,当成奔跑时的状态

2、碰撞检测的函数修改为狗子出现,tom赶紧回头就跑

3、tom跑出canvas范围,触发结局。

2、准备素材

动画精灵可以利用图片数组来完成,也可以直接用专门的json串来定义,本文纯属个人娱乐,所以我就截了几张tom奔跑的图来做动画精灵。下面三张图放在public下。

"tom1.png","tom2.png","tom3.png"

3、生成一个静止的tom

用来充当前期胸有成竹的tom,自信满满的逼近jerry

cat = new PIXI.Sprite(app.loader.resources["tom.png"].texture)
  //  调整汤姆的大小和位置
  //Change the sprite's position
  cat.x = 40
  cat.y = 190
  // 用cat.scale.set(0.5, 0.5)也可以,缩放大小为原图的一半
  //Change the sprite's size
  cat.width = 80
  cat.height = 245
  // 实现sprite水平镜像反转
  // 设置anchor  0left 0.5center 1right
  cat.anchor.x = 0.5
  // 水平缩放比例为-1
  cat.scale.x *= -1
  

4、生成一个慌忙逃跑的tom

用来切换tom看见狗子慌乱逃跑的样子,这里采用AnimatedSprite创建。

首先定义好图片数组

 let alienImages = ["tom1.png","tom2.png","tom3.png"]

然后依次用Texture读取文件,push进textureArray


let textureArray = []

 for (let i=0; i < 3; i++)
 {
     let texture = PIXI.Texture.from(alienImages[i])
     textureArray.push(texture)
 }

之后接一段类似sprite的配置,定义好大小位置,是否反转,同时先隐藏,到时机了再显示

 catAnimate = new PIXI.AnimatedSprite(textureArray)
 catAnimate.x = 40
 catAnimate.y = 175

 // 用cat.scale.set(0.5, 0.5)也可以,缩放大小为原图的一半
 //Change the sprite's size
 catAnimate.width = 80
 catAnimate.height = 240
 // 实现sprite水平镜像反转
 // 设置anchor  0left 0.5center 1right
 catAnimate.anchor.x = 0.5
 // 水平缩放比例为-1
 catAnimate.scale.x *= -1
 catAnimate.visible = false

设置一下动画相关属性,首先是动画播放速度,设置loop属性,如果设置为true,那基本触发不了onComplete函数,还能调用gotoAndPlay设置从第几帧开始播放,可以采用更多的图片当帧数,这样会更加流畅。

 catAnimate.animationSpeed = 0.2 // 1,每秒播放60张图片
 catAnimate.loop = true // 循环
 catAnimate.onComplete = () => {
   console.log("播放完成")
 } //完成的回调函数
 catAnimate.gotoAndPlay(0) // 第0帧开始播放

5、在游戏循环里书写逻辑

首先是碰撞检测,当tom碰到jerry之后,给予狗子速度,狗子会从右方出现

  // 如果相撞了
  if (hitTestRectangle(cat, mouse)) {
    dogVX = -3
  }
  

然后限制下狗子停在jerry前方

  if(dog.x <= mouse.x - 40) {
    dogVX = 0
  }
  

当tom回头跑,也就是速度为负数时,开启动画

 if(catVX < 0) {
    catAnimate.visible = true
    cat.visible = false
  } else {
    catAnimate.visible = false
    cat.visible = true
  }

设立游戏结束条件

 // 游戏结束
  if(cat.x < 0) {
    // // 隐藏开始场景和游戏场景,开启游戏结束场景
    startGame.visible = false
    Game.visible = false
    overGame.visible = true
  }

其他逻辑跟之前的demo基本一致,生成PIXI.Application,设立游戏循环,键盘监测等等,可以翻阅我之前的文章。

6、游戏效果

效果比之前稍微好一点了,动起来感觉就像个动画?

狗子.gif

7、源码

这里只放修改过的源码部分,具体完整版源码,可以看我另一篇文章初试pixijs,实现猫和老鼠小游戏(下),本来想试试码上掘金的功能的,不过暂时还没适配好,就后续再放出来。

新建变量

let catAnimate: PIXI.AnimatedSprite
let dog: PIXI.Sprite
let dogVX = 0// 设置狗子的速度属性

修改了的play函数

// 游戏循环函数--具体处理逻辑
function play(delta: number) {
  cat.x += catVX
  catAnimate.x += catVX
  if(catVX < 0) {
    catAnimate.visible = true
    cat.visible = false
  } else {
    catAnimate.visible = false
    cat.visible = true
  }
  bg.x += bgVX
  dog.x += dogVX
  if(dog.x <= mouse.x - 40) {
    dogVX = 0
  }
  // 如果相撞了
  if (hitTestRectangle(cat, mouse)) {
    dogVX = -3
  } else if (!hitTestRectangle(cat, mouse)) {
  }
  // 游戏结束
  if(cat.x < 0) {
    // // 隐藏开始场景和游戏场景,开启游戏结束场景
    startGame.visible = false
    Game.visible = false
    overGame.visible = true
  }
}

游戏场景里多了狗子和动画tom的相关逻辑,结束场景我换了个图gameover2.jpeg

// 游戏场景的精灵
function gameScene(): void {
  // 设置背景
  // bg = new PIXI.Sprite(app.loader.resources["bg.jpeg"].texture)
  bg = new PIXI.TilingSprite(app.loader.resources["bg.png"].texture, 1800, 400) // 替换为这一行代码
  bg.x = 0
  bg.y = 0
  bg.width = 1800
  bg.height = 400
  Game.addChild(bg)
  
  cat = new PIXI.Sprite(app.loader.resources["tom.png"].texture)
  //  调整汤姆的大小和位置
  //Change the sprite's position
  cat.x = 40
  cat.y = 190
  // 用cat.scale.set(0.5, 0.5)也可以,缩放大小为原图的一半
  //Change the sprite's size
  cat.width = 80
  cat.height = 245
  // 实现sprite水平镜像反转
  // 设置anchor  0left 0.5center 1right
  cat.anchor.x = 0.5
  // 水平缩放比例为-1
  cat.scale.x *= -1
 
  let alienImages = ["tom1.png","tom2.png","tom3.png"]
  let textureArray = []

  for (let i=0; i < 3; i++)
  {
      let texture = PIXI.Texture.from(alienImages[i])
      textureArray.push(texture)
  }

  catAnimate = new PIXI.AnimatedSprite(textureArray)
  catAnimate.x = 40
  catAnimate.y = 175

  // 用cat.scale.set(0.5, 0.5)也可以,缩放大小为原图的一半
  //Change the sprite's size
  catAnimate.width = 80
  catAnimate.height = 240
  // 实现sprite水平镜像反转
  // 设置anchor  0left 0.5center 1right
  catAnimate.anchor.x = 0.5
  // 水平缩放比例为-1
  catAnimate.scale.x *= -1
  catAnimate.visible = false
  catAnimate.animationSpeed = 0.2 // 1,每秒播放60张图片
  catAnimate.loop = true // 循环
  catAnimate.onComplete = () => {
    console.log("播放完成")
  } //完成的回调函数
  catAnimate.gotoAndPlay(0) // 第几帧开始播放
  Game.addChild(cat)
  Game.addChild(catAnimate)
  mouse = new PIXI.Sprite(app.loader.resources["jerry.png"].texture)
  //  调整杰瑞的大小和位置
  //Change the sprite's position
  mouse.x = 300
  mouse.y = 320
  //Change the sprite's size
  mouse.width = 40
  mouse.height = 60
  // 实现sprite水平镜像反转
  // 设置anchor  0left 0.5center 1right
  mouse.anchor.x = 0.5
  // 水平缩放比例为-1
  mouse.scale.x *= -1
  // 杰瑞应该比汤姆小只
  Game.addChild(mouse)

  dog = new PIXI.Sprite(app.loader.resources["dog.png"].texture)
  //  调整杰瑞的大小和位置
  //Change the sprite's position
  // dog.x = 340
  dog.x = 500

  dog.y = 170
  //Change the sprite's size
  dog.width = 140
  dog.height = 240
  // 实现sprite水平镜像反转
  // 设置anchor  0left 0.5center 1right
  dog.anchor.x = 0.5
  // 水平缩放比例为-1
  dog.scale.x *= -1
  // 杰瑞应该比汤姆小只
  Game.addChild(dog)
}
// 结束场景的精灵
function overScene(): void {
  let overbg = new PIXI.Sprite(app.loader.resources["gameover2.jpeg"].texture)
  overbg.width = 400
  overbg.height = 400
  overGame.addChild(overbg)

  let style = new PIXI.TextStyle({
    fontFamily: "Futura",
    fontSize: 20,
    fill: "#646cffaa"
  });
  let message = new PIXI.Text("tom被狗子追上狠揍了一顿!", style)
  message.x = 100
  message.y = 10

  overGame.addChild(message)

  
}


三、小结

今天也只是简单完善了下之前的demo,不过pixi不愧是出名的动画库,功能十分强大,大家也可以去试一下。

ps: 我是地霊殿__三無,期待和你一同成长!

Snipaste_2022-07-19_15-30-26.jpg