iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
JavaScript

QA 的 JavaScript 初心之路:30 天做出一個能玩的戰鬥小遊戲《勇者 vs 小怪》系列 第 12 篇

Day12|從一片空白到打不死的小強:第一階段總結

  • 分享至 

  • xImage
  •  

第一階段回顧:從 hello world 到能互動

十二天前我完全沒寫過 JavaScript。今天回頭看,已經有一個能按按鈕、會扣血、會宣布勝負的網頁了。這篇不學新東西,把前十一天整理一遍,順便誠實記錄哪裡最卡。

十一天學了什麼

Day 主題 關鍵收穫
1 環境建置 VS Code + Live Server,console.log 印在主控台不是網頁上
2 變數與型別 let/const、SyntaxError 會擋掉整支程式、typeof null 是 "object"
3 字串 模板字串 `${}` 比 + 拼接好用太多
4 條件判斷 === 不是 ==(0 == false 竟然是 true)、邊界值要主動測
5 陣列 索引從 0 開始是「位移量」、length 本身是第一個不存在的索引
6 物件 const 鎖的是「指向誰」不是內容、Console 的活參照陷阱
7 迴圈 for 三段式、無窮迴圈讓我的電腦起飛
8 函式 參數是影本、return 才會交出值、Math.max 設傷害下限
9 作用域 變數活在哪、var 為什麼被勸退
10 DOM 抓元素、改 textContent,畫面第一次有東西
11 事件 addEventListener,遊戲第一次會等玩家

最難的一天和最久的一天,不是同一天

這是我這十二天最意外的一個發現:花最久的是 Day 11,但最難的是 Day 10。

Day 10 難,是因為 document 那一整套東西完全是新世界。前九天我學的都是「怎麼算」,Day 10 開始學的是「怎麼跟瀏覽器溝通」——document.getElementById 這種寫法,一開始只能照抄,說不上理解。

Day 11 久,反而不是因為觀念難,而是因為整體內容變長了。

卡住的真正原因:我開始需要在腦中模擬程式

Day 11 寫到後面,我發現自己一直在做同一件事:回頭找「我要的這個動作,該加在哪一行」。

而且不只是找位置,還要在腦中模擬:加在這裡的話,執行到這一行的時候,enemy.hp 是多少?訊息文字現在是什麼?按鈕變了沒?——同一個變數在不同位置有不同的值,而我要判斷的是「在哪個位置插入,才會拿到我要的那個狀態」。

需要同時考慮的東西變多了,這才是變慢的原因。

回頭看,前十天的程式都是「從上到下跑一遍就結束」,腦中只要跟著跑一次就好。從 Day 11 開始,程式變成「掛好機關、停下來等、被點擊、跑一段、再等」——它有了狀態,而狀態會隨著玩家的操作改變。我卡住的地方不是語法,是要開始追蹤「現在是第幾回合、小怪死了沒、訊息該顯示哪一種」。

這也解釋了為什麼 Day 11 出現的兩個 bug 都跟狀態有關:「勝利的瞬間顯示了鞭屍訊息」是搞混了「剛剛死」和「早就死」;「畫面凍住」是資料的狀態和畫面的狀態不同步。這兩個都不是打錯字,是沒想清楚狀態。

最有 QA 感的一刻:那個 -5

如果要挑一個「這件事跟我本業最有關」的瞬間,是 Day 8 那個 -5。

當時我測 calcDamage(15, 20)——攻擊力比防禦力低,函式回傳 -5。數學上沒錯,但放進遊戲就變成 敵人 HP 60 - (-5) = 65,攻擊反而幫對方補血。

這個問題最像我平常的工作:不需要理解程式怎麼寫的,只要餵一組極端的輸入,問題就直觀地跳出來。不用推理、不用讀程式碼,看一眼就知道不對。

而且後續的決策也很 QA:發現問題之後,不是隨便挑個修法,而是要問「這裡應該怎樣才對」。我最後選了「最少造成 1 點傷害」,不是因為它最好寫,是因為之後想做流血類的武器,讓攻擊力不足的玩家也能靠擦傷磨贏魔王——一個邊界值的決定,影響了遊戲後期的戰術空間。

十一天下來我發現自己一直在做這件事:Day 4 測 hp 剛好等於 30、Day 5 測 enemies[length]、Day 7 故意跑無窮迴圈、Day 11 一直按到血變負數。我沒有刻意要做測試,只是很自然會想「如果餵一個怪的值進去會怎樣」——這大概是職業病,但在學程式的時候意外很好用,因為它讓我撞到很多正常照抄範例不會撞到的東西。

我做了一份速查表

寫到 Day 11 的時候,我發現一個具體的困擾:經常覺得「前幾天好像學過可以用一樣的方法」,然後開始翻紀錄找。

所以我整理了一份速查表,放在 repo 的 CHEATSHEET.md。它的分類方式是「我想做什麼」而不是「這是什麼語法」——因為卡住的時候我腦中想的是「我想把這個數字顯示在畫面上」,不是「我需要 DOM 操作」。

裡面還有兩個區塊是為自己做的:

  • 錯誤訊息對照表:把這十一天真的遇過的紅字全部列出來,看到就能直接查意思和常見原因
  • 「安靜失敗」清單:不報錯但也沒生效的那些坑,目前收集到六個

第二個清單是這十一天最意外的收穫。我原本以為寫程式的難處是「錯誤看不懂」,實際上真正難查的是不報錯的錯:字串改一個字不生效、兩個同名函式安靜覆蓋、監聽器掛上 undefined 卻不吭聲、資料改了畫面沒動。這些都不會有紅字告訴你,只會讓你懷疑自己。

repo 現況

ironman-js-battle/
├── day01/ ~ day11/     每天的練習檔
├── CHEATSHEET.md       速查表
└── README.md           進度清單

十一個 commit,每天一個。程式碼從 console.log("鐵人賽 Day 1 開跑") 長到一個能互動的戰鬥畫面。

下一階段

接下來要把這些零件真正組裝起來:目前小怪只會站著被打,要讓牠會反擊;目前只有一回合,要做成完整的回合制;目前畫面很醜,要加上 CSS 和血條。

而看完自己的卡關紀錄,我對下一階段最需要的準備已經很清楚了:不是學更多語法,是練習「在腦中追蹤狀態」。Day 11 兩個 bug 都是狀態沒想清楚,而接下來的程式只會更長、狀態只會更多。

第一階段結束。從一片空白的網頁,到一個會等我按下攻擊的小怪——雖然牠現在還是打不死的小強。


上一篇
Day11|事件:我做出了一隻打不死的小強
下一篇
Day13|innerHTML:我第一次在自己的網頁上被攻擊
系列文
QA 的 JavaScript 初心之路:30 天做出一個能玩的戰鬥小遊戲《勇者 vs 小怪》 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言