補充幾個 Loader 的特性:
[ Demo-1 ]
const loader = PIXI.Loader.shared;
loader.add('bunny', 'assets/basics/bunny.png');
loader.load((loader, resources) => {
// console.log("loader: ", loader, " resources: ", resources);
console.log('complete');
});
// 在讀取完成前再使用 .add() 一次
loader.add('bunny', 'assets/basics/bunny.png');
[ Demo-2 ]
const loader = PIXI.Loader.shared;
loader.add('bunny', 'assets/basics/bunny.png');
// 圖取不同圖片,可是素材名都命名為 'bunny'
loader.add('bunny', 'assets/basics/bunny2.png');
loader.load((loader, resources) => {
console.log('complete');
});
PixiJS 使用 Loader 時,可不指定讀入的 素材名稱。
此時會以讀入的素材 url 命名
例如:
const loader = PIXI.Loader.shared;
loader.add('assets/basics/bunny.png');
loader.load();
結果為:
[ Demo-3 ]
const loader = PIXI.Loader.shared;
loader.add('bunny', 'assets/basics/bunny.png');
// 更改了素材名,但 url 相同
loader.add('bunny2', 'assets/basics/bunny.png');
loader.load((loader, resources) => {
console.log('complete');
});
前半小結:
Loader 的 Resource 快取與 textureCache / baseTextureCache 某方面來說有點像,
但是是不同的東西
[ Demo-4 ]
使用 PIXI.Sprite.from() 時,會自動檢查是否有快取
如果已有快取,便不會再送 Request
TextureCache / BaseTextureCache 不會增加
不會再送 Request
function createBunny(){
const bunny = PIXI.Sprite.from('assets/basics/bunny.png');
bunny.anchor.set(0.5);
return bunny;
};
setInterval(() => {
const bunny = createBunny();
bunny.x = Math.random() * app.screen.width;
bunny.y = Math.random() * app.screen.height;
app.stage.addChild(bunny);
}, 1000);
同理可先使用 Loader 將兔子圖片讀入,確保隨後使用 PIXI.Sprite.from() 時,
不會因為沒有快取
而產生讀取時間
[ Demo-5 ]
const loader = PIXI.Loader.shared;
loader.add('assets/basics/bunny.png');
loader.load((loader, resources) => {
console.log('complete');
startApp();
});
function startApp(){
setInterval(() => {
const bunny = createBunny();
bunny.x = Math.random() * app.screen.width;
bunny.y = Math.random() * app.screen.height;
app.stage.addChild(bunny);
}, 1000);
};
PIXI.Sprite.from() 是 讀取 與 處理快取 相當方便的方法
但是 PIXI.AnimatedSprite 沒有這麼方便的方法可 同時處理讀取與快取
昨天的文章裡提到 PIXI.AnimatedSprite 裡帶入素材陣列的兩種方式:
1- 手動帶入素材陣列
2- 使用已整理成 PIXI.Spritesheet 物件裡的 animation
兩種方式皆為 已確定讀入素材快取 的前提下發生的
也就是說,沒有 PIXI.AnimatedSprite 的 from( filename.json
) 的方式
可以同時處理讀取 JSON、讀取各個 Texture / BaseTexrue 與處理快取的方法
PIXI.AnimatedSprite.fromFrames() 與 PIXI.AnimatedSprite.fromImages() 都是在 已有快取 或 已知素材名的前提下使用,與 先讀.json 後再 讀取圖片 的方式不同
[ Demo-6 ] - 產生一個 loop 播放的兔子
function createAnimatedBunny() {
loader.add('bunniesSpritesheet', 'bunnies.json');
loader.load((loader, resources) => {
const bunnySpritesheet = resources.bunniesSpritesheet.spritesheet;
const animateBunny = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny);
// 省略一些 bunnySpritesheet 的設定
app.stage.addChild(animateBunny);
});
};
createAnimatedBunny();
因為 loader.add('bunniesSpritesheet'
, 'bunnies.json'); 的 bunniesSpritesheet 重複了
function createAnimatedBunny() {
loader.add(`bunniesSpritesheet`, 'bunnies.json');
loader.load((loader, resources) => {
const bunnySpritesheet = resources.bunniesSpritesheet.spritesheet;
const animateBunny = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny);
// 省略一些 bunnySpritesheet 的設定
app.stage.addChild(animateBunny);
});
};
createAnimatedBunny();
改一下 Resource Name,讓呼叫 createAnimatedBunny() 時不會因為素材名稱相同出錯:
function createAnimatedBunny() {
// 動態改素材名
const spritesheetName = `Spritesheet${Math.random()* 1000}`;
loader.add(spritesheetName, 'bunnies.json');
loader.load((loader, resources) => {
const bunnySpritesheet = resources[spritesheetName].spritesheet;
const animateBunny = new PIXI.AnimatedSprite(bunnySpritesheet.animations.bunny);
app.stage.addChild(animateBunny);
});
};
雖然可以重複呼叫 createAnimatedBunny(),可是接著有兩個問題:
1- TextureCache / BaseTextureCache 重複
2- Resource 沒快取了
發生原因: Texture / BaseTexture 的原始檔都有檢查是否有重複的 cacheId,
重複時會出現 console.warn();
由於一組 Spritesheet 通常 不會只有一兩張 Texture,
因此因為讀取 Spritesheet 的 .JSON 檔時出現的 console.warn(); 通常都是一整片
,
可能還需要將 console.warn(); 過濾掉,很不方便。
在 console頁籤 點選下拉選單,可以將 console.warn(); 關掉
還有一種做法是每次要 呼叫 Loader 時,就把所有快取清掉
Loader.reset():
Loader.reset() 方法實作在 Loader 的父類別 resource-loader:
使用結果: 清除 resources 快取
PIXI.utils.clearTextureCache():
使用結果: 清除
TextureCache / BaseTextureCache
PIXI.utils.destroyTextureCache():
使用結果: 摧毀
TextureCache / BaseTextureCache
從結果來看,TextureCache / BaseTextureCache 的結果是相同的,
差別在:正在使用 Texture / BaseTexture 的元件會 出現錯誤
使用 clearTextureCache() 後,原本的兔子還在,但 TextureCache / BaseTextureCache 清除了
使用 destroyTextureCache() 後,由於使用中的材質被摧毀了,出現錯誤
使用清除快取的方式處理序列圖重複的方法,
顯然不是正確的處理方式,就不接著討論了
相關討論: