說明
看完官方教程中提到的這本書 — Learn Pixi.js ,準備寫寫讀後感了,官方教程中所說的內容,基本上就是書的前4章,所以我就從第5章開始寫寫吧。
動畫精靈指的是按順序使用一系列略有不同的影象,建立的精靈,之後一幀一幀的播放這些影象,就可以產生運動的幻覺。
也就是說用這種圖片
做出這樣的效果
要製作動畫精靈我們需要用到 PixiJS 的 AnimatedSprite 方法。
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 方法,所以動畫精靈也可以用普通精靈的屬性和方法,比如x
,y
,width
,height
,scale
,rotation
。
好的,我們開始試試這個方法。
<!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>
複製程式碼
注意版本問題:
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 的程式碼了。
總結
動畫精靈就是逐幀動畫,通過一幀一幀的播放影象來產生運動的幻覺。
本文就是聊了聊建立動畫精靈的一些方式和如何使用動畫精靈。
如果文中有錯誤的地方,還請小夥伴們指出,萬分感謝。