# PixiJS - Treasure Hunter Game
###### tags: `PixiJS`
2022.08.08(Mon.)
## ▉ Helper Function > keyboard()
### ▍ keyboard() 程式碼
```javascript!
function keyboard(keyCode){
var key = {};
key.code = keyCode;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
key.downHandler = function(event){
if(event.keyCode === key.code){
if(key.isUp && key.press)key.press();
key.isDown = true;
key.isUp = false;
}
event.preventDefault();
}
key.upHandler = function(event){
if(event.keyCode === key.code){
if(key.isDown && key.release)key.release;
key.isDown = false;
key.isUp = true;
}
event.preventDefault();
}
window.addEventListener(
"keydown", key.downHandler.bind(key), false
);
window.addEventListener(
"keyup", key.upHandler.bind(key), false
);
return key;
}
```
### ▍ 分析 ▸ 物件(Object)
> 參考資料:[重新認識 JavaScript: Day 04 物件、陣列以及型別判斷](https://ithelp.ithome.com.tw/articles/10190962)
> 參考資料:[Fooish 程式技術 - JavaScript Object (物件)](https://www.fooish.com/javascript/object.html)
> 參考資料:[來數數 JavaScript 的所有資料型別](https://blog.huli.tw/2022/02/25/javascript-how-many-types/)
* **前言**
```javascript=
var key = {};
key.code = keyCode;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
key.downHandler = function(event){...}
key.upHandler = function(event){...}
```
在程式碼一開始,便出現這條程式,看到大括號就想到物件,但是對JavaScript物件不是很熟悉,所以決定來學習什麼是物件。
* **JS內建型別**
主要分成兩大類:++基本型別++、++物件型別++
(基本型別之外的值都是物件)
```
JS內建型別
├─基本型別(primitives)
│ ├─string
│ ├─number
│ ├─boolean
│ ├─null
│ ├─undefined
│ └─symbol
└─物件型別(object)
```
> 參考資料:[6.1 ECMAScript Language Types](https://tc39.es/ecma262/#sec-ecmascript-language-types)
而從規範的第六章中,可以看到規範將JS型別分成了8種(雖然是列出7點,但第6點的Numeric Types又分成Number Type以及BigInt Type)

* **物件>屬性>鍵值對**
> 參考資料:[ECMA 262](https://262.ecma-international.org/5.1/#sec-4.3.3)
```!
An object is a collection of properties and has a single prototype object.
The prototype may be the null value.
```
從上面得知,「物件」可以儲存零到多個「屬性(property)」,而一個「屬性」包含一組「鍵值對(key-value pair)」(或稱為name-value pair)。
屬性的「鍵(key)」是一個字串型態。
屬性的「值(value)」可以為任一基本型別、一個物件或是函式。
把以上文字整理成一張圖:

* **物件宣告**
> 參考資料:[Should I be using object literals or constructor functions?](https://stackoverflow.com/questions/4859800/should-i-be-using-object-literals-or-constructor-functions)
再來是建立物件的方法,基本上有兩種:++物件建構式++、++物件實字++
* **物件建構式(Object Constructor)**
new一個Object()建立物件,再給他屬性跟方法。
```javascript!
var person = new Object();
person.name = "Hello";
person.age = 20;
person.sayHi = function(){
console.log("Hi");
}
```
* **物件實字(Object Literal)**
最常用的方法,用{}大括號來建立物件。
```javascript!
var person = {
name: "Hello",
age: 20,
sayHi: function(){
console.log("Hi")
}
}
```
* **物件屬性的存取方法**
> 參考資料:[[筆記] 物件是什麼?method 是什麼?談談 JavaScript 中的物件建立(Object) - Part 1](https://pjchender.blogspot.com/2016/01/javascriptobject.html)
>
> 參考資料:[MDN:Property accessors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors)
> accessor 中文含意為存取器,所以此處property accessors指的是屬性存取
建立物件後,如果想要存取物件的屬性,基本上有兩種方法:++Dot notation++、++Bracket notation++
* **點點符號(Dot notation)**
利用點點(.)來存取物件的屬性。
```javascript!
var person = {
name: "Hello",
age: 20,
sayHi: function(){
console.log("Hi")
}
}
person.name; //"Hello"
person.age; //20
```
* **中括號符號(Bracket notation)**
利用中括號([ ])來存取物件的屬性。
```javascript!
var person = {
name: "Hello",
age: 20,
sayHi: function(){
console.log("Hi")
}
}
person["name"]; //"Hello"
person["age"]; //20
```
> 中括號[ ]裡面如果放的是字串而不是變數,要記得加上引號。
### ▍ 分析 ▸ 事件處理
> 參考資料:[[JS] 事件筆記(上)](https://medium.com/%E9%A6%AC%E6%A0%BC%E8%95%BE%E7%89%B9%E7%9A%84%E5%86%92%E9%9A%AA%E8%80%85%E6%97%A5%E8%AA%8C/js-%E4%BA%8B%E4%BB%B6%E7%AD%86%E8%A8%98-%E4%B8%8A-5377a572be51)
> 參考資料:[重新認識 JavaScript: Day 14 事件機制的原理](https://ithelp.ithome.com.tw/articles/10191970?sc=iThelpR)
> 參考資料:[重新認識 JavaScript: Day 15 隱藏在 "事件" 之中的秘密](https://ithelp.ithome.com.tw/articles/10192015)
> 參考資料:[Event Flow MDN](https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases)
> 參考資料:[3 Phases of JavaScript Event](https://javascript.plainenglish.io/3-phases-of-javascript-event-2ff09aa76b03)
* **前言**
```javascript!
window.addEventListener(
"keydown", key.downHandler.bind(key), false
);
window.addEventListener(
"keyup", key.upHandler.bind(key), false
);
```
看到addEventListener還有前面function括號中引數放了event,所以再來要學的是JS事件處理。
* **事件流程(DOM Event Flow)**
先了解在事件觸發後的事件流程是如何跑的(事件是如何被傳遞的)。
分成了3個階段(phase):++captrue phase++、++target phase++、++bubbling phase++
* **(1)captrue phase**
(inner > outer)
root of the tree ---> target node
DOM Event運作時,會從根節點觸發,一路傳遞到target節點上。
* **(2)target phase**
(會觸發2次)
到達target node的階段。
* **(3)bubbling phase**
(outer > inner)
target node ---> root of the tree
DOM Event運作時,會從target節點觸發,一路傳遞到根節點上。
* **先捕獲,後冒泡**
如下圖所示,假如我們`<td>`上的click事件被觸發:
1. <font color=red>capture phase</font>
會「先捕獲」,也就是從根節點Document出發,一路傳遞到此處的target`<td>`的過程。
```!
Document -> <html> -> <body> -> <table> -> <tbody> -> <tr> -> <td>
```
2. <font color=blue>target phase</font>
到達target`<td>`時的階段。
3. <font color=green>bubbling phase</font>
接著「後冒泡」,從target`<td>`出發,一路傳遞到跟節點Document的過程。
```!
<td> -> <tr> -> <tbody> -> <table> -> <body> -> <html> -> Document
```

(圖片來源:[w3.org](https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases))
* **事件綁定(Event Handler)**
> 參考資料:[MDN Event handling (overview)](https://developer.mozilla.org/en-US/docs/Web/Events/Event_handlers)
> 參考資料:[JavaScript DOM Event (事件處理)](https://www.fooish.com/javascript/dom/event.html)
> 參考資料:[3種事件綁定方式](https://medium.com/%E9%A6%AC%E6%A0%BC%E8%95%BE%E7%89%B9%E7%9A%84%E5%86%92%E9%9A%AA%E8%80%85%E6%97%A5%E8%AA%8C/js-%E4%BA%8B%E4%BB%B6%E7%AD%86%E8%A8%98-%E4%B8%8A-5377a572be51)
大致分成3種方式:++Html inline atribute++、++DOM object property++、++addEventListener++
這裡主要提addEventListener,他一共有3個參數:
1. 事件名稱
可參考[HTML DOM Events](https://www.w3schools.com/jsref/dom_obj_event.asp),有很多event可以使用。
2. 事件處理
第一個參數事件觸發時執行的function。
3. Boolean值
決定是捕獲還是冒泡機制(預設為冒泡)
捕獲:從最外面(根元素),往內(指定元素)找
冒泡:從最裡面(指定元素),往外(根元素)找
### ▍ 分析 ▸ bind()
* **前言**
```javascript!
window.addEventListener(
"keydown", key.downHandler.bind(key), false
);
```
從前面可以知道上面的程式碼,會在"keydown"事件發生時觸發第二個參數的函式,該函式key.downHandler是key物件中的函式之一(如下),但是什麼是bind()?
```javascript!
key.downHandler = function(event){
if(event.keyCode === key.code){
if(key.isUp && key.press)key.press();
key.isDown = true;
key.isUp = false;
}
event.preventDefault();
}
```
* **強制指定this的方式**
說到bind(),就一定要再提到另外兩個call()跟apply()。