学习 PixiJS — 补间动画

说明

补间动画指的是,咱们能够经过为精灵的位置、比例、透明度,等属性,设置开始值和结束值,制做动画,动画中间须要的部分由软件自动计算填充。html

Pixi 没有内置补间引擎,可是你可使用不少很好的开源的补间库,好比 Tween.jsDynamic.js 。若是要制做很是专业的自定义补间效果,可使用这两个库中的其中一个。可是如今咱们要使用的是一个名为 Charm.js 的专门用于 Pixi 的补间库。git

使用 Charm

要开始使用 Charm ,首先直接用 script 标签,引入 js 文件github

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

而后建立它的实例canvas

let c = new Charm(PIXI);
复制代码

变量 c 如今表明 Charm 实例。数组

前面的文章中讲到的粒子效果同样,在调用 state 函数以后,必须为游戏循环中的每一个帧更新补间。就是在游戏循环中调用 Charm 的 update 方法,以下所示:ide

function gameLoop() {
    requestAnimationFrame(gameLoop);
    state();
    c.update();
    renderer.render(stage);
}
复制代码

滑动补间

Charm 最有用的补间效果之一是 slide 。使用 slide 方法可使精灵从画布上的当前位置平滑移动到任何其余位置。slide 方法有七个参数,但只有前三个参数是必需的。函数

名称 默认值 描述
anySprite 须要移动的精灵
finalXPosition 滑动结束时 x 坐标
finalYPosition 滑动结束时 y 坐标
durationInFrames 60 补间须要的帧数,也就是动画应该持续多长时间
easingType "smoothstep" 缓动类型
yoyo false 用于肯定精灵是否应在补间的起点和终点之间来回移动。
delayTimeBeforeRepeat 0 一个以毫秒为单位的数字,用于肯定精灵 yoyo 以前的延迟时间。

示例:oop

如下是如何使用 slide 方法使精灵用120帧从原始位置移动到坐标为(128,128)的位置的关键代码。post

c.slide(sprite, 128, 128, 120);
复制代码

效果图: 学习

查看示例

若是你想让精灵在起点和终点之间来回移动,请将 yoyo(第六个参数)设置为 true,代码以下所示:

c.slide(sprite, 128, 128, 120, "smoothstep", true);
复制代码

查看示例

补间对象

Charm 全部的补间方法都返回一个补间对象,你能够这样建立:

let slidePixie = c.slide(sprite, 80, 128, 120, "smoothstep",true);
复制代码

slidePixie 就是补间对象,它包含一些有用的属性和方法,能够用于控制补间。

其中一个是 onComplete 方法,它将在补间完成后当即运行。如下代码是精灵到达终点时如何使用 onComplete 方法在控制台中显示消息。

let slidePixie = c.slide(sprite, 80, 128, 120, "smoothstep",true);
slidePixie.onComplete = () => console.log("一次滑动完成");
复制代码

若是将 yoyo (slide 方法的第六个参数)设置为 true,则每当精灵到达其起点和终点时,onComplete 方法都将运行。

补间还有 pause 和 play 方法,能够中止和开始补间。

slidePixie.pause();
slidePixie.play();
复制代码

补间对象还具备 playing 属性,若是补间当前正在播放,则该属性值为 true。只不过有些补间方法返回的对象中直接有 playing 属性,有些补间方法返回的对象中的 playing 属性是在一个叫 tweens 的数组中, tweens 数组中包括了这个补间方法建立的全部补间对象。 以 slide 方法为例,完成一个滑动须要建立 x 轴补间对象和 y 轴补间对象,这两个对象都放在了 tweens 数组中,这两个对象也都分别有 playing 属性。

查看示例

全部 Charm 的补间方法都返回你能够控制和访问的补间对象。

设置缓动类型

slide 方法的第四个参数是 easingType 。它是一个字符串,用于肯定补间加速和减速的类型。这些类型共有15种可供选择,而且它们对于 Charm 的全部不一样补间方法都是相同的。某些类型对应的会有一个基本类型,一个 squared 类型和一个cubed 类型。squared 类型和 cubed 类型只是将基本类型的效果放大而已。大多数 Charm 的补间效果的默认缓动类型是 smoothstep。

Linear: linear,精灵从开始到中止保持匀速运动。

Smoothstep: smoothstepsmoothstepSquaredsmoothstepCubed。加速精灵并以很是天然的方式减慢速度

Acceleration: accelerationaccelerationCubed。逐渐加速精灵并忽然中止。 若是要更加平滑的加速效果,请使用 sinesineSquaredsineCubed

Deceleration: decelerationdecelerationCubed。忽然加速精灵并逐渐减慢它。要得到更加平滑的减速效果,请使用inverseSineinverseSineSquaredinverseSineCubed

Bounce: bounce 10 -10 ,这将使精灵到达起点和终点时略微反弹,更改乘数10和 -10,能够改变效果。

查看示例

使用 slide 进行场景过渡

你在游戏或应用程序中确定要作的一件事就是让场景过渡,而后将新场景滑入视图。它多是你游戏的标题滑动以显示游戏的第一级,或者多是一个菜单,能够滑动以显示更多的应用程序内容。你可使用 slide 方法执行此操做。

首先,建立两个容器对象:sceneOnesceneTwo,并将它们添加到舞台上。

sceneOne = new Container();
sceneTwo = new Container();
stage.addChild(sceneOne);
stage.addChild(sceneTwo);
复制代码

接下来,为每一个场景建立精灵。制做一个像画布同样大的蓝色矩形; 并在矩形中间添加上 Scene One 的文字,将二者都添加到 sceneOne 容器中。再制做一个像画布同样大的红色矩形;并在矩形中间添加上Scene Two 的文字,将这二者添加到 sceneTwo 容器中。你最终获得的两个容器对象,以下图所示。

如下是关键代码:

//1. Scene one sprites: 
//画蓝色矩形
let blueRectangle = new PIXI.Graphics();
blueRectangle.beginFill(0x014ACA);
blueRectangle.drawRect(0, 0, canvasWith, canvasHeight);
blueRectangle.endFill();
sceneOne.addChild(blueRectangle);

//添加文字,并在容器中居中
let sceneOneText = new PIXI.Text("Scene One");
sceneOneText.style = { fill: "#fff", fontSize: "40px" };
let sceneOneTextX = (canvasWith - sceneOneText.width) / 2;
let sceneOneTextY = (canvasWith - sceneOneText.height) / 2;
sceneOneText.position.set(sceneOneTextX, sceneOneTextY);
sceneOne.addChild(sceneOneText);

//2. Scene two sprites:
//画红色矩形
let redRectangle = new PIXI.Graphics();
redRectangle.beginFill(0xEF4631);
redRectangle.drawRect(0, 0, canvasWith, canvasHeight);
redRectangle.endFill();
sceneTwo.addChild(redRectangle);

//添加文字,并在容器中居中
let sceneTwoText = new PIXI.Text("Scene Two");
sceneTwoText.style = { fill: "#fff", fontSize: "40px" };
let sceneTwoTextX = (canvasWith - sceneTwoText.width) / 2;
let sceneTwoTextY = (canvasHeight - sceneTwoText.height) / 2;
sceneTwoText.position.set(sceneTwoTextX, sceneTwoTextY);
sceneTwo.addChild(sceneTwoText);
复制代码

在一个真实的项目中,你能够为每一个容器填充每一个场景所需的精灵数量,你也能够为你的项目添加尽量多的场景容器。

接下来,将 sceneTwo 移开,使其位于画布的右边缘以外。代码以下所示:

sceneTwo.x = canvasWith;
复制代码

这将在画布上显示 sceneOne,而 sceneTwo 在须要时会从左侧滑出,以下所示。

sceneTwo 就在屏幕外等着。

最后,使用 slide 方法从 sceneOne 过渡到 sceneTwo 。只需将 sceneOne 滑动到左侧,而后从右侧滑动 sceneTwo ,取代它的位置,代码以下。

c.slide(sceneTwo, 0, 0);
c.slide(sceneOne, -canvasWith, 0);
复制代码

下图显示了这段代码的效果。

查看示例

时间过渡

你能够自定义一个 wait 函数在设定的时间间隔后进行过渡。

function wait(duration = 0) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, duration);
    });
}
复制代码

要使用 wait,请为其提供一个参数,它表明你但愿等待的时间(以毫秒为单位)。如下是在延迟1秒(1000毫秒)后从 sceneOne 过渡到 sceneTwo 的方法。

wait(1000).then(() => {
    c.slide(sceneTwo, 0, 0);
    c.slide(sceneOne, -canvasWith, 0);
});
复制代码

查看示例

其实在 Charm 库中已经定义了 wait 这个方法,原理和上面的 wait 函数是同样的。你能够这样使用它。

c.wait(1000).then(() => {
    c.slide(sceneTwo, 0, 0);
    c.slide(sceneOne, -canvasWith, 0);
});
复制代码

沿贝塞尔曲线移动

若是你还不清楚什么是贝塞尔曲线,能够先看看这篇文章

slide 方法沿直线为精灵制做动画,但你也可使用另外一种方法(followCurve)使精灵沿贝塞尔曲线移动。首先,将贝塞尔曲线定义为4个坐标点的二维数组,以下所示:

let curve = [
    [sprite.x, sprite.y], //起始点
    [108, 32], //控制点1
    [176, 32], //控制点2
    [196, 160] //结束点
];
复制代码

followCurve 方法的参数以下:

名称 默认值 描述
anySprite 须要移动的精灵
curve 贝塞尔曲线数组
durationInFrames 60 补间须要的帧数,也就是动画应该持续多长时间
easingType "smoothstep" 缓动类型
yoyo false 用于肯定精灵是否应在补间的起点和终点之间来回移动。
delayTimeBeforeRepeat 0 一个以毫秒为单位的数字,用于肯定精灵 yoyo 以前的延迟时间。

接下来,使用 CharmfollowCurve 方法使精灵跟随该曲线。(提供 curve 数组做为第二个参数)

c.followCurve(
 sprite, //须要移动的精灵
 curve, //贝塞尔曲线数组
 120, //持续时间,以帧为单位
 "smoothstep", //缓动类型
 true, //yoyo
 1000 //yoyo以前的延迟时间
);
复制代码

效果图:

若是你须要使精灵的中点沿着曲线移动,还须要设置精灵的锚点(anchor)居中,以下所示:

sprite.anchor.set(0.5, 0.5);
复制代码

查看示例

slidefollowCurve 方法适用于简单的来回动画效果,但你也能够结合它们以使精灵遵循更复杂的路径。

沿路径移动

你可使用 CharmwalkPath 方法链接一系列点,并使精灵移动到每一个点。该系列中的每一个点都称为 waypoint 。首先,从由坐标点组成的二维数组定位路径点开始,这些 waypoint 映射出你但愿精灵遵循的路径。

let waypoints = [
 [32, 32], //要移动到的第一个坐标点
 [32, 128], //要移动到的第二个坐标点
 [300, 128], //要移动到的第三个坐标点
 [300, 32], //要移动到的第四个坐标点
 [32, 32] //要移动到的第五个坐标点
];
复制代码

你能够根据须要使用任意多的 waypoint

walkPath 方法的参数以下:

名称 默认值 描述
anySprite 须要移动的精灵
waypoints 坐标点的二维数组
durationInFrames 60 补间须要的帧数,也就是动画应该持续多长时间
easingType "smoothstep" 缓动类型
loop false 用于肯定精灵在到达结尾时是否从头开始
yoyo false 用于肯定精灵是否应在补间的起点和终点之间来回移动。
delayBetweenSections 0 一个以毫秒为单位的数字,用于肯定精灵在移动到路径的下一部分以前应该等待的时间。

接下来,使用 walkPath 方法使精灵按顺序移动到全部这些点。(前两个参数是必需的)

c.walkPath(
    sprite, //须要移动的精灵
    waypoints, //坐标点的二维数组
    300, //持续时间,以帧为单位
    "smoothstep", //缓动类型
    true, //循环
    true, //轮流反向播放动画
    1000 //移动到路径的下一部分以前应该等待的时间
);
复制代码

效果图:

查看示例

而使用 walkCurve 方法,可使精灵遵循一系列链接的贝塞尔曲线。首先,建立任何贝塞尔曲线数组,描述你但愿精灵遵循的路径。

let curvedWaypoints = [
 //第一条曲线
 [[sprite.x, sprite.y],[75, 500],[200, 500],[300, 300]],
 //第二条曲线
 [[300, 300],[250, 100],[100, 100],[sprite.x, sprite.y]]
];
复制代码

每条曲线的四个点与 followCurve 方法中的相同:起始位置,控制点1,控制点2和结束位置。第一条曲线中的最后一个点应与下一条曲线中的第一个点相同。你能够根据须要使用尽量多的曲线。

walkCurve 方法的参数以下:

名称 默认值 描述
anySprite 须要移动的精灵
curvedWaypoints 贝塞尔曲线的坐标点的数组
durationInFrames 60 补间须要的帧数,也就是动画应该持续多长时间
easingType "smoothstep" 缓动类型
yoyo false 用于肯定精灵是否应在补间的起点和终点之间来回移动。
delayBeforeContinue 0 一个以毫秒为单位的数字,用于肯定精灵yoyo以前的延迟时间。

接下来,提供 curvedWaypoints 数组做为 walkCurve 方法中的第二个参数,来试试这个方法。

c.walkCurve(
    sprite, //须要移动的精灵
    curvedWaypoints, //贝塞尔曲线的坐标点的数组
    300, //持续时间,以帧为单位
    "smoothstep", //缓动类型
    true, //循环
    true, //轮流反向播放动画
    1000 //移动到路径的下一部分以前应该等待的时间
);
复制代码

效果图:

查看示例

使用 walkPath 和 walkCurve 将为你提供了一个很好的开端,它们能够为游戏制做一些有趣的动画。

更多补间效果

Charm 有许多其余内置的补间效果,你会发现它们在游戏和应用程序中有不少用处。下面是其余一些效果的介绍。

fadeOut 和 fadeIn fadeOut 方法使精灵逐渐变得透明,fadeIn 方法使精灵从透明逐渐显现。这两个方法须要的参数是同样的。

参数:

名称 默认值 描述
anySprite 须要产生效果的精灵
durationInFrames 60 持续的帧数

示例:

c.fadeOut(anySprite);
c.fadeIn(anySprite);
复制代码

查看示例

pulse

使用 pulse 方法可使精灵以稳定的速率连续淡入淡出。

参数:

名称 默认值 描述
anySprite 须要产生效果的精灵
durationInFrames 60 淡入淡出应该持续的帧数,也就是持续时间
minAlpha 0 精灵能够减小到的最小的透明度值

示例:

c.pulse(anySprite);
复制代码

查看示例

若是你只但愿精灵在再次淡入以前变为半透明,请将第三个参数设置为0.5,以下所示:

c.pulse(anySprite, 60, 0.5);
复制代码

scale

你可使用 scale 方法让精灵产生缩放效果。

参数:

名称 默认值 描述
anySprite 须要产生效果的精灵
endScaleX 0.5 x 轴缩放的比例
endScaleY 0.5 y 轴缩放的比例
durationInFrames 60 持续时间,以帧为单位

示例:

c.scale(
    sprite, //精灵
    0.1, //x轴缩放的比例
    0.1, //y轴缩放的比例
    100 //持续时间,以帧为单位
);
复制代码

查看示例

breathe

若是你但愿缩放效果来回 yoyo,请使用 breathe 方法。它是一种缩放效果,使精灵看起来好像在呼吸。

参数:

名称 默认值 描述
anySprite 须要产生效果的精灵
endScaleX 0.5 x 轴缩放的比例
endScaleY 0.5 y 轴缩放的比例
durationInFrames 60 持续时间,以帧为单位
yoyo true 是否轮流反向播放
delayBeforeRepeat 0 一个以毫秒为单位的数字,用于肯定精灵 yoyo 以前的延迟时间。

示例:

c.breathe(
    sprite, //精灵
    0.1, //x轴缩放的比例
    0.1, //y轴缩放的比例
    100, //持续时间,以帧为单位
    true, //轮流反向播放 
    0, //yoyo 之间的延迟时间
);
复制代码

查看示例

strobe

使用 strobe 方法经过快速改变精灵比例,使精灵看起来像闪光灯同样闪烁。

参数: 只须要传入一个精灵做为参数便可。

示例:

c.strobe(sprite);
复制代码

查看示例

wobble

使用 wobble 方法可使精灵像果冻同样摆动。

参数: 只须要传入一个精灵做为参数便可。

示例:

c.wobble(sprite);
复制代码

查看示例

若是你使用这些缩放补间效果(scale,breathe,strobe,或者 wobble),将精灵的锚点居中,就能够从精灵的中心进行缩放。

sprite.anchor.set(0.5, 0.5);
复制代码

注意:
目前, Charm 这个库支持的 Pixi 版本是 3.0.11。若是使用比较高的版本会有一些问题,好比出现这样的警告。

这是由于 Pixi 版本4.0.0起已弃用 ParticleContainer ,改成使用 particles.ParticleContainer 了。因此要解决这个问题须要把 Charm.js 文件中的 ParticleContainer 改成 particles.ParticleContainer 。

上一篇 学习 PixiJS — 视觉效果

下一篇 学习 PixiJS — 碰撞检测

相关文章
相关标签/搜索