上一篇的成果在載入檔案時畫面就會停在那邊,一般的遊戲通常會有一個下載中的畫面,告知使用者現在下載了幾%,還差幾%還未下載完成。
因此今日我們就要來製作這個loading page
首先,在index.html
裡加上一個div
<div id="gameContainer">
<canvas id="gameCanvas"></canvas>
<div id="loadingPage">Loading...</div>
</div>
並在style.css裡設定
#gameCanvas{
position:absolute;
}
#loadingPage{
min-width: 100%;
min-height: 100%;
position:absolute;
left:0px;
top: 0px;
z-index:1;
background-color: #000000;
color: #fff;
text-align: center;
vertical-align: middle;
line-height: 100vh;
}
#loadingPercent{
position:absolute;
min-width: 100%;
min-height: 100%;
top:calc(50%);
}
這樣我們就會有一個很簡單的loading畫面如下圖
直接用jquery去操控剛剛所設定的div裡面的文字顯示,來更新現在的下載進度:
this.loader.onProgress.add((e) => {
jQuery("#loadingPage").html("Loading..." + Math.floor(e.progress) + "%");
});
整個Loader.ts修改後的程式碼如下:
import { ResourcesList } from "./ResourcesList";
import {eventEmitter} from "../Main";
import {CoreEvent} from "./Event";
import math = PIXI.core.math;
export class Loader{
private static loader:PIXI.loaders.Loader;
private static failedFiles:Array<string> = [];
private static completedFiles:Array<string> = [];
public static resources:PIXI.loaders.Resource;
public static load(){
this.loader = new PIXI.loaders.Loader();
ResourcesList.img.forEach(element => {
this.loader.add(element.id, element.path);
});
this.loader.load((loader, resources) => {
this.resources = resources;
});
//可取得下載進度
this.loader.onProgress.add((e) => {
jQuery("#loadingPage").html("Loading..." + Math.floor(e.progress) + "%");
});
//載入檔案錯誤時
this.loader.onError.add((t, e, r) => {
this.failedFiles.push(r.name);//載入失敗的檔案列表
});
//每個檔案載入時都會呼叫
this.loader.onLoad.add((e, t) => {
this.completedFiles.push(t.name);//載入成功的檔案列表
});
//全部下載完成後
this.loader.onComplete.add(() => {
if (this.failedFiles.length == 0){
//全部的檔案都下載成功
} else{
jQuery("#loadingPage").html("Loading...failed: could not load "+ this.failedFiles);
}
});
}
}
PIXI.utils.EventEmitter使用EventEmitter3,在pixiJSv4之後已直接被整理到pixi裡了。
這個套件可以讓我們在js裡很方便的使用事件,在動畫處理上,事件的監聽與發送可以讓我們在處理動畫上更加輕鬆,也可以降低這些元件間的相依性。
下面是EventEmitter3上的一個簡單使用範例
var EE = new EventEmitter()
, context = { foo: 'bar' };
function emitted() {
console.log(this === context); // true
}
EE.once('event-name', emitted, context);//context為傳入函數的參數
EE.on('another-event', emitted, context);
EE.removeListener('another-event', emitted, context);
如果我們希望整個遊戲共用一個EventEmitter,可以將產生的EventEmitter
做export:
export let eventEmitter:EventEmitter;
要使用這個物件可以直接import進來
import {eventEmitter} from "../Main";
在Loader.ts
加入下面的程式碼:
//全部下載完成後
this.loader.onComplete.add(() => {
if (this.failedFiles.length == 0){
eventEmitter.emit(CoreEvent.AssetsLoadComplete);
} else{
jQuery("#loadingPage").html("Loading...failed: could not load "+ this.failedFiles);
}
});
接著在Main.ts
裡設定下載完後要做的事情:
//設定共用的事件傳遞元件
eventEmitter = new EventEmitter();
eventEmitter.on(CoreEvent.AssetsLoadComplete,()=>{
//隱藏loading page
jQuery("#loadingPage").hide();
//加入背景
var background = PIXI.Sprite.from(Loader.resources["background"].texture);
application.stage.addChild(background);
});
上面需要注意,因為我們在Loader.loader.load()裡將下載後的resource存在一個變數裡,所以我們可以直接使用
Loader.resources\["background"\].texture
來取得某一個resource id下的texture。
線上展示:http://claire-chang.com/ironman2018/1031/
成果檔案下載:ironman20181031