recursal/MDN huggingface dataset:
快捷選單項
=====

這個用戶介面添加一個或多個項目到瀏覽器的快捷選單。這是用戶在網頁上點擊右鍵時出現的選單。頁籤也可以透過 browser.menus API 使用快捷選單。

![Example of content menu items added by a WebExtension, from the context-menu-demo example](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items/context_menu_example.png)

你可以用這個介面來顯示一些跟特定瀏覽器或網頁內容相關的功能。舉例來說，當用戶在圖片上按右鍵時提供圖片編輯器的功能或者在反白內容上按右鍵時提供儲存頁面內容的功能。你可以對選單添加普通的選單項目、核取方塊、單選按鈕組以及分隔線。選單項目透過`contextMenus.create` (en-US)添加後透過它會顯示在所有瀏覽器頁籤，但是你可以透過`contextMenus.remove` (en-US)來移除它。

指定快捷選單項目
--------

透過`contextMenus` (en-US) API 可以程式化地管理快捷選單項目。然而，你必須請求 `contextMenus` 的權限才能使用這些 API 的好處。


```json
"permissions": ["contextMenus"]
```


現在你可以在你套件的後端腳本處添加（修改／刪除）選單項目。建立一個選單項目你要指定 id，標題以及它應該隸屬於哪個選單：


```js
browser.contextMenus.create(
  {
    id: "log-selection",
    title: browser.i18n.getMessage("contextMenuItemSelectionLogger"),
    contexts: ["selection"],
  },
  onCreated,
);
```


接著你的套件會監聽選單項目的點擊。送出有關項目點擊、點擊環境以及發生點擊頁籤的資訊可以用來使用恰當的套件功能。


```js
browser.contextMenus.onClicked.addListener(function(info, tab) {
  switch (info.menuItemId) {
    case "log-selection":
      console.log(info.selectionText);
      break;
    ...
  }
})
```

圖示
--

更多關於建立快捷選單圖示的細節請查看文件光子設計系統的圖示學。

範例
--

GitHub 上的webextensions-examples 程式庫包含了兩個建立快捷選單的範例：

* menu-demo 替瀏覽器的快捷選單添加幾個項目。
* context-menu-copy-link-with-types 替連結添加一個快捷選單項，以純文字或 rich HTML 的形式複製連結的 UR。
工具列按鈕
=====

 根據工具列按鈕 (en-US)，這個用戶介面是一個加到瀏覽器工具列的按鈕。用戶透過點擊按鈕來與你的套件互動。

 ![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Toolbar_button/browser-action.png)

工具列按鈕與網址列按鈕非常相似。關於差別以及何時該使用的指引，詳閱工具列按鈕。

詳細指定工具列按鈕
---------

透過在 manifest.json 中使用 `browser_action` (en-US) 鍵來定義工具列按鈕的屬性：


```json
"browser\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "我在哪？"
}
```


唯一一個強制的鍵只有 `default_icon`。

指定工具列按鈕的方式有兩種： 有彈出視窗跟沒有彈出視窗。如果你不指定彈出視窗，當用戶點擊按鈕事件會被傳送到套件，而套件透過 `browserAction.onClicked` (en-US) 監聽：


```js
browser.browserAction.onClicked.addListener(handleClick);
```


如果你指定彈出視窗，點擊事件不會被傳送，取而代之當用戶點擊按鈕時彈出視窗會被展開。用戶可以跟彈出視窗互動且當用戶點擊了彈出視窗外側它會自動關閉。更多建立與管理彈出視窗的細節請查看彈出視窗文章。

註： 你的套件只能有一個工具列按鈕。

你可以透過 `browserAction` (en-US) API 程式化地更改任何工具列按鈕的屬性。

圖示
--

更多關於建立工具列按鈕使用的圖示，請查看文件光子設計系統裡的圖示學。

範例
--

GitHub 上的擴充套件範例程式庫包含兩個建立工具列按鈕的範例：

* bookmark-it 使用不含彈出視窗的工具列按鈕。
* beastify 使用包含彈出視窗的工具列按鈕。
作者
==

|  |  |
| --- | --- |
| 型別 | `String` |
| 強制 | No |
| 範例 | 
```json
"author": "cool puppy"
```
 |

套件作者，用來顯示在瀏覽器的用戶介面中。如果有提供 developer 鍵而且裡面包含 "name" 屬性，那會覆蓋 author 鍵。不能指定多個作者。

這是一個可侷限的屬性。

範例
--


```json
"author": "cool puppy"
```

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
applications
============

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | 通常是不強制（請看你什麼時候會需要 Add-on ID？）。在 Firefox 48（桌面）前以及Android版Firefox 是強制的。 |
| 範例 | 
```json
"applications": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0"
  }
}
```
 |

敘述
--

`applications` 鍵包含了詳細描述特定應用的鍵。

目前這只包含了一個鍵，`gecko`，它包含 4 個 string 參數：

* `id` 是套件 ID。Firefox 48 以後爲選擇性，48 前爲強制。需要什麼來指定 add-on ID 請查看套件與 Add-on ID。
* `strict_min_version`：支持的最舊 Gecko 版本。在這個欄位版本號包含 "\*" 是不合法的。預設是 "42a1"。
* `strict_max_version`： 支持的最新 Gecko 版本。如果套件安裝的 Firefox 版本超過這個版本號則套件會被禁用或不被允許安裝。預設爲 "\*"，表示禁用最新支持版本檢查。
* `update_url` 是套件更新 manifest。備：連結必須以 "https" 開頭。這個鍵用來自己管理套件更新（不透過套件管理器）。

查看可用 Gecko 版本。

### 套件 ID 格式

套件 ID 格式必須是下列其中一種：

* GUID
* 寫得像信箱地址的字串：`extensionname@example.org`

後者比較容易產生與操作。小心，在這裡使用真實信箱地址可能會引來垃圾信件。

例如：


```json
"id": "extensionname@example.org",

"id": "{daf44bf7-a45e-4450-979c-91cf07434c3d}"
```

範例
--

包含所有可用鍵的範例。註：大多數套件會忽略 `strict_max_version` 和 `update_url`。


```json
"applications": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0",
    "strict\_max\_version": "50.\*",
    "update\_url": "https://example.com/updates.json"
  }
}
```

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
options\_ui
===========

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | No |
| 範例 | 
```json
"options\_ui": {
  "page": "options/options.html"
}
```
 |

用 `options_ui` 鍵來定義套件的選項頁面 (en-US)。

選項頁面包含了套件的設定。用戶可以從套件管理員進入這個畫面，而你可以用`runtime.openOptionsPage()` (en-US)打開它。

指定 `options_ui` 爲一個與套件打包在一起的 HTML 檔案路徑。就像一般的網頁一樣，HTML 檔案可包含 CSS 與 JavaScript 檔案。跟普通頁面不同的是，它可以使用所有被授權 (en-US)的套件 APIs。 不過，它執行的作用域不同於你的後端腳本。

 如果你想在**選項頁面**與**後端腳本**的 JavaScript 裡**共用**資料或函數，你可以透過用`extension.getBackgroundPage()` (en-US)與後端腳本的 Window (en-US) 關聯、用`extension.getViews()` (en-US)與任何套件內腳本的`Window` (en-US)關聯來實現。你也可以透過 `runtime.sendMessage()` (en-US)、 `runtime.onMessage` (en-US)，跟（或）`runtime.connect()` (en-US)在選項頁面與後端的頁面的 JavaScript 之間溝通。
 後者（或是`runtime.Port` (en-US)）也可以用來在後端腳本與\*\*內容腳本\*\*之間共用選項。

一般要儲存選項頁面的選項變動時，你要可能會用 storage API、storage.sync (en-US)（如果你想要在所有用戶登入的瀏覽器實例之間同步設定的話），或者透過 storage.local （如果設定是針對目前身份或機器）。而如果你希望你的後端腳本（或內容腳本）監聽該變化，你可以加上 storage.onChanged (en-US) 監聽器。

語法
--

`options_ui` 鍵是一個包含了下列內容的物件：

| Name | Type | Description |
| --- | --- | --- |
| `browser\_style (en-US)` | `Boolean` | 可選，預設爲 `true`。

 用這個來替你的頁面引入一個樣式表，使你的頁面與瀏覽器UI以及其他用
 `browser_style`
 的套件看起來一致。雖然它預設是`true`還是建議你加入這個屬性。


 在 Firefox 裡，樣式表可以在 chrome://browser/content/extension.css 或
 chrome://browser/content/extension-mac.css（OS
 X）查看。設定尺寸的時候注意到這個樣式表目前會做這個設定`box-sizing: border-box`
 （查看 box-sizing）。

Firefox風格指南寫到一些你可以應用到彈出視窗裡面的元素上來變成特定樣式的class。 |
| `open_in_tab` | `Boolean` | 可選，預設爲 `false`。

 如果設爲
 `true`，選項頁面會在普通的瀏覽器頁籤開啓而不是整合在瀏覽器的套件管理員裡。
  |
| `page` | `String` | 強制。
包含選項頁面細項的HTML檔案路徑。
這個路徑是 manifest.json 的相對路徑。 |

範例
--


```json
"options\_ui": {
    "page": "options/options.html"
  }
```

瀏覽器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Browser styles (en-US)
homepage\_url
=============

|  |  |
| --- | --- |
| 型別 | `String` |
| 強制 | No |
| 範例 | 
```json
"homepage\_url": "https://example.org/my-addon"
```
 |

套件首頁的 URL。

如果有 developer 鍵且它包含 "url" 屬性，這會覆蓋 homepage\_url 鍵。

這是一個可侷限的屬性。

範例
--


```json
"homepage\_url": "https://github.com/mdn/webextensions-examples/tree/main/beastify"
```

瀏覽器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
background
==========

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | No |
| 範例 | 
```json
"background": {
  "scripts": ["background.js"]
}
```
 |

用 `background` 鍵來引入一個或多個後端腳本，還有一個選擇性的套件後端頁面。

後端腳本是用來放置一些需要維護長期狀態或是進行長期操作的程式碼，它麼的生命週期跟任何網頁或瀏覽器視窗是獨立的。

後端腳本會在套件一被讀取就被讀入，一直到套件被禁用或移除才會卸載。只要你有請求對應的權限 (en-US)你可以在這個腳本裡使用任何擴充套件 APIs。

更多細節，查看套件解析的"後端頁面"章節。

`background` 鍵是一個物件，可能包含下列二屬性其中之一，兩者都是選擇性的：

|  |  |
| --- | --- |
| `"scripts"` | 
 一個字串組成的陣列，每個都是 JavaScript 原始碼的路徑。路徑是
 manifest.json 檔案自身的相對路徑。這些是會被套件讀取的後端腳本。

腳本共用全局 `window`。
腳本根據陣列裡的順序讀入。

**註：**Firefox 版本50以前有一個錯誤當 Firefox
 除錯器開啓時，腳本並不總是按照陣列裡的順序讀入。要解決這個錯誤，你可以用
 `"page"` 屬性並且在頁面中透過
 `<script>` 標籤讀入後端腳本。這個錯誤在 Firefox 50
 被修正，從那開始腳本總是會依照陣列中的順序讀入。


**備註：**
 如果你想要用`<script>標籤`從遠端取得一個腳本（例如
 `<script src =
"https://code.jquery.com/jquery-1.7.1.min.js">`），你必須要修改套件 manifest.json 中的
 `content_security_policy` 鍵。

 |
| `"page"` | 
 如果你指定
 `"scripts"`，那麼爲了讓你的腳本執行一個空白頁面會被建立。


 如果頁面中需要某些內容，你可以用
 `"page"` 選項定義自己的頁面。


 如果你用了這個屬性，你就不能透過
 `"scripts"`
 來指定後端腳本。但是你可以像一般的網頁一樣在頁面中引入你自己的腳本。
  |

範例
--


```json
"background": {
    "scripts": ["jquery.js", "my-background.js"]
  }
```


讀取兩個後端腳本。


```json
"background": {
    "page": "my-background.html"
  }
```


讀取一個自訂的後端頁面。

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
Web 遊戲開發介紹
==========

現有 Web 環境已成為多元的平台，不只可建構令人驚艷的高品質遊戲，也是發佈這些遊戲的重要媒介。可供撰寫的遊種類......
現有的 Web 技術再搭配最新版瀏覽器，就能打造出絕佳的 Web 遊戲，而且我們講的可不是用 Flash® 寫的簡單卡牌遊戲，或是多人的社交遊戲而已。卻是可打趴一堆平面遊戲的 3D 動作射擊或角色扮演遊戲。多虧 JavaScript 的即時 (Just-in-time，JIT) 技術與新 API 雙雙大幅提升其效能，你所撰寫的遊戲已可於瀏覽器 (或支援 HTML5 的裝置) 中執行，卻又不致犧牲任何效能。

HTML5 遊戲平台
----------

如同 Mozilla 常說的「Web 即是平台」，你可將 Web 想像為較佳的遊戲平台。接著就來看看 Web 平台的核心：

| 功能 | 技術 |
| --- | --- |
| **音效** | Web Audio API |
| **圖形** | WebGL (en-US) (OpenGL ES 2.0) |
| **輸入** | 觸控事件、Gamepad API (en-US)、裝置感測器、WebRTC (en-US)、Full Screen API、Pointer Lock API |
| **程式語言** | JavaScript（或 C/C++ 可透過Emscripten 編譯為 JavaScript） |
| **網路連線** | WebRTC (en-US) 及/或 WebSockets |
| **儲存功能** | IndexedDB 或雲端 |
| **Web** | HTML、CSS、SVG（還有更多！） |

商業案例
----

不論你是獨立或大型遊戲工作室的開發者，你都應該將 Web 作為自己下一個遊戲專案的系統。先來看看 Web 能對你提供多少優勢：

1. Web 無遠弗屆，而用 HTML5 撰寫的遊戲可自由在桌機、平板電腦、智慧電視、智慧型手機上執行。
2. 可獲得更好的行銷與露出機會。你不再限制於某個 App 商店才能推廣自己的 App；反而能透過 Web 上的所有媒體推銷遊戲，並利用 Web 的串連與分享效率接觸到新客戶。
3. 你能控制「付款」這個重要的作業。之前只要你的遊戲放在某個生態系統中，就必須支付超過 30% 的收益給該系統。但現在你可選擇自己喜歡的 App 訂價與付款服務。
4. 同樣的，你也能自行控制 App 的更新頻率，而不再需要枯等別人審核你的重要修正檔，還不知道今天還明天才能上架。
5. 控制你的分析方式！你能蒐集自己所需的資料，或可選擇你所愛用的第三方，進而獲得你的銷售資訊以及所觸及的消費族群；不需再讓別人幫你決定分析方法。
6. 你能進一步管理自己與消費者之間的關係，不再受限於 App 商城的機制而取得篩選過的反饋意見。也不需再經過中間人，就能以自己的方式和消費者直接交流。
7. 玩家隨時隨地都能暢玩你的遊戲。因為 Web 無所不在，消費者能在自己的手機、平板電腦、家裡桌機、辦公室電腦，或任何地方觀看遊戲進度。
遊戲開發者所應知道的 Web 技術
-----------------

 我們要為開發者提供 API 的相關資訊，了解 Web 帶來的絕妙開發功能。
 以下只列舉出其中數項：

Full Screen API

此簡易 API 可讓遊戲全螢幕運作，提供玩家絕佳的動作體驗。

Gamepad API (en-US)

如果要讓遊戲搭配搖桿或其他類型的控制器，就用這個 API。

HTML 與 CSS

這兩種技術可用以建立遊戲的使用者介面，並設定其風格與配置方式。部分的 HTML 即為 `<canvas>` 元素，可直接建構 2D 圖形。

HTML audio (en-US)

`<audio>` (en-US) 元素可輕鬆播放簡易音效與音樂。如果需要進一步效果，可參閱 Web Audio API 達到真正的音訊處理效能！

IndexedDB

此強大的資料儲存 API，可將使用者的資料保存於電腦或其他裝置之上，亦可於本端儲存遊戲資料與其他資訊；如此可避免每次都需再下載資料一次。即使目前處於無網路連線的狀態 (例如飛機上長達數個小時的旅程...)，也同樣可以玩遊戲 。

JavaScript

JavaScript 就是 Web 上使用的程式語言，可於現有瀏覽器上達到絕佳速度，且目前還在不斷的提升。你可寫出遊戲的程式碼，或可透過如 Emscripten 或 Asm.js 的技術，輕鬆移植現有的遊戲。

Pointer Lock API

Pointer Lock API 可鎖定遊戲介面中的滑鼠或其他指向裝置。取代之前的絕對游標定位，現可接收座標差而得到更精確的使用者動作，並避免使用者突然在他處輸入，卻遺漏了重要動作。

SVG (Scalable Vector Graphics，可縮放向量圖形)

可建構向量圖形，根據裝置畫面的解析度而順暢調整。

Typed Array（具型別陣列）

JavaScript 的具型別陣列，可讓你在 JavaScript 中存取原始的二進位資料。如此可讓你設定 GL 紋理 (Texture)、遊戲資料，或其他物件。甚至非原生 JavaScript 格式的亦可處理。

Web Audio API

此 API 可透過 JavaScript 程式碼控制音訊的回播、合成、操作等作業，讓你建構絕妙音效並即時播放音樂。

WebGL (en-US)

可於 Web 內容中建立高效能、硬體加速的 3D (與 2D) 圖像。此為 Web 所支援的 OpenGL ES 2.0 實作。

WebRTC (en-US)

WebRTC (Real-Time Communications) API 可控制音訊與視訊資料 (包含視訊會議)，並能在兩名使用者之間來回傳輸其他應用程式的資料。想讓玩家能一邊爆怪物的頭還一邊交談？就用這個 API 吧。

WebSockets

WebSocket API 可讓你的 App 或網站連上伺服器，進而即時來回傳輸資料。適用於多人遊戲、聊天服務等。

Web Workers

Workers 可讓你分配背景執行緒，執行本身所屬的 JavaScript 程式碼，藉以利用新的多核心處理器。

XMLHttpRequest and File API

整合的 XMLHttpRequest 與 File API，可你從 Web 伺服器接收或傳送所需的任何資料 (別因為「XML」搞混了)。如此能順利下載新的遊戲關卡與圖片，藉以來回傳輸非即時的遊戲狀態資訊。
只使用 JavaScript 的 2D 打磚塊遊戲
=========================

* 次頁 »

本文將帶你逐步做出簡單的 MDN 打磚塊遊戲。除了只用 JavaScript 寫成之外，也透過 HTML5 的 `<canvas>` 繪製。

每個步驟均提供可測試修改的實際範例，讓你能看到各個步驟所產生的影響。你將了解該如何使用 `<canvas>` 元件完成基礎的遊戲機制，例如繪製 (Render)、移動圖形、碰撞偵測、操控機制、輸贏狀態等。

若要能充分了解此一系列文章，你應具備基礎至中等的 JavaScript 知識。結束此教學之後即可寫出自己的簡易網頁遊戲。

![Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives.](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/mdn-breakout-gameplay.png)

課程細節
----

所有課程和其他不同版本的 MDN 打磚塊遊戲，均可至 GitHub 找到：

1. 建立 Canvas 並繪製
2. 讓球移動
3. 讓球反彈
4. 搖桿和鍵盤控制 (en-US)
5. 判斷遊戲結束 (en-US)
6. 建立磚塊場地 (en-US)
7. 碰撞偵測 (en-US)
8. 更新分數並判斷輸贏 (en-US)
9. 滑鼠控制 (en-US)
10. 結束 (en-US)

 若一開始就單純使用 JavaScript，將能學到紮實的網頁遊戲開發知識。往後則可自由選擇你自己愛用的框架 (Framework) 來完成專案。
 框架同樣是由 JavaScript 寫成的工具。因此在用框架開發之前，能先了解程式語言本身將有助於了解框架內部所發生的事。框架可加快開發速度並代勞遊戲中某些無聊的部份，但若遊戲運作得不如預期，你都可試著除錯或撰寫純 JavaScript 的解決方案。

**備註：** 如果你對 2D 網頁遊戲開發的遊戲函式庫有興趣，可參考此〈使用剖析器 (Phaser) 的打磚塊遊戲 (en-US)〉系列相關文章 。

**備註：** 此系列文章也能當做行動遊戲開發工作坊的教材。如果你想講解一般的遊戲開發，則可利用此教學為基礎的〈Gamedev Canvas Content Kit〉。

下一步
---

好吧！讓我們開始第一章 — 建立 Canvas 並繪製。

* 次頁 »
讓球碰到牆壁後反彈
=========

* « 前頁
* 次頁 » (en-US)

這是 Gamedev Canvas tutorial (en-US)中的第三步 你可以在以下的連結中查看原始碼Gamedev-Canvas-workshop/lesson3.html.

很好我們現在可以讓球移動了, 但目前他會在移動到邊緣後消失, 這使我們少了點樂趣! 為了解決這個問題我們稍後會加入一些碰撞處理 ( later (en-US) ) 使球可以再碰到邊緣時反彈.

簡單的碰撞偵測
-------

為了偵測碰撞的發生，我們將檢查球是否接觸(相撞)牆壁，如果有碰到，我們將改變球的行進方向。

為了方便計算，我們定義一變數 `ballRadius` 代表球的半徑。在你程式碼宣告變數的地方加入以下內容:


```js
var ballRadius = 10;
```


接著更新繪製球的 `drawBall()` 函數，加入以下內容:


```js
ctx.arc(x, y, ballRadius, 0, Math.PI \* 2);
```

從頂部和底部反彈
--------

總共有四面牆壁會與球發生碰撞 — 首先處理上方的牆壁，我們在每個影格檢查球是否有接觸到 Canvas 上方壁面 —如果是的話，我們將扭轉球的運動，所以它將開始在相反的方向移動，並保持在可見邊界。記住坐標係從左上角開始，我們可以得到這樣的東西：


```js
if (y + dy < 0) {
  dy = -dy;
}
```


如果球位置的 Y 值低於零，改變 Y 軸上的運動的方向，通過設置它等於本身，扭轉。如果球是向上移動的速度為每幀的 2 個像素，現在它將移動「了」的速度為- 2 像素，這實際上等於在每幀的 2 個像素的速度向下移動。

上面的代碼將處理球反彈的頂部邊緣，所以現在讓我們想想下邊緣：


```js
if (y + dy > canvas.height) {
  dy = -dy;
}
```


 如果球的 Y 位置大於畫布的高度（請記住，我們計算從左上角的 Y 值，所以頂部邊緣開始在 0 和底部邊緣是在 480 像素，畫布的高度），然後通過反轉的 Y 軸運動的底部邊緣，如前。
 我們可以將這兩個語句為一個節省代碼冗長：


```js
if (y + dy > canvas.height || y + dy < 0) {
  dy = -dy;
}
```


如果兩個語句中的一個是真的，則反轉球的運動。

從左邊和右邊反彈
--------

我們有頂部和底部邊緣覆蓋，所以讓我們想想左，右的。它實際上是非常相似的，你所要做的就是重複 X 而不是 Y 的陳述：


```js
if (x + dx > canvas.width || x + dx < 0) {
  dx = -dx;
}

if (y + dy > canvas.height || y + dy < 0) {
  dy = -dy;
}
```


在這一點上你應該插入上面的代碼塊到 draw()功能，在關閉括號。

球不斷地消失在牆上！
----------

測試你的代碼在這一點上，你會留下深刻的印象-現在我們有一個球，反彈了所有四個邊緣的畫布！然而，我們有另一個問題-當球擊中每一個牆，它下沉到它略有改變方向：

![](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls/ball-in-wall.png)

這是因為我們計算的牆壁和球的中心的碰撞點，而我們應該做它的圓周。球應該反彈後，如果接觸牆，而不是當它已經在牆上的一半，所以讓我們調整我們的陳述有點包括。更新你添加到的最後一個代碼：


```js
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
  dx = -dx;
}
if (y + dy > canvas.height - ballRadius || y + dy < ballRadius) {
  dy = -dy;
}
```


當球的中心與牆的邊緣之間的距離與球的半徑完全相同時，它會改變運動方向。從邊緣減去一個半徑的寬度以及添加到另一個方向給我們在碰撞檢測在中球彈回牆壁的印象。

比較你的程式碼
-------

讓我們用剛剛所學的再次檢查完成的程式碼，並把玩一下：

**備註：** 每次球撞到牆上時嘗試改變球的顏色為隨機的顏色。

下一步
---

我們現在已經進入了舞台，我們的球是移動和停留在遊戲板上。 在第四章中，我們將討論實現一個可控制的球拍 - 參見 Paddle and keyboard controls (en-US).

* « 前頁
* 次頁 » (en-US)
讓球移動
====

* « 前頁
* 次頁 »

這一篇是Gamedev Canvas tutorial (en-US)十個步驟中的第二步。當完成此步驟你的程式碼應該會與Gamedev-Canvas-workshop/lesson2.html差不多

完成上一個步驟，你已經知道如何畫出一顆球，現在讓他動起來吧。藉由繪製球在螢幕上然後再清除，然後在每個影格中繪製球在偏移一點點的位置上（如果在同一個位置上就等於沒動），造成物體移動的感覺，就如同電影中物體移動的方式。

定義一個繪製用的迴圈
----------

為了固定更新 canvas 繪圖區域的每一個影格，我們需要定義一個繪製函式（drawing function），它將會重複執行，用不同的變數改變球的位置或其他物的位置。重複執行一個函式，其中使用 JavaScript timing function，像是 `setInterval()` (en-US) 或是 `requestAnimationFrame()`.

除了前兩行的 JavaScript，其餘的都刪除，並將以下的程式碼加入在前兩行之後。draw()函數每十毫秒會被 setInterval 執行一次:


```js
function draw() {
  // drawing code
}
setInterval(draw, 10);
```


因為 `setInterval` 無限循環的特性， `draw()` 函數將會每 10 毫秒被呼叫一次除非我們將它停止。 現在，讓我們來把球畫出來 — 將以下程式碼加入到 `draw()` 函數內:


```js
ctx.beginPath();
ctx.arc(50, 50, 10, 0, Math.PI \* 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
```


現在將你的程式碼更新 — 球將會在每個影格被重新繪製.

讓球動起來
-----

由於球並沒有移動，你沒有辦法察覺到它正不斷的被重新繪製。讓我們稍作修改。首先，取代掉原本寫死的位置(50,50)，我們宣告變數 x 和 y 讓球從 Canvas 正中央的底部出發，接著利用 x 和 y 來定義球應該被畫在哪裡。

首先將下面兩行程式碼加到你的 `draw()` 函數用以定義 `x` 和 `y`:


```js
var x = canvas.width / 2;
var y = canvas.height - 30;
```


接著修改 `draw()` 函數，在 `arc()` (en-US) 方法裡使用了變數 x 和 y，就像下面被強調的那行程式碼：


```js
function draw() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}
```


再來是最重要的部分: 在每個影格被繪製出來後，我們想要對 x 和 y 增加一數值，讓球看起來好像在移動一樣。讓我們來定義這個數值為 dx 以及 dy，並且分別設為 2 以及 -2。將以下程式碼添加到你定義 x 和 y 的地方:


```js
var dx = 2;
var dy = -2;
```


最後，在每個影格中我們利用 dx 和 dy 來更新 x 和 y 的數值，球就會在每次更新後被畫到不同的位置。將最後兩行程式碼加到你的 draw()函數內:


```js
function draw() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
  x += dx;
  y += dy;
}
```


儲存你的程式碼並在瀏覽器重新整理。程式正常運作，雖然球似乎留下的他的蹤跡:

![](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball/ball-trail.png)

在每個影格開始前清除 canvas
-----------------

由於我們在每個影格繪製新的球之前並沒有把舊的清除掉，讓他看起來像留下了一條痕跡。別擔心，其實是有方法可以把 canvas 清除掉: `clearRect()` (en-US). 這個方法需要 4 個參數: 前兩個參數代表了長方形左上角的 x 和 y 座標，後兩個參數代表了長方形右下角的 x 和 y 座標。之前在這長方形範圍內所繪製的東西將會被清除掉。

將以下強調的程式碼加到 `draw()` 函數內:


```js
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
  x += dx;
  y += dy;
}
```


將程式碼儲存並重新整理瀏覽器，這次球沒有再留下痕跡了。每 10 毫秒 canvas 會被清除，球將會被畫在指定的位置上，且 x 和 y 會更新以用在下一個影格.

整理程式碼
-----

再接續幾個章節我們會持續增加 `draw()` 函數內的指令，讓我們儘可能的維持程式的簡潔度。讓我們把繪製球的程式碼獨立為一個函數。

將原本的 draw() 函數拆成以下兩個函數:


```js
function drawBall() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  x += dx;
  y += dy;
}
```

比較你的程式碼
-------

以下為到目前為止完整的程式碼，你可以核對並試著操作以幫助你更瞭解他的運作方式:

Exercise: 練習改變球的移動速度或行進方向。

下一步
---

我們繪製了球並且讓他可以移動，但他仍會消失在 canvas 的邊緣。在第三章我們將會實作 讓球碰到牆壁後反彈 (en-US).

* « 前頁
* 次頁 »
建立Canvas並畫出
===========

* « 前頁
* 次頁 »

這是Gamedev Canvas tutorial (en-US)十個步驟的第一步。你可以這份教學的原始碼，當你完成這份教學你的程式碼應該跟Gamedev-Canvas-workshop/lesson1.html差不多。

在開始撰寫遊戲功能之前，我們先建構在遊戲中負責渲染的基礎結構。渲染可透過 HTML 的`<canvas>` 元件完成。

遊戲的 HTML
--------

當整個遊戲透過`<canvas>` 元件渲染時，HTML 檔案結構就會相當簡單。用你最喜歡的文字編輯器打開新的 HTML 檔，將它命名為`index.html並存在適當的位置上，再將下面的的程式碼貼到index.html中`:


```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Gamedev Canvas Workshop</title>
    <style>
 \* {
 padding: 0;
 margin: 0;
 }
 canvas {
 background: #eee;
 display: block;
 margin: 0 auto;
 }
 </style>
  </head>
  <body>
    <canvas id="myCanvas" width="480" height="320"></canvas>

    <script>
 // JavaScript code goes here
 </script>
  </body>
</html>
```


在 header 中設定了文字編碼、以及`<title>`和一些 CSS 樣式。在 body 中包含`<canvas>`與`<script>`，前者將用來渲染遊戲畫面，後者將用來撰寫 JavaScript 程式控制渲染。`<canvas>` 元件有個 `id` 為 `myCanvas` 方便當作參考(reference，如許多程式語言中的變數)讓我們設定它的寬度為 480 pixels 與高度 320 pixels，這份教學中全部的 JavaScript 程式碼都會寫在 `<script>` 開始標記與 `</script>` 結束標記中間。

Canvas 基礎
---------

為了能夠順利渲染圖形在`<canvas>`元件中，獲得`<canvas>`元件的參考。請將下列的程式碼加在`<script>`開始標記的後面。


```js
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
```


我們將`<canvas>`元件的參考存成變數 canvas 為了未來使用。建立 ctx 變數儲存"2D 渲染環境"，ctx 變數實際拿來繪製 Canvas 的工具。

以下片段的程式範例在 canvas 上印出紅色正方形。將以下的程式加在上面 J 的 avaScript 程式碼之後，再用瀏覽器打開`index.html`測試。


```js
ctx.beginPath();
ctx.rect(20, 40, 50, 50);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
```


所有的指令都介於`beginPath()` (en-US)與`closePath()` (en-US)。我們用`rect()` (en-US)定義了一個矩形，`rect()` (en-US)中前兩個數值代表左上角的座標。在上面的情況中，矩形距離左邊 20 pixels，距離畫面上方 40 pixels，50 pixels 寬，50 pixels 高，形成完美的正方形。`fillStyle` (en-US)屬性所儲存的顏色會被`fill()` (en-US)方法用來塗滿正方形，在此為塗上紅色。

不僅矩形— 以下的程式碼印出綠色的圓形。試著將程式碼加在 JavaScript 底部，存檔在重新整理瀏覽器中的`index.html`:


```js
ctx.beginPath();
ctx.arc(240, 160, 20, 0, Math.PI \* 2, false);
ctx.fillStyle = "green";
ctx.fill();
ctx.closePath();
```


如同你看到的我們再次使用了`beginPath()` (en-US)與`closePath()` (en-US)。在它們中間最重要的程式碼是`arc()` (en-US)。`arc()` (en-US)用到六個參數(依序介紹)：

* `圓弧中心的x、y座標`
* 圓弧的半徑
* 圓弧開始和結束的角度(從開始到結束的角度, 以弧度表示)
* 繪製的方向(`false`代表順時針方向, 預設或 true 為逆時針方向) 最後一個參數並非必要

`fillStyle` (en-US)看起來與之前不同，原因就像 CSS 一樣可以用 16 進位、顏色關鍵字、`rgba()函式等其他可用的顏色指定方法。`

不但有`fill()` (en-US)填滿圖形，還有 `stroke()` (en-US) 專門為外輪廓線上色。也試著加入下面的 JavaScript 程式碼吧:


```js
ctx.beginPath();
ctx.rect(160, 10, 100, 40);
ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
ctx.stroke();
ctx.closePath();
```


上面的程式碼印出藍色邊框的空心矩形，由於在`rgba()函式的`alpha 通道，藍色邊框呈現半透明。

比較你的程式碼
-------

這裡第一課的有全部原始碼，在 JSFiddle 上實際運行:

**備註：** 練習改變物體的大小和顏色

下一步
---

現在我們已經設定基本的 HTML 並且學了一些 canvas 知識 ，讓我們接著下去第二章實做如何在遊戲中移動球 (en-US)。 (en-US)

* « 前頁
* 次頁 »
伺服端網站程式設計
=========

***動態網站***–***伺服端網站程式設計***是一連串有關如何建立動態網站的模組：動態網站可以針對 HTTP 請求，發送客製化的資訊。這些模組將介紹伺服端網站程式設計：還有以初學者的角度，來教你怎麼使用 Django (Python) 與 Express (Node.js/JavaScript) 來架設基本的動態網路程式。

大多數主流網站會使用伺服端技術，以根據需要呈現動態資料。例如說，來想想亞馬遜（Amazon）上架多少商品、還有臉書（Facebook）貼了多少動態。如果都用靜態頁面來呈現這些內容，開發就會毫無效率可言。因此，我們會使用靜態技術（HTML、CSS、JavaScript）來顯示靜態模板；並在需要時，動態更新模板內的資料。一如你在逛亞馬遜時，看著五花八門的產品一般。

在當今的 Web development 的世界，我們強烈建議學習怎麼開發伺服端網站程式。

學習路徑
----

學習伺服端網站程式設計通常比用戶端網站程式設計簡單，因為動態網站比較傾向執行多次相似的操作（像是從資料庫擷取資料並放到頁面上、驗證用戶輸入的資料並存到資料庫、檢查登入用戶權限之類的）、使用框架建立網站能讓上述操作、以及其他常見操作變得簡單許多。

基本的程式概念（或是理解特定的語言）會很有用，但不是必須的。同樣地，精於用戶端網站程式設計不是必須，但它能在前端開發時，幫你做得更好。

首先你要知道「web 是怎麼作動的」。我們建議先看看這些文章：

* 何謂網路伺服器？
* 建立網站需要什麼軟體？ (en-US)
* 如何把檔案傳到伺服器？ (en-US)

有了基本觀念後，就可以開始去學習模組章節的東西了。

模組
--

本章節包含了以下模組。你首先要從第一個模組開始，再循序漸進，學習接下來的模組。這些模組將告訴你如何與訪間最熱門的其中兩個伺服器端框架共事。

伺服器端程式設計起步走

本模組會提供與技術無關的伺服器資訊，像是「那什麼？」、「和用戶端有啥不同？」、「有用嗎？」之類的。本模組也會概述一些比較熱門的伺服器端 web 框架、並告訴你如何選擇。最後，我們還會概述有關伺服器服務的安全性問題。

Django 網站框架 (Python)

Django 以 Python 寫成，是個非常熱門的伺服器端 web 框架。本模組會講解 Django 是好框架的理由、如何建立開發環境、還有如何處理常見工作。

Express web framework (Node.js/JavaScript)

Express 以 JavaScript 寫成、並在 node.js 執行環境執行。它也是個非常熱門的伺服器端 web 框架。本模組會講解一些有關本框架的重要優點、也同樣會講解如何建立開發環境、還有如何處理常見工作。

參見
--

不用框架的 Node 伺服器 (en-US)

如果不想用框架的話，這篇文章會告訴你如何使用純 Node.js 提供簡易的靜態檔案。
無障礙網頁
=====

如果要當 web 開發者，學會 HTML、CSS、JavaScript 是很重要的。不過除此之外，你還要學得更多：你需要**負責任地**運用這些技術，才能讓所有讀者都能使用你的網頁。要達成這點，本模塊將展示一般最佳實做（在 HTML、CSS、JavaScript 有示範）、跨瀏覽器測試、還有其他啟動的要點。

概觀
--

When someone describes a site as "accessible," they mean that any user can use all its features and content, regardless of how the user accesses the web — even and especially users with physical or mental impairments.

* Sites should be accessible to keyboard, mouse, and touch screen users, and any other way users access the web, including screen readers and voice assistants like Alexa and Google Home.
* Applications should be understandable and usable by people regardless of auditory, visual, physical, or cognitive abilities.
* Sites should also not cause harm: web features like motion can cause migraines or epileptic seizures.

**By default, HTML is accessible, if used correctly.** Web accessibility involves ensuring that content remains accessible, regardless of who and how the web is accessed.

先決條件
----

要理解本模塊的概念，最少理解 HTML、CSS、JavaScript 是個好主意。如果在學習相關技術時學習會更好。

**備註：** 如果使用的設備無法讓你建立自己的文件，可以試著在 JSBin 或 Glitch 這種程式撰寫網站，執行大多數範例。

教學
--

何謂無障礙網頁？

這篇文章針對何謂無障礙網頁，起了一個好開頭。這模塊包含了要考慮哪些族群以及理由、不同族群會用什麼工具和 Web 互動、還有怎麼把無障礙網頁導入 Web 開發工作流程。

HTML：無障礙網頁的好開始 (en-US)

只要確保在任何時候，正確的 HTML 元素都用於正確的目的，就能消除各種網頁的障礙。這篇文章詳述 HTML 如何確保網頁無障礙。

充分實踐 CSS 與 JavaScript 的無障礙 (en-US)

如果 CSS 與 JavaScript 使用得當，將可以為無障礙網頁提供助力……反過來的話，就會嚴重影響無障礙體驗。這篇文章詳述如何在內容複雜的情況下，確保能充分實踐 CSS 與 JavaScript 的無障礙。

WAI-ARIA 基礎

從之前的文章來看，有時製作要涉及到非語意的 HTML 還有動態 JavaScript 更新技術……等，會令複雜的 UI 控制變得很困難。WAI-ARIA 正是為了解決此一問題而生。它對瀏覽器和輔助技術添加進一步的語意，讓用戶能知道發生了什麼事。我們將介紹如何在基本層面使用此技術，以提昇無障礙。

無障礙多媒體 (en-US)

會導致無障礙網頁出問題的另一個根源是多媒體：影片、聲音、圖片等內容，需要有合適的文字替代，以便輔助技術和它的用戶能夠理解。我們將在這篇文章中闡明作法。

行動無障礙網頁 (en-US)

隨著行動設備訪問漸受歡迎、還有像是 iOS 與 Android 這般熱門平台，已經具備完善的輔助工具，考慮到如何在這些平台上實踐無障礙網頁，就變得十分重要。這篇文章將討論行動裝置特有的無障礙網頁相關議題。

評估
--

無障礙網頁偵錯 (en-US)

要評估本模塊，我們會提出一些簡單的網站，你需要偵測有哪些無障礙的問題並修復之。

參見
--

* Start Building Accessible Web Applications Today：Marcy Sutton 所作的一套優秀教學影片。
* Deque University resources：包含程式碼範例、螢幕閱讀器參考、或是其他有用的資源。
* WebAIM resources：有教學、便覽、工具……等。
* Web Accessibility Evaluation Tools List - includes a list of web accessibility evaluation tools.