加入loading page
上一篇的成果在載入檔案時畫面就會停在那邊,一般的遊戲通常會有一個下載中的畫面,告知使用者現在下載了幾%,還差幾%還未下載完成。
因此今日我們就要來製作這個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畫面如下圖
更新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); } }); } }
EventEmitter介紹
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