學習 PixiJS — 補間動畫

說明

補間動畫指的是,我們可以通過爲精靈的位置、比例、透明度,等屬性,設置開始值和結束值,製作動畫,動畫中間需要的部分由軟件自動計算填充。

Pixi 沒有內置補間引擎,但是你可以使用很多很好的開源的補間庫,比如 Tween.jsDynamic.js 。如果要製作非常專業的自定義補間效果,可以使用這兩個庫中的其中一個。但是現在我們要使用的是一個名爲 Charm.js 的專門用於 Pixi 的補間庫。

使用 Charm

要開始使用 Charm ,首先直接用 script 標籤,引入 js 文件

<script src="https://www.kkkk1000.com/js/Charm.js"></script>

然後創建它的實例

let c = new Charm(PIXI);

變量 c 現在代表 Charm 實例。

前面的文章中講到的粒子效果一樣,在調用 state 函數之後,必須爲遊戲循環中的每個幀更新補間。就是在遊戲循環中調用 Charm 的 update 方法,如下所示:

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 之前的延遲時間。

示例:

以下是如何使用 slide 方法使精靈用120幀從原始位置移動到座標爲(128,128)的位置的關鍵代碼。

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 — 視覺效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章