You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md

217 lines
6.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 建立太空遊戲 Part 2在畫布上繪製英雄與怪物
## 課前測驗
[課前測驗](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/31?loc=zh_tw)
## Canvas
Canvas 是 HTML 中的元素,預設上不帶有任何內容,就如一塊白板。你需要自己彩繪上去。
✅ 在 MDN 上閱讀[更多關於 Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)。
這是它典型的宣告方式,位在頁面的 body 中:
```html
<canvas id="myCanvas" width="200" height="100"></canvas>
```
上面我們設定了 `id`、`width` 和 `height`
- `id`:讓你在處理物件時,能快速地取得參考位置。
- `width`:物件的寬度。
- `height`:物件的高度。
## 繪製簡單幾何圖樣
Canvas 使用了笛卡爾座標系繪製圖案。因此有 x 軸與 y 軸來表達物件的所在地點。座標點 `0,0` 位在畫布的左上方;而右下方則是我們定義畫布的寬度與高度。
![畫布網格](../canvas_grid.png)
> 圖片出自於 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
要在 Canvas 物件上繪製圖案,你需要執行下列步驟:
1. **取得 Canvas 物件的參考位置**。
1. **取得 Context 物件的參考位置**,定義在 Canvas 元素中。
1. 使用 context 元素**進行繪製動作**。
以程式碼表達上述步驟會呈現成:
```javascript
// 繪製紅色矩形
//1. 取得 canvas 參考點
canvas = document.getElementById("myCanvas");
//2. 設定 context 為 2D 以繪製基本圖形
ctx = canvas.getContext("2d");
//3. 填入色彩紅色
ctx.fillStyle = 'red';
//4. 利用這些參數決定位置與大小,繪製矩形
ctx.fillRect(0,0, 200, 200) // x,y,width, height
```
✅ Canvas API 主要是處理 2D 圖形,但你也可以在網頁中繪製 3D 圖形。要完成這個需求,你可以使用 [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)。
你可以使用 Canvas API 繪製出這些物件:
- **幾何圖形**,我們已經展示繪製矩形的流程,還有許多種形狀可以使用。
- **文字**,你可以繪製文字,決定你想要的字型及顏色。
- **圖片**,你可以依據圖片檔繪製圖案,舉例來說像是 .jpg 或是 .png 檔。
✅ 試試看!你知道如何繪製矩形,你能在頁面中繪製圓形嗎?看看在 CodePen 上有趣的 Canvas 塗鴉。這邊有一樣[特別令人驚豔的例子](https://codepen.io/dissimulate/pen/KrAwx)。
## 讀取並繪製圖片檔
建立 `Image` 物件並設定其 `src` 屬性,你可以讀取圖片檔。接著監聽 `load` 事件,了解圖片何時已經可以被使用。程式碼如下:
### 讀取檔案
```javascript
const img = new Image();
img.src = 'path/to/my/image.png';
img.onload = () => {
// 圖片載入完成,準備使用
}
```
### 讀取檔案之模式
建議上可以將上述程式打包起來,建立成完整的結構,判斷圖片是否載入完成,也方便未來的使用:
```javascript
function loadAsset(path) {
return new Promise((resolve) => {
const img = new Image();
img.src = path;
img.onload = () => {
// 圖片載入完成,準備使用
resolve(img);
}
})
}
// 實際用法
async function run() {
const heroImg = await loadAsset('hero.png')
const monsterImg = await loadAsset('monster.png')
}
```
要在畫面上繪製遊戲物件,你的程式碼會如下所示:
```javascript
async function run() {
const heroImg = await loadAsset('hero.png')
const monsterImg = await loadAsset('monster.png')
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(heroImg, canvas.width/2,canvas.height/2);
ctx.drawImage(monsterImg, 0,0);
}
```
## 是時候來建立你的遊戲了
### 建立目標
你需要建立包含 Canvas 元素的網頁。它會是 `1024*768` 的黑色畫面。我們提供了兩張圖片:
- 英雄艦艇
![英雄艦艇](../solution/assets/player.png)
- 5*5 隻怪物
![敵軍艦艇](../solution/assets/enemyShip.png)
### 開始開發的建議步驟
在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括:
```bash
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
```
在 Visual Studio Code 中開啟這個資料夾的副本。你需要建立本地端的開發環境,建議為 Visual Studio Code 與安裝好的 NPM 與 Node。如果你的電腦中還沒設定好 `npm`[這是它的設定流程](https://www.npmjs.com/get-npm)。
前往 `your_work` 資料夾,開始你的專案:
```bash
cd your-work
npm start
```
這會啟動 HTTP 伺服器,網址為 `http://localhost:5000`。開啟瀏覽器並輸入該網址。目前會是空白的頁面,但不久後就會不一樣了。
> 筆記:想觀察畫面的改變,請重新整理你的頁面。
### 加入程式碼
`your-work/app.js` 中加入程式碼以解決下列目標:
1. 在 Canvas **繪製**黑色背景
> 要點:在 `/app.js` 中,加入兩行程式在 TODO 下方:設定 `ctx` 元素為黑色,左上方座標點為 0,0 且大小與 Canvas 相等。
2. **讀取**材質
> 要點:使用 `await loadTexture` 導入圖片位置以新增玩家與敵軍圖片。你還沒辦法在畫面上看到它們!
3. 在畫面的正下方**繪製**英雄
> 要點:使用 `drawImage` API 來繪製 heroImg 到畫面上,設定位置為 `canvas.width / 2 - 45` 與 `canvas.height - canvas.height / 4)`。
4. **繪製** 5*5 隻怪物
> 要點:現在移除註解,在畫面上繪製敵人。接著編輯函式 `createEnemies`。
首先,設定幾個常數:
```javascript
const MONSTER_TOTAL = 5;
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
const STOP_X = START_X + MONSTER_WIDTH;
```
接著,利用迴圈在畫面上繪製矩陣型態的怪物:
```javascript
for (let x = START_X; x < STOP_X; x += 98) {
for (let y = 0; y < 50 * 5; y += 50) {
ctx.drawImage(enemyImg, x, y);
}
}
```
## 結果
完成後的成果應該如下所示:
![黑畫面上有英雄與 5*5 隻怪物](../partI-solution.png)
## 解答
試著自己先完成程式碼,但如果你遭遇到困難,請參考[解答](../solution/app.js)。
---
## 🚀 挑戰
你已經學會繪製 2D 圖形的 Canvas API。看看 [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API),試著繪製 3D 物件。
## 課後測驗
[課後測驗](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/32?loc=zh_tw)
## 複習與自學
[閱讀更多資料](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API),學習更多有關 Canvas API 的用法。
## 作業
[把玩 Canvas API](assignment.zh-tw.md)