# 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) 大致分成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()。