---
# System prepended metadata

title: PixiJS - Treasure Hunter Game
tags: [PixiJS]

---

# 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）
    
    ![](https://i.imgur.com/8r3P6fJ.png)

    
* **物件>屬性>鍵值對**
    > 參考資料：[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）」可以為任一基本型別、一個物件或是函式。
    
    把以上文字整理成一張圖：
    
    ![](https://i.imgur.com/bigjYvp.png)

* **物件宣告**
    > 參考資料：[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
            ```

        ![](https://i.imgur.com/ewDS82H.png)
        （圖片來源：[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)

    大致分成３種方式：++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()。
