iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
Modern Web

再談 PixiJS,那些先前不一定有提到的部分與地雷系列 第 29

[Re:PixiJS - Day29] 使用 TexturePacker 製作 AnimatedSprite 與 Sprite 的大圖與 json 檔

這篇介紹 TexturePacker 工具,並使用匯出的 .json檔Spritesheet圖

今日目標:

  • 使用 Loader 讀取 .json 檔,同時處理完各個 texture 的快取
  • 將 TexturePacker 產生的 Animation 指定給 PIXI.AnimatedSprite
  • 將 TexturePacker 產生的 Animation 指定給 PIXI.Sprite

今天的文章使用 Free Version 版本的 TexturePacker,沒有使用到進階功能


處理素材:

  • 數組連續圖檔
  • 一些單張圖檔,連續圖檔一起合成一張,以 減少Request

  • bunny_b_0~4.png 為兔子變藍色的連續圖
  • bunny_g_0~4.png 為兔子變綠色的連續圖
  • bunny_r_0~4.png 為兔子變紅色的連續圖
  • 其他為單張圖

通通丟進 TexturePacker 裡:


會直接拼成一張 spritesheet


預覽連續圖

1. 將連續圖複選起來
2. 點右上角 Preview Anims 按鈕

開啟 Animation preview 視窗可調整預覽速度

勾選 Auto-detect animations 後,會直接將名字相近的連續圖群組起來

以本例來說,名字相近的連續圖檔為:

  • bunny_b_0~4.png
  • bunny_g_0~4.png
  • bunny_r_0~4.png
  • 其他為單張圖

TexturePacker 在解析檔名與群組後的結果為:

"animations": {
	"bunny_b": ["bunny_b_0.png","bunny_b_1.png","bunny_b_2.png","bunny_b_3.png","bunny_b_4.png"],
	"bunny_g": ["bunny_g_0.png","bunny_g_1.png","bunny_g_2.png","bunny_g_3.png","bunny_g_4.png"],
	"bunny_r": ["bunny_r_0.png","bunny_r_1.png","bunny_r_2.png","bunny_r_3.png","bunny_r_4.png"]
},

組好的 bunny_bbunny_gbunny_r 即為後續可帶入的 animation


將連續圖動態塞進 PIXI.AnimatedSprite 裡

[ Demo ]

用 Loader 讀取 Spritesheet 素材:

const loader = PIXI.Loader.shared;
loader.add({
    name: 'bunnies',
    url: 'bunnies9.json',
});

從前幾天的文章可知,使用 TexturePacker 轉出來的 .json檔,因為符合一些條件,在讀入後會產生一個 PIXI.Spritesheet 類別spritesheet 物件

這個物件裡有 animations物件
animations物件 裡則是剛剛自動依據名字生成的 animationbunny_bbunny_gbunny_r


產生 PIXI.AnimatedSprite 實體並帶入 Animation:

function startApp() {
    // 先取得 resource 裡的 spritesheet
    const bunnySpritesheet = PIXI.Loader.shared.resources.bunnies.spritesheet;
    
    // 將 spritesheet.animations 裡的 animation 帶進 PIXI.AnimatedSprite 實體
    bunnyR = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny_r);
    bunnyG = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny_g);
    bunnyB = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny_b);
    
    // 設定 bunnyR 的位置、播放速度、開始播放等
    bunnyR.animationSpeed = 0.1;
    bunnyR.play();
    
    bunnyG.animationSpeed = 0.1;
    bunnyG.play();
    
    bunnyB.animationSpeed = 0.1;
    bunnyB.play();
};

完成!


使用 Spritesheet 裡的 其他texture

PIXI.Sprite 使用 texture 的兩種方法:

方法1: new PIXI.Sprite(PIXI.Texture)

方法2: PIXI.Sprite.from(PIXI.Texture)

兩種方法都要將 PIXI.Texture 帶入


既然要帶入 PIXI.Texture,來找看看哪些是 PIXI.Texture

  • 建立一個物件,指向剛剛讀入的素材 bunnies
// 取得 resource
const bunnyResource = PIXI.Loader.shared.resources.bunnies;

讀入素材裡有 textures物件textures物件裡有依據檔名產生的 PIXI.Texture

例如:
bunnyResource.textures['halfAlphaBunny.png'] 是一個名為 halfAlphaBunny.pngPIXI.Texture

// 可使用 resource[素材名].textures 裡的 texture
const halfAlphaBunnyTexture = bunnyResource.textures['halfAlphaBunny.png'];
const bunnyHelfAlpha = new PIXI.Sprite(halfAlphaBunnyTexture);
app.stage.addChild(bunnyHelfAlpha);

讀入素材可解析成 PIXI.Spritesheet 時,
讀入素材的 spritesheet 裡也有 textures物件 ,可找到 相同的 PIXI.Texture

// 可使用 resource[素材名].spritesheet.textures 裡的 texture
const halfAlphaBunnyTexture = bunnyResource.spritesheet.textures['halfAlphaBunny.png'];

const bunnyHelfAlpha = new PIXI.Sprite(halfAlphaBunnyTexture);
app.stage.addChild(bunnyHelfAlpha);

兩段Code 僅有中間多一個 spritesheet. 差異,其餘相同

都能取得 halfAlphaBunny.png 的 texture,接著可使用 PIXI.Sprite產生實體 加到場景上


要取得素材名,還要取得 textures 好麻煩

還有一種簡單取得 Texture 的方式:透過快取

先前提到 .json檔 讀入後,會自動產生 各個Texture快取

此時可很簡單的使用 PIXI.Sprite.from快取名 產生 PIXI.Sprite實體

const rot90bunny = PIXI.Sprite.from("rot90bunny.png"); // 或是 "bunny.png" ...等

並直接使用


Sprite sheet 裡的 Texture 都是同一個 BaseTexture

先前提過:
不同的Texture 可以有 相同的BaseTexture
以 Sprite sheet 來討論的 Texture / BaseTexture 會更有感覺

左上: 名為 bunny.pngTexture,為大張 Sprite sheet (BaseTextrue) 的一部份
中下: 名為 rot90bunny.pngTexture,為大張 Sprite sheet (BaseTextrue) 的一部份

比對兩個 TextureBaseTexture:結果為相同


補充:
How to create sprite sheets & animations for PixiJS 4


上一篇
[Re:PixiJS - Day28] Loader 的其他特性
下一篇
[Re:PixiJS - Day30] 完賽 / 未完賽
系列文
再談 PixiJS,那些先前不一定有提到的部分與地雷45
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言