学习 PixiJS — 动画精灵

说明

看完官方教程中提到的这本书 — Learn Pixi.js ,准备写写读后感了,官方教程中所说的内容,基本上就是书的前4章,因此我就从第5章开始写写吧。javascript

动画精灵指的是按顺序使用一系列略有不一样的图像,建立的精灵,以后一帧一帧的播放这些图像,就能够产生运动的幻觉。html

也就是说用这种图片java

在这里插入图片描述

作出这样的效果 git

在这里插入图片描述

要制做动画精灵咱们须要用到 PixiJSAnimatedSprite 方法。github

PIXI.extras.AnimatedSprite

定义:spring

使用纹理数组建立动画精灵的方法。json

用法:canvas

new PIXI.extras.AnimatedSprite(textures,autoUpdate)
复制代码

参数 :跨域

名称 类型 默认值 描述
textures array 用一系列略有不一样的图像作的纹理数组。
autoUpdate boolean true 用来判断是否使用 PIXI.ticker.shared 自动更新动画时间。

返回值:
返回一个对象,对象会有一些属性和方法,用于控制动画精灵。数组

返回值对象的属性:

名称 类型 描述
animationSpeed number 动画精灵的播放速度。越高越快,越低越慢,默认值是1
currentFrame number(只读) 正在显示的当前帧编号
onComplete function loop属性为false时,一个动画精灵完成播放时调用
playing Boolean 肯定当前动画精灵是否正在播放
onFrameChange function 当一个动画精灵更改要呈现的纹理时调用
loop boolean 动画精灵是否在播放后重复播放
onLoop function loop属性为true时调用的函数
textures array 用于这个动画精灵的纹理数组
totalFrames number (只读) 动画中的帧总数

返回值对象的方法:

名称 参数 描述
play 播放动画精灵
gotoAndPlay frameNumber,number类型,开始帧的索引 转到特定的帧并开始播放动画精灵
stop 中止播放动画精灵
gotoAndStop frameNumber,number类型,中止帧的索引 转到特定的帧并中止播放动画精灵

使用返回值中的这些属性和方法,咱们就能够控制动画精灵了,好比播放动画精灵,设置动画的速度,设置是否循环播放等,除此以外,还要知道就是 PIXI.extras.AnimatedSprite 方法继承自 PIXI.Sprite 方法,因此动画精灵也能够用普通精灵的属性和方法,好比xywidthheightscalerotation

好的,咱们开始试试这个方法。

<!doctype html>
<html lang="zn">

<head>
    <meta charset="UTF-8">
    <title>动画精灵</title>
</head>

<body>
    <div id="px-render"></div>

    <script src="https://www.kkkk1000.com/js/pixi4.8.2.js"></script>
    <script> // 建立一个 Pixi应用 须要的一些参数 let option = { width: 400, height: 300, transparent: true, } // 建立一个 Pixi应用 let app = new PIXI.Application(option); // 获取渲染器 let renderer = app.renderer; let playground = document.getElementById('px-render'); // 把 Pixi 建立的 canvas 添加到页面上 playground.appendChild(renderer.view); //设置别名 let TextureCache = PIXI.utils.TextureCache; let Texture = PIXI.Texture; let Rectangle = PIXI.Rectangle; let AnimatedSprite = PIXI.extras.AnimatedSprite; //须要加载的雪碧图的地址(该图片服务器端已作跨域处理) let imgURL = "https://user-gold-cdn.xitu.io/2019/1/14/16849ce12c0e953a?w=320&h=286&f=png&s=27286"; //加载图像,加载完成后执行setup函数  PIXI.loader.add(imgURL).load(setup); function setup() { //获取纹理 let base = TextureCache[imgURL]; //第一个纹理 let texture0 = new Texture(base); texture0.frame = new Rectangle(0, 0, 80, 143); //第二个纹理 let texture1 = new Texture(base); texture1.frame = new Rectangle(80, 0, 80, 143); //第三个纹理 let texture2 = new Texture(base); texture2.frame = new Rectangle(160, 0, 80, 143); //第四个纹理 let texture3 = new Texture(base); texture3.frame = new Rectangle(240, 0, 80, 143); //建立纹理数组 let textures = [texture0, texture1, texture2, texture3]; //建立动画精灵 let pixie = new PIXI.extras.AnimatedSprite(textures); //设置动画精灵的速度 pixie.animationSpeed = 0.1; //把动画精灵添加到舞台 app.stage.addChild(pixie); //播放动画精灵 pixie.play(); } </script>
</body>

</html>
复制代码

查看效果

上面这个例子中,建立纹理数组时彷佛点麻烦,要解决这个问题,咱们能够用名叫 SpriteUtilities 的库,该库包含许多有用的函数,用于建立Pixi精灵并使它们更易于使用。

安装:

直接用 script 标签,引入js 文件就能够

<script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
复制代码

安装好以后,咱们须要建立一个新实例,代码以下

let su = new SpriteUtilities(PIXI);
复制代码

以后就能够用 su 对象访问全部方法了。

咱们这里须要用到的就是 su 对象的 filmstrip 方法。

定义:

filmstrip 方法能够自动将雪碧图转换为可用于制做精灵的纹理数组

用法:

su.filmstrip("anyTilesetImage.png", frameWidth, frameHeight, optionalPadding);
复制代码

参数:

名称 类型 描述
anyTilesetImage string 雪碧图的路径
frameWidth number 每帧的宽度(以像素为单位)
frameHeight number 每帧的高度(以像素为单位)
optionalPadding number 每帧周围的填充量(可选值,以像素为单位)

返回值:

返回一个数组,可用于制做动画精灵的纹理数组。

如今咱们使用 SpriteUtilities 来改写下刚才的示例代码。

<!doctype html>
<html lang="zn">

<head>
    <meta charset="UTF-8">
    <title>动画精灵</title>
</head>

<body>
    <div id="px-render"></div>

    <script src="https://www.kkkk1000.com/js/pixi4.8.2.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script> //建立一个 Pixi应用 须要的一些参数 let option = { width: 400, height: 300, transparent: true, } //建立一个 Pixi应用 let app = new PIXI.Application(option); //获取渲染器 let renderer = app.renderer; let playground = document.getElementById('px-render'); //把 Pixi 建立的 canvas 添加到页面上 playground.appendChild(renderer.view); let su = new SpriteUtilities(PIXI); //须要加载的雪碧图的地址(该图片服务器端已作跨域处理) let imgURL = "https://user-gold-cdn.xitu.io/2019/1/14/16849ce12c0e953a?w=320&h=286&f=png&s=27286"; PIXI.loader.add(imgURL).load(setup); function setup() { //建立纹理数组 let frames = su.filmstrip(imgURL, 80, 143); //建立动画精灵 let pixie = new PIXI.extras.AnimatedSprite(frames); //设置动画精灵的速度 pixie.animationSpeed = 0.1; //把动画精灵添加到舞台 app.stage.addChild(pixie); //播放动画精灵 pixie.play(); } </script>
</body>

</html>
复制代码

查看效果

filmstrip 方法自动将整个雪碧图转换为可用于制做动画精灵的纹理数组。可是,若是咱们只想使用雪碧图中的一部分帧呢?这时候须要用到 frames 方法了。

定义:

frames 方法使用雪碧图中的一组子帧,来建立纹理数组。

用法:

su.frames(source, coordinates, frameWidth, frameHeight)
复制代码

参数:

名称 类型 描述
source string 雪碧图的路径
coordinates array 包含每帧的 x 和 y 坐标的二维数组
frameWidth number 每帧的宽度(以像素为单位)
frameHeight number 每帧和高度(以像素为单位)

返回值:
返回一个数组,可用于制做动画精灵的纹理数组。

示例代码:

<!doctype html>
<html lang="zn">

<head>
    <meta charset="UTF-8">
    <title>动画精灵</title>
</head>

<body>
    <div id="px-render"></div>

    <script src="https://www.kkkk1000.com/js/pixi4.8.2.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script> //建立一个 Pixi应用 须要的一些参数 let option = { width: 400, height: 300, transparent: true, } //建立一个 Pixi应用 let app = new PIXI.Application(option); //获取渲染器 let renderer = app.renderer; let playground = document.getElementById('px-render'); //把 Pixi 建立的 canvas 添加到页面上 playground.appendChild(renderer.view); let su = new SpriteUtilities(PIXI); //须要加载的雪碧图的地址(该图片服务器端已作跨域处理) let imgURL = "https://user-gold-cdn.xitu.io/2019/1/14/16849ce12c0e953a?w=320&h=286&f=png&s=27286"; PIXI.loader.add(imgURL).load(setup); function setup() { //建立纹理数组 let frames = su.frames(imgURL, [[0, 0], [80, 0], [160, 0], [240, 0]], 80, 143); //建立动画精灵 let pixie = new PIXI.extras.AnimatedSprite(frames); //设置动画精灵的速度 pixie.animationSpeed = 0.1; //把动画精灵添加到舞台 app.stage.addChild(pixie); //播放动画精灵 pixie.play(); } </script>
</body>

</html>
复制代码

查看效果

除了上面提到的方式,还能够用纹理贴图集来建立动画精灵。

使用纹理贴图集来建立动画精灵,就是先经过json文件,加载全部纹理,而后把须要的纹理再放进一个数组中,最后把这个数组当参数,传入PIXI.extras.AnimatedSprite 方法中,来建立动画精灵。

代码:

<!doctype html>
<html lang="zn">

<head>
    <meta charset="UTF-8">
    <title>动画精灵</title>
</head>

<body>
    <div id="px-render"></div>

    <script src="https://www.kkkk1000.com/js/pixi4.8.2.js"></script>
    <script> //建立一个 Pixi应用 须要的一些参数 let option = { width: 400, height: 300, transparent: true, } //建立一个 Pixi应用 let app = new PIXI.Application(option); //获取渲染器 let renderer = app.renderer; let playground = document.getElementById('px-render'); //把 Pixi 建立的 canvas 添加到页面上 playground.appendChild(renderer.view); //须要加载的纹理贴图集的地址 let textureURL = "https://www.kkkk1000.com/images/learnPixiJS-AnimatedSprite/dnf.json"; //加载纹理贴图集,加载完成后执行setup函数 PIXI.loader.add(textureURL).load(setup); function setup() { let id = PIXI.loader.resources[textureURL].textures; //建立纹理数组 let frames = [ id["dnf0.png"], id["dnf1.png"], id["dnf2.png"], id["dnf3.png"] ]; //建立动画精灵 let pixie = new PIXI.extras.AnimatedSprite(frames); //设置动画精灵的速度 pixie.animationSpeed = 0.1; //把动画精灵添加到舞台 app.stage.addChild(pixie); //播放动画精灵 pixie.play(); } </script>
</body>

</html>
复制代码

查看效果

上面的代码建立纹理数组时,是把纹理一个一个的放进数组中,若是数量比较少还好,多一点呢?假若有100个呢?一个一个的放就太麻烦了,这时候咱们能够用 SpriteUtilities 库中提供的 frameSeries 方法。

定义:

frameSeries 方法能够经过已加载的纹理贴图集,使用一系列编号的帧ID来建立动画精灵。

用法:

su.frameSeries(startNumber, endNumber, baseName, extension)
复制代码

参数:

名称 类型 描述
startNumber number 起始帧序列号(默认值是0)
endNumber number 结束帧序列号(默认值是1)
baseName string 可选的基本文件名
extension string 可选的文件扩展名

返回值:
返回一个数组,可用于制做动画精灵的纹理数组。

注意:
使用 frameSeries 方法时,要确保在 json 文件中,定义的每帧的名称都是按顺序来的,好比 frame0.png frame1.png frame2.png 这种。由于 frameSeries 方法的源码是这样写的

frameSeries(startNumber = 0, endNumber = 1, baseName = "", extension = "") {
   //建立一个数组来存储帧名
   let frames = [];

   for (let i = startNumber; i < endNumber + 1; i++) {
     let frame = this.TextureCache[`${baseName + i + extension}`];
     frames.push(frame);
   }
   return frames;
 }
复制代码

源码中实际上是用 for 循环把帧名拼接起来的。因此要保证帧名是按顺序来的,否则就获取不到了。

下来咱们就试试 frameSeries 方法吧。

<!doctype html>
<html lang="zn">

<head>
    <meta charset="UTF-8">
    <title>动画精灵</title>
</head>

<body>
    <div id="px-render"></div>

    <script src="https://www.kkkk1000.com/js/pixi4.8.2.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script> //建立一个 Pixi应用 须要的一些参数 let option = { width: 400, height: 300, transparent: true, } //建立一个 Pixi应用 let app = new PIXI.Application(option); //获取渲染器 let renderer = app.renderer; let playground = document.getElementById('px-render'); //把 Pixi 建立的 canvas 添加到页面上 playground.appendChild(renderer.view); let su = new SpriteUtilities(PIXI); //须要加载的纹理贴图集的地址 let textureURL = "https://www.kkkk1000.com/images/learnPixiJS-AnimatedSprite/dnf.json"; PIXI.loader.add(textureURL).load(setup); function setup() { //建立纹理数组 debugger; let frames = su.frameSeries(0, 7, "dnf", ".png"); //建立动画精灵 let pixie = new PIXI.extras.AnimatedSprite(frames); //设置动画精灵的速度 pixie.animationSpeed = 0.1; //把动画精灵添加到舞台 app.stage.addChild(pixie); //播放动画精灵 pixie.play(); } </script>
</body>

</html>
复制代码

查看效果

注意版本问题:
一、PIXI.extras.AnimatedSprite 这个方法原来叫PIXI.extras.MovieClip ,是在 4.2.1 版本的时候修改的,本文示例代码中用 PixiJS 的版本是 4.8.2,因此没有问题,若是你在使用过程当中发现调用PIXI.extras.AnimatedSprite 这个方法有问题,能够先检查下版本是否正确。

二、 SpriteUtilities 目前支持的 PixiJS 的版本是 3.0.11,而 SpriteUtilities 中用的就是PIXI.extras.MovieClip 方法,因此你若是用了比较高的 PixiJS 的版本,须要在SpriteUtilities 中修改下方法的别名。

spriteUtilities.js 文件中须要把 renderingEngine.extras.MovieClip 改为renderingEngine.extras.AnimatedSprite,把 renderingEngine.ParticleContainer 改为 PIXI.particles.ParticleContainer

这个 spriteUtilities.js 就是修改后的。

固然你也可使用低版本的 PixiJS,这样就不用改 spriteUtilities.js 的代码了。

总结

动画精灵就是逐帧动画,经过一帧一帧的播放图像来产生运动的幻觉。

本文就是聊了聊建立动画精灵的一些方式和如何使用动画精灵。

若是文中有错误的地方,还请小伙伴们指出,万分感谢。

下一篇 学习 PixiJS — 精灵状态