# Phaser.js 介紹
###### tags: `技術文件`
撰寫於 2019/08
1. HTML5 遊戲框架
2.使用canvas技術,瀏覽器需支援canvas

3.官方文件完整
4.官方範例多
5.目前最新穩定版本為 v3.19.0,在2019/08/08釋出
- 官方網站
http://phaser.io/
- 中文參考網站
http://yltang.net/tutorial/phaser/1/
- Canvas教學文件
https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API/Tutorial
- v3.19.0 API Documentation
https://photonstorm.github.io/phaser3-docs/index.html
- v2.6.2 API Documentation
http://phaser.io/docs/2.6.2/index
# Phaser.js 執行順序
- preload: 預先載入資源,如圖片等
- create: 載入資源之後,設定遊戲物件和產生遊戲畫面等
- update: 會重複執行,在此進行遊戲的邏輯設定,遊戲的判定,每秒重複執行約60次

# Phaser.js 使用
因為在這個專案使用的是 v2.6.2,
看的都是v2.6.2前的文件,
所以以下說明都是在 v2.6.2 前的使用方法,
尚未確定在最新版有什麼使用上的不同。
* 以下介紹一下在專案裡的解說畫面有用到的 Phaser.js簡單功能
* [遊戲網址](https://udn.com/upf/ubrand/2019_data/TCEDU_Speedup/)
### 第一步(HTML撰寫)
- 設定一個div,作為遊戲載入的視窗,phaser.js會在其中生成canvas
- phaser.js需在自行編寫的main.js之前載入
```
<div id="gameDiv"></div>
<script src="js/phaser.min.js"></script>
<script src="js/main.js"></script>
```
### 第二步(生成遊戲物件)
- 宣告全域變數 game 為一個 Phaser.Game 物件
- 這時可以看到一個寬375、高544的黑色畫面
- 裡面可帶入的參數
http://phaser.io/docs/2.6.2/Phaser.Game.html
new Game(width, height, renderer, parent, state, transparent, antialias, physicsConfig)
```
var game = new Phaser.Game(375, 544, Phaser.AUTO, 'gameDiv');
```
### 第三步(狀態管理)
- 為了方便維護,將遊戲狀態分開管理
- 在 html的 main.js前面載入 start.js
```
<div id="gameDiv"></div>
<script src="js/phaser.min.js"></script>
<script src="js/start.js"></script>
<script src="js/main.js"></script>
```
- 在 start.js裡面,宣告全域變數 startState為一個物件
```
var startState = {
preload: function() {
},
create: function() {
},
update: function() {
},
};
```
- 在 main.js裡面,將 startState加入game中,命名為 startState
- 並開始執行 startState
```
var game = new Phaser.Game(375, 544, Phaser.AUTO, 'gameDiv');
game.state.add("startState", startState);
game.state.start('startState');
```
### 第四步(生成圖片)
- 在 prload載入資源 startBg.png,並命名為 startBg
- 這只是載入資源,畫面還是黑的
- load裡面的方法 image(key, url, overwrite) → {Phaser.Loader}
```
preload: function() {
game.load.image("startBg","images/startBg.png");
},
```
- 在 create生成畫面
- 在 reload載入的資源,可以在 create和 update使用
- add是一個GameObjectFactory,可用來快速生成多個物件
- 這是生成image物件的方法 image(x, y, key, frame, group) → {Phaser.Image}
- 遊戲座標(x, y): 左上角為 (0, 0)

```
create: function() {
game.add.image(0, 0, "startBg");
},
```
### 第五步(生成動畫)
- 生成影格 spritesheet(key, url, frameWidth, frameHeight, frameMax, margin, spacing) → {Phaser.Loader}
- 生成動畫 animations.add(name, frames(e.g. [1, 2, 3] or ['run0', 'run1', run2]), frameRate(per second) , loop(false), useNumericIndex(true))
```
preload: function() {
game.load.image("startBg","images/startBg.png");
game.load.spritesheet('animationAct','images/animation.png', 270, 570);
},
create: function() {
game.add.image(0, 0, "startBg");
var animationAct = this.game.add.sprite(110 , 100, 'animationAct')
animationAct.scale.setTo(0.6, 0.6) //縮小
animationAct.animations.add('move', [0,1,2,3,4,5,6,7,8,9,10,11], 10, true)
animationAct.animations.play('move');
},
```
### 第六步(plugin)
為了方便維護,將一些額外的設定拉出來,並在遊戲裡面生成物件,使全域能使用
* main.js
```
var game = new Phaser.Game(375, 544, Phaser.AUTO, 'gameDiv');
game.global = Object.assign(pluginObj);
game.state.add("startState", startState);
game.state.start('startState');
```
讓畫面自動生成文字
* start.js
```
.
.
.
update: function() {
},
joinWords: function() {
var dailogueX = 20;
var dailogueY = game.world.centerY * 1.3;
var words = [
[
"學 習 王 , 你 來 啦 !",
"準 備 好 接 下 新 的 任 務 了 嗎 ?",
"我 的 時 間 不 多 , 你 仔 細 聽 好"
],
[
"為 了 讓 台 中 市 的 校 園 學 習 環 境 更 好",
"這 次 你 必 須 要 用 最 快 的 速 度",
"拿 到 重 要 的 全 民 學 習 之 鑰"
],
[
"過 程 中 你 可 能 會 遭 遇 無 情 攻 擊",
"希 望 你 能 順 利 過 關"
]
];
var dialogue = {};
dialogue.content = words;
this.game.global.typewriter(dailogueX + 65, dailogueY + 40, dialogue, this);
}
};
```
* 設定計時器,1秒後生成文字
* add(delay, callback, callbackContext, arguments) → {Phaser.TimerEvent}
```
create: function() {
game.add.image(0, 0, "startBg");
var animationAct = this.game.add.sprite(110 , 100, 'animationAct');
animationAct.scale.setTo(0.6, 0.6);
animationAct.animations.add('move', [0,1,2,3,4,5,6,7,8,9,10,11], 10, true);
animationAct.animations.play('move');
this.game.time.events.add(1000, this.joinWords, this);
},
```