iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
Modern Web

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

[Re:PixiJS - Day27] Loader(2/2) / 解析 JSON 檔與讀取成 PIXI.Spritesheet

  • 分享至 

  • xImage
  •  

PixiJS 是怎麼把 Spritesheet JSON 檔讀成 PIXI.Spritesheet 後給 PIXI.AnimatedSprite 使用的?


[ Demo ]:
準備了幾個讀取的檔案:

  • bunniesJSONJSON格式,使用 TexturePackerPublish sprite sheet 功能 匯出 的 JSON 檔。
  • bunniesJSONNoFrameJSON格式,另一個 JSON 檔。
const loader = PIXI.Loader.shared;
loader.add('bunny', 'assets/basics/bunny.png');
loader.add('bunniesJSON', 'bunnies.json');
loader.add('bunniesJSONNoFrame', 'bunnies_noFrams.json');

一般 JSON 與可解析成 PIXI.Spritesheet 的 JSON 檔的相同處

左: 可解析成 PIXI.Spritesheet 的 JSON 檔
右: 一般 JSON 檔

  • 黃框上: JSON 原始資料皆存在 resources[命名/檔名][data] 裡
  • 黃框下: type 同為1,表示是 JSON格式

PIXI.LoaderResource.TYPE: JSON檔的 type類型1


一般 JSON 與可解析成 PIXI.Spritesheet 的 JSON 檔的相異處

左: 可解析成 PIXI.Spritesheet 的 JSON 檔
右: 一般 JSON 檔

  • 黃框上: 可解析成 Spritesheet 的 JSON 檔,children 陣列裡有物件
  • 黃框下: 可解析成 Spritesheet 的 JSON 檔,有 spritesheettexture 兩個物件。

為什麼使用 TexturePacker 的 Publish sprite sheet 功能匯出 的 JSON 檔,會有 spritesheet 與 textures 兩個物件?

這問題困擾了一陣子,後來在 SpritesheetLoader 原始碼裡找到答案

  • 讀入的檔案要有 data 屬性
  • 讀入檔案為 JSON 格式
  • 讀入檔案的 data 屬性裡必須要有 frames 屬性

同時滿足這幾個條件後,讀入的 Resource 會解析成 PIXI.Spritesheet
並同時有spritesheet 物件(即 PIXI.Spritesheet),與 textures 兩個物件

Resource.texturesResource.spritesheet.textures相同的東西


由於 PIXI.SpritesheetPIXI.AnimatedSprite 有點相近,先前有些疑惑:

  • PIXI.Spritesheet 不是可視物件,其中的 animations 屬性裡有材質陣列可讓 AnimatedSprite實體 使用,但本身不是可視物件 (不在 Display 繼承清單內)。

舉例來說,bunniesJSON.spritesheet.animations 裡有個 bunny 陣列,這個陣列就是 PIXI.AnimatedSprit實體 用來跑動態的材質陣列


AnimatedSprite 的建構式:

new PIXI.AnimatedSprite (textures, autoUpdate) 
  • textures 為 PIXI.Texture 的陣列

AnimatedSprite說明文件 裡,提到了兩種將材質帶入 PIXI.AnimatedSprite 實體的方法:

1- 手動整理帶入的材質陣列:

官網裡三個相關範例都是使用這個方式:

2- 使用 PIXI.Spritesheet 裡 animatoins 物件的某段 animation 資料:

專案上會由設計匯出各種單張序列圖,我這使用 TexturePacker 打包成 JSON 檔與 Sprite sheet 圖
減少 Request 數外,先透過 TexturePacker 軟體先設定好序列圖動態的感覺,
讓 PixiJS 裡直接讓 AnimatedSprite實體 使用 已調整好 的動態。

前半心得:
PIXI.AnimatedSprite 是滿特別的類別,官方 Demo 提到手動整理 texture陣列 的方法,
會有點不知道使用 第三方工具 產生的 Sprite sheet 要如何使用


解析成 PIXI.Spritesheet 時同時做了的事情:

  • 只寫了讀取 Spritesheet 的 JSON 檔,但 PixiJS 同時將 Spritesheet 的圖檔 讀入了

實驗: 將昨天 Loader 的 onLoad() 方法加在讀取 Spritesheet 的行為裡
結果: 會觸發兩個onLoad 事件,然後完成 Loader 的讀取

Network 頁籤 上也會看到讀了 .json 後,接著讀取 .png (Sprite sheet 圖)

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

loader.onLoad.add((loader, resource) => {
    console.log("onLoad: ", loader, resource)
});
loader.onComplete.add((loader, resource) => {
    console.log("onComplete: ", loader, resource)
})

loader.load((loader, resources) => {
    console.log("loader: ", loader, " resources: ", resources);
});

另一個疑惑:
讀取完成的 Resource,一個是自己命名的 bunniesJSON,用來讀 .json
另一個 bunniesJSON_image,讀的是 Spritesheet 圖片,這個 _image 是哪來的?

PIXI.SpritesheetLoader 在解析讀取的 JSON 為 Spritesheet 時,
會將如入的 Spritesheet 圖檔命名為 Resource名+_image

The Loader's image Resource name is automatically appended with _image.


讀成 Spritesheet 時產生的 TextureCache / BaseTextureCache

PIXI.utils.BaseTextureCache:會同時產生

  • 底圖
  • [素材名]_image

兩種 BaseTextureCache

PIXI.utils.TextureCache:另外加上各種拼成 Spritesheet 時各個材質的名稱

  • 底圖
  • [素材名]_image
  • bunny.png、bunny1~4.png 為大張 Spritesheet 底圖裡的某塊材質 (這部分會在之後的文章提到)

後半心得:
這部分不容易理解,因為需理解:

  • 可視物件的繼承
  • TextureCache / BaseTextureCache
  • LoaderPIXI.SpritesheetLoader

相關文章不好找,希望這篇能對 PIXI.AnimatedSprite 有更多的認識


上一篇
[Re:PixiJS - Day26] Loader(1/2) / 讀取事件與解析讀取的檔案
下一篇
[Re:PixiJS - Day28] Loader 的其他特性
系列文
再談 PixiJS,那些先前不一定有提到的部分與地雷45
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言