iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Modern Web

PixiJS青銅玩家系列 第 23

【LV. 23】PixiJS青銅玩家:helper function - keyboard()(1)

  • 分享至 

  • xImage
  •  

▉ 前言

這裡將利用教程所提供的"Treasure Hunter Game"來直接學習PixiJS中的語法。"Treasure Hunter Game"的程式碼 ---> Click Here !

系統提示:「True mastery of any skill takes a lifetime.」,PixiJS青銅玩家還卡關於自定義function階段,僅獲得經驗提昇等級。

▉ 主線任務:helper function - keyboard( )

▍任務說明

keyboard()這個函數是用來監聽與捕捉鍵盤事件,他在此遊戲的用途主要為角色explorer的移動控制「上、下、左、右」。

▍作法

function keyboard(keyCode) {
  var key = {};
  key.code = keyCode;
  key.isDown = false;
  key.isUp = true;
  key.press = undefined;
  key.release = undefined;
  //The `downHandler`
  key.downHandler = function(event) {
    if (event.keyCode === key.code) {
      if (key.isUp && key.press) key.press();
      key.isDown = true;
      key.isUp = false;
    }
    event.preventDefault();
  };

  //The `upHandler`
  key.upHandler = function(event) {
    if (event.keyCode === key.code) {
      if (key.isDown && key.release) key.release();
      key.isDown = false;
      key.isUp = true;
    }
    event.preventDefault();
  };

  //Attach event listeners
  window.addEventListener(
    "keydown", key.downHandler.bind(key), false
  );
  window.addEventListener(
    "keyup", key.upHandler.bind(key), false
  );
  return key;
}

▍分析

這個function老實說研究了相當久,還是沒說到非常清楚整個運作,因為光是掃過去,就看見了許多JavaSscript的大觀念,例如:物件、事件處理、bind(),而bind()又可以提到call()apply(),又可以延伸到this的概念,然後this又可以牽扯到物件導向(跟第一個提到的物件又可以接上),整個就是一大坨大觀念連結在一起,所以有點不知所措。

後來決定把這個function分成兩到三天寫,從「大方向:這個function做了哪些事情」--->「觀念:這個function裡所藏的觀念」寫起。

***

好的,所以先來從「大方向:這個function做了哪些事情」開始。

如何使用
首先,最基本的這個函式該怎麼使用?使用方式其實非常簡單,如下方所示就能創建出一個新的keyboard物件:

let keyObj = keyboard(asciiKeyCodeNumber);

此物件只能接受一個參數,且這個參數必須為ASCII值,這在【LV. 15】就曾經提過,可以回到當時回顧一下,這邊就先放上這個遊戲會使用到的ASCII值:

接著便能使用對keyboard這個物件給賦值pressrelease兩種方法:

keyObject.press = () => {
  //key object pressed
};
keyObject.release = () => {
  //key object released
};

知道如何使用後,就可以來看看Treasure Hunter Game遊戲中是怎麼運用他的,一樣出現在【LV. 15】過,先抓到「上、下、左、右」鍵所對應到的ASCII值:

let left = keyboard(37),
    up = keyboard(38),
    right = keyboard(39),
    down = keyboard(40);

接著對keyboard這個物件給賦值pressrelease兩種方法,當按下按鍵或放開按鍵時會執行什麼動作:

left.press = function() {
    explorer.vx = -5;
    explorer.vy = 0;
};
left.release = function() {
    if (!right.isDown && explorer.vy === 0) {
      explorer.vx = 0;
    }
};

up.press = function() {
    explorer.vy = -5;
    explorer.vx = 0;
};
up.release = function() {
    if (!down.isDown && explorer.vx === 0) {
      explorer.vy = 0;
    }
};

right.press = function() {
    explorer.vx = 5;
    explorer.vy = 0;
};
right.release = function() {
    if (!left.isDown && explorer.vy === 0) {
      explorer.vx = 0;
    }
};

down.press = function() {
    explorer.vy = 5;
    explorer.vx = 0;
};
down.release = function() {
    if (!up.isDown && explorer.vx === 0) {
      explorer.vy = 0;
    }
};

如何運作
知道怎麼使用之後,再來往內部觀察,看看他做了哪些事情。

首先,看到最後一行:

return key;

可以知道keyboard這個function在最後會回傳一個名為「key」的物件,而key物件中有許多的屬性都是我們自定義的,例如「code、isDown、isUp、press、release、downHandler、upHandler」。

那這邊利用了devtool來看看這個物件在幹麻,我先創建一個keyboard物件,參數帶入ASCII值37(對應到方向鍵-左鍵),並將此物件命名為left

再來就來看看left物件帶有的屬性:

但其實好像看了也沒什麼想法,先有個概念就好。

然後因為我目前對JS的很多觀念都不熟悉,所以以下想法是「猜測的」!

先看看keyboard function中以下程式碼:

window.addEventListener(
    "keydown", key.downHandler.bind(key), false
);
window.addEventListener(
    "keyup", key.upHandler.bind(key), false
);

他用了addEventListener去監聽keydownkeyup事件,然後當keydownkeyup事件被觸發時,就會執行第二個參數key.downHandler.bind(key)key.upHandler.bind(key)

key.downHandlerkey.upHandler是key物件裡的屬性,程式碼如下:

key.downHandler = function(event) {
    if (event.keyCode === key.code) {
      if (key.isUp && key.press) key.press();
      key.isDown = true;
      key.isUp = false;
    }
    event.preventDefault();
};

//The `upHandler`
key.upHandler = function(event) {
    if (event.keyCode === key.code) {
      if (key.isDown && key.release) key.release();
      key.isDown = false;
      key.isUp = true;
    }
    event.preventDefault();
};

屬性擁有一組鍵值對(key-value pair),在這裡的鍵為downHandlerupHandler,而這裡的值為一個函式(值可以為任一基本型別、一個物件或是函式,明天會寫更詳細)。

這兩個函式所需的參數event,目前猜測是依靠addEventListener監聽得到的事件目標(按了哪個按鍵),然後利用bind()把這個觸發事件的按鍵指向給downHandlerupHandler這兩個的參數event?

然後他會去確認這個觸發事件的按鍵(也就是event)的keyCodekeyCode是JS的函式),是否符合我們創建新keyboard物件所回傳的key.code是一樣的,如果是則執行裡頭程式:

if (event.keyCode === key.code){
    ...
}

所以大略總結一下,以按下按鍵為例:
先透過addEventListener監聽,當keydown事件被觸發,則執行key.downHandler.bind(key),接著就來到以下程式碼去做if條件句判斷:

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.press(),也就是執行我們前面寫下的press方法,以left物件來說就是以下程式碼:

left.press = function() {
    explorer.vx = -5;
    explorer.vy = 0;
};

大致上的運作想法是這樣,但是對於JS概念實在不是很熟悉,所以基本上都是先大膽猜測(?),如有錯誤歡迎指教!


▉ 結語

這篇要怎麼寫一直沒有想法,所以變成這23天來最晚交出去的一篇,果然到越後面越難產(;´༎ຶД༎ຶ`),這邊keyboard function寫完後估計會更難吧(要開始寫點官方文件以外的內容了),總之今天先這樣,明天應該會惡補一些JavaScript的概念,然後整理成筆記寫出來!


參考資料


上一篇
【LV. 22】PixiJS青銅玩家:helper function - randomInt()
下一篇
【LV. 24】PixiJS青銅玩家:helper function - keyboard()(2)物件
系列文
PixiJS青銅玩家30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言