學習 PixiJS — 動畫精靈

說明

看完官方教程中提到的這本書 — Learn Pixi.js ,準備寫寫讀後感了,官方教程中所說的內容,基本上就是書的前4章,所以我就從第5章開始寫寫吧。

動畫精靈指的是按順序使用一系列略有不同的圖像,創建的精靈,之後一幀一幀的播放這些圖像,就可以產生運動的幻覺。

也就是說用這種圖片

在這裏插入圖片描述

做出這樣的效果
在這裏插入圖片描述

要製作動畫精靈我們需要用到 PixiJSAnimatedSprite 方法。

PIXI.extras.AnimatedSprite

定義:

使用紋理數組創建動畫精靈的方法。

用法:

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://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.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://www.kkkk1000.com/images/learnPixiJS-AnimatedSprite/dnf.png";
 
        //加載圖像,加載完成後執行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://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script>
        //創建一個 Pixi應用 需要的一些參數
        var option = {
            width: 400,
            height: 300,
            transparent: true,
        }
        //創建一個 Pixi應用
        var app = new PIXI.Application(option);
        //獲取渲染器
        var renderer = app.renderer;
        var playground = document.getElementById('px-render');
        //把 Pixi 創建的 canvas 添加到頁面上
        playground.appendChild(renderer.view);
         
        let su = new SpriteUtilities(PIXI);
        //需要加載的雪碧圖的地址(該圖片服務器端已做跨域處理)
        let imgURL = "https://www.kkkk1000.com/images/learnPixiJS-AnimatedSprite/dnf.png";
        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://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script>
        //創建一個 Pixi應用 需要的一些參數
        var option = {
            width: 400,
            height: 300,
            transparent: true,
        }
        //創建一個 Pixi應用
        var app = new PIXI.Application(option);
        //獲取渲染器
        var renderer = app.renderer;
        var playground = document.getElementById('px-render');
        //把 Pixi 創建的 canvas 添加到頁面上
        playground.appendChild(renderer.view);
         
        let su = new SpriteUtilities(PIXI);
        //需要加載的雪碧圖的地址(該圖片服務器端已做跨域處理)
        let imgURL = "https://www.kkkk1000.com/images/learnPixiJS-AnimatedSprite/dnf.png";

        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://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
    <script>
        //創建一個 Pixi應用 需要的一些參數
        var option = {
            width: 400,
            height: 300,
            transparent: true,
        }
        //創建一個 Pixi應用
        var app = new PIXI.Application(option);
        //獲取渲染器
        var renderer = app.renderer;
        var 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://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
    <script src="https://www.kkkk1000.com/js/spriteUtilities.js"></script>
    <script>
        //創建一個 Pixi應用 需要的一些參數
        var option = {
            width: 400,
            height: 300,
            transparent: true,
        }
        //創建一個 Pixi應用
        var app = new PIXI.Application(option);
        //獲取渲染器
        var renderer = app.renderer;
        var 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() { 
            //創建紋理數組
            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>

查看效果

注意版本問題:
1、PIXI.extras.AnimatedSprite 這個方法原來叫PIXI.extras.MovieClip ,是在 4.2.1 版本的時候修改的,本文示例代碼中用 PixiJS 的版本是 4.8.2,所以沒有問題,如果你在使用過程中發現調用PIXI.extras.AnimatedSprite 這個方法有問題,可以先檢查下版本是否正確。

2、 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 的代碼了。

總結

動畫精靈就是逐幀動畫,通過一幀一幀的播放圖像來產生運動的幻覺。

本文就是聊了聊創建動畫精靈的一些方式和如何使用動畫精靈。

如果文中有錯誤的地方,還請小夥伴們指出,萬分感謝。

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