陣列腳本為遊戲中常見的腳本撰寫模式,可以大幅減少程式碼數量,且方便未來進行修改及調整。本篇將帶你了解什麼是陣列、如何搭配 for 迴圈使用,並以一個完整的多獎勵發放腳本為例,逐步說明每個區塊的用途。
💡 為什麼要用陣列?
假設你想一次發給玩家 5 種不同的道具,如果不使用陣列,你需要這樣寫:
❌ 不使用陣列(重複、難維護)
cm.gainItem(4000001, 1);
cm.gainItem(4000002, 1);
cm.gainItem(4000003, 1);
cm.gainItem(4000004, 1);
cm.gainItem(4000005, 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,是道具 IDgift[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,都可以用同樣的模式快速搭建,大大提升腳本撰寫效率!