返回教學列表
JS教學

基礎陣列循環

陣列腳本為遊戲中常見的腳本撰寫模式,可以大幅減少程式碼數量,且方便未來進行修改及調整。本篇將帶你了解什麼是陣列、如何搭配 for 迴圈使用,並以一個完整的多獎勵發放腳本為例,逐步說明每個區塊的用途。

💡 為什麼要用陣列?

假設你想一次發給玩家 5 種不同的道具,如果不使用陣列,你需要這樣寫:

❌ 不使用陣列(重複、難維護)

cm.gainItem(4000001, 1); cm.gainItem(4000002, 1); cm.gainItem(4000003, 1); cm.gainItem(4000004, 1); cm.gainItem(4000005, 1);

✅ 使用陣列 + 迴圈(簡潔、易改)

for (var i = 0; i < gift.length; i++) { cm.gainItem(gift[i][0], gift[i][1]); }

使用陣列的版本不管你有 5 個還是 50 個獎勵,迴圈的程式碼都不需要改變——只需要在陣列裡新增一行就好。

📋 完整範例代碼

JavaScript — 多獎勵發放腳本
var gift = [ [4000001, 1], // 獎勵 [4000002, 1], // 獎勵 [4000003, 1], // 獎勵 [4000004, 1], // 獎勵 [4000005, 1], // 獎勵 ]; var log = "補償獎勵"; var 可領取次數 = 1; function start() { status = -1; action(1, 0, 0); } function action(mode, type, selection) { if (mode == 1) { status++; } else if (mode == 0) { status--; } else { cm.dispose(); return; } if (status == 0) { player = cm.getPlayer(); var msg = "#w"; for (var i = 0; i < gift.length; i++) { msg += "獎勵道具 " + (i + 1) + " #i" + gift[i][0] + ":# #z" + gift[i][0] + ":# x " + gift[i][1] + "\r\n\r\n"; } msg += "是否確認領取獎勵"; cm.sendYesNo(msg); } if (status == 1) { if (player.getPrizeLog(log) >= 可領取次數) { cm.sendOk("此帳號已領取 " + 可領取次數 + " 次"); cm.dispose(); return; } for (var i = 0; i < gift.length; i++) { cm.gainItem(gift[i][0], gift[i][1]); } player.setPrizeLog(log); cm.sendOk("獎勵已發放"); cm.dispose(); return; } }

📖 逐步解析

1  陣列結構 — gift

var gift = [ [4000001, 1], // [道具ID, 數量] [4000002, 1], [4000003, 1], ];

gift 是一個 二維陣列(陣列裡面還有陣列)。

每一個內層 [道具ID, 數量] 代表一筆獎勵資料:

  • gift[0][4000001, 1],代表第 1 個獎勵
  • gift[0][0]4000001,是道具 ID
  • gift[0][1]1,是道具數量

要新增或移除獎勵,只需要在這裡增減一行 [道具ID, 數量],下方的程式碼完全不用動。

2  設定變數 — log可領取次數

var log = "補償獎勵"; var 可領取次數 = 1;
  • log:領取紀錄的名稱(Key),用來辨識玩家是否已領過此活動。每個不同的活動要使用不同的名稱,避免紀錄互相衝突。
  • 可領取次數:限制每個帳號最多可以領幾次。設為 1 代表只能領一次,改成 3 就能領三次。

3  程式進入點 — start()

function start() { status = -1; action(1, 0, 0); }

玩家點擊 NPC 時,系統會先呼叫 start()

  • status(對話頁碼)初始化為 -1
  • 立即呼叫 action(1, 0, 0),相當於模擬玩家按下「下一步」,讓 status-1 加 1 變成 0,進入第一個對話畫面。

4  按鈕判斷 — mode 控制流程

if (mode == 1) { status++; // 按「是」或「下一步」→ 頁碼 +1 } else if (mode == 0) { status--; // 按「否」或「上一步」→ 頁碼 -1 } else { cm.dispose(); // 其他情況(如強制關閉)→ 結束對話 return; }
  • mode == 1:玩家按下確認/下一頁,status 加 1。
  • mode == 0:玩家按下取消/上一頁,status 減 1。
  • 其他(如關閉視窗):直接呼叫 cm.dispose() 結束腳本。

5  第一個畫面 — 用 for 迴圈列出所有獎勵

if (status == 0) { player = cm.getPlayer(); var msg = "#w"; for (var i = 0; i < gift.length; i++) { msg += "獎勵道具 " + (i + 1) + " #i" + gift[i][0] + ":# #z" + gift[i][0] + ":# x " + gift[i][1] + "\r\n\r\n"; } msg += "是否確認領取獎勵"; cm.sendYesNo(msg); }

這裡是 for 迴圈的核心用法。逐行解析迴圈邏輯:

  • var i = 0:從第 0 個獎勵開始(陣列索引從 0 起算)。
  • i < gift.length:只要 i 還沒超過陣列總數就繼續執行。gift.length 會自動計算陣列有幾筆,這裡是 5。
  • i++:每次執行完一輪,i 加 1,移到下一個獎勵。

msg 字串格式說明:

  • #w:顯示對話框背景。
  • #i道具ID:#:在對話框中顯示道具圖示。
  • #z道具ID:#:顯示道具的名稱。
  • \r\n\r\n:換行(在對話框中空一行)。
  • cm.sendYesNo(msg):顯示「是/否」選項的對話框。

6  第二個畫面 — 次數判斷 + 發放道具

if (status == 1) { // 第一步:先確認是否超過次數上限 if (player.getPrizeLog(log) >= 可領取次數) { cm.sendOk("此帳號已領取 " + 可領取次數 + " 次"); cm.dispose(); return; } // 第二步:逐一發放陣列中所有獎勵 for (var i = 0; i < gift.length; i++) { cm.gainItem(gift[i][0], gift[i][1]); } // 第三步:記錄已領取一次,然後結束 player.setPrizeLog(log); cm.sendOk("獎勵已發放"); cm.dispose(); return; }

玩家按下「是」後,status 變成 1,進入發放邏輯:

  • getPrizeLog(log):讀取此帳號對 "補償獎勵" 這個 key 的領取次數。
  • 若次數 >= 可領取次數,代表已達上限,顯示提示並結束。
  • 否則執行 for 迴圈,用 cm.gainItem() 一筆一筆發放 gift 陣列中的每個獎勵。
  • setPrizeLog(log):將此帳號的領取紀錄 +1,之後再來就會被次數判斷擋住。

🛠️ 如何快速修改獎勵內容

📌 只需要改最上面的 gift 陣列!

例如你想把 5 個獎勵改成 3 個,並且第 2 個給 5 個,只需要修改陣列部分:

修改範例
var gift = [ [4000001, 1], // 第 1 個獎勵:ID 4000001,數量 1 [4000002, 5], // 第 2 個獎勵:ID 4000002,數量改成 5 [4000099, 1], // 第 3 個獎勵:換成另一個道具 ID // 刪掉第 4、5 個,這樣就只剩 3 個獎勵了 ];

底下的 for 迴圈會自動讀取陣列長度(gift.length 此時變成 3),完全不需要手動修改任何邏輯。

✅ 重點整理

陣列 [] 的概念

把一組相關的資料集中放在一起,用 [索引] 取值,索引從 0 開始。

二維陣列就是「陣列裡面的陣列」,用 [行][欄] 取得特定位置的資料。

for 迴圈的三個部分

  • 初始值 var i = 0:從哪裡開始
  • 條件 i < gift.length:什麼時候停止
  • 更新 i++:每輪結束後怎麼變化

為什麼這樣寫比較好?

  • 獎勵清單集中在最上方,一眼就能看到並快速修改。
  • 不管有幾個獎勵,迴圈的程式碼完全不用改。
  • 顯示清單和發放道具都使用同一份 gift 陣列,不會出現「顯示的跟發的不一樣」的問題。

💡 學會陣列+迴圈之後,不管是簽到禮包、補償獎勵、還是多選題 NPC,都可以用同樣的模式快速搭建,大大提升腳本撰寫效率!