跳到內容

程式碼片段

本節包含三個用於 LightScript 的實用程式碼片段:儀錶狀態處理器特效處理器

作為上一節的延續,Meter 類別旨在幫助追蹤不穩定儀錶資料中的有意義變化。將其視為您程式碼的剎車踏板——即使在複雜區域也能提供穩定性。每個儀錶都持有一個可自訂的值陣列,這些值是在每次 update 函式執行期間收集的。當該陣列中的所有值都相同(即資料「穩定」)時,儀錶更新其值並觸發連結的回呼函式以啟動特效。

方法說明
Meter(size, callback)建構函式接受 sizecallback 兩個參數。size — 為了使儀錶值被認為「穩定」到足以處理,相同值應出現的次數。較高的值帶來更高的準確性,較低的值帶來更少的延遲。callback — 當儀錶值穩定且已更改時要呼叫的函式。
Meter.setValue(value)您應該每個影格呼叫 setValue(value),或在此儀錶的新原始資料可用時隨時呼叫。

收集螢幕資料的過程通常應遵循以下結構:

  1. engine.vision.meter 值根據螢幕上的新資料更新。
  2. 在 update 函式內,呼叫 Meter.setValue(engine.vision.meter) 以記錄新值。
  3. Meter 檢查其內部陣列以查看是否所有值都相同。如果是,它更新自己的狀態並執行其分配的回呼函式。
  4. 然後,回呼函式使用 Meter 的變數評估特定條件,並在滿足這些條件時執行其程式碼。

重要注意事項:

不要跳過使用回呼。由於 update 函式持續執行,它必須保持盡可能高效。其主要職責應是更新 Meter 值。避免在 update 中鏈接條件語句來檢查儀錶和觸發特效,因為這會在每個循環中導致不必要的檢查。相反,在單獨的函式中定義您的特效並將它們作為回呼傳遞給您的 Meter

穩定後,Meter 將向其回呼函式提供幾個值:

變數說明
Meter.value儀錶的當前值。
Meter.increased指示此次更新我們的值是否增加的布林值
Meter.decreased指示此次更新我們的值是否減少的布林值
Meter.diff儀錶在此次更新中經歷的變化的_絕對值_。

以下是一個基本的單儀錶設置,包含 Meter 類別程式碼:

<head>
<title>Meter Example</title>
<meta description="Step-by-step metering" />
<meta meter="health" tags="vlc,fortnite" x= ".05" y=".9" width=".189" h="70-140" s="40-100" l="40-100" type="linear" />
</head>
<body style="margin: 0; padding: 0; background: #000;">
<canvas id="exCanvas" width="320" height="200"></canvas>
</body>
<script>
var c = document.getElementById("exCanvas");
var ctx = c.getContext("2d");
// 初始化儀錶
var healthMeter = new Meter(5, healthEffect);
function update(){
// 更新 Meter 值
healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update);
}
function healthEffect(){
if(healthMeter.increased){
// 觸發特效
} else if (healthMeter.value == 0){
// 觸發特效
} else if (healthMeter.diff > .3){
// 觸發特效
}
}
function Meter(size, callback) {
this.size = size;
this.value = 0;
this.diff = 0;
this.increased = false;
this.decreased = false;
var values = [];
this.setValue = function (updatedValue) {
// 添加並移位。
values.push(updatedValue);
if (values.length > this.size) {
values.shift();
}
// 如果我們沒有長期匹配,提前退出。
for (var i = 0; i < values.length - 1; i++) {
if (values[i] !== values[i + 1]) return;
}
// 我們到達這裡,所以我們有一個匹配的值集合。設定變數並執行回呼。
if (this.value !== values[0]) {
this.diff = Math.abs(this.value - values[0]);
this.increased = this.value < values[0];
this.decreased = this.value > values[0];
this.value = values[0];
callback();
}
};
}
window.requestAnimationFrame(update);
</script>

狀態處理器是一個特效堆疊,專門處理優先於所有其他特效的特效。如果您希望一個大型主導動畫不間斷地執行直到完成,請將其插入狀態處理器。

方法說明
StateHandler()建構函式不需要任何參數。
StateHandler.push(new State())您可以使用 push 將新狀態推入狀態堆疊,處理將立即開始。
StateHandler.pop()從狀態堆疊中彈出當前狀態,並開始處理堆疊上的前一個狀態。

推入狀態處理器的任何物件都必須實作 Process()。Process 函式決定處理器中特效的生命週期。

以下展示了一個基本的狀態處理器,以及應在特效函式內執行的 Process 函式:

var stateHdlr = new StateHandler();
function StateHandler() {
var stack = [];
var state = null;
// 將當前狀態設定為堆疊頂部的項目
var updateState = function () {
if (stack.length > 0) {
state = stack[stack.length - 1];
} else {
state = null;
}
};
// 允許開發者將特效添加到狀態處理器
this.Push = function (newState) {
stack.push(newState);
updateState();
};
// 允許開發者從處理器移除特效
this.Pop = function () {
stack.pop();
updateState();
};
// 呼叫當前狀態(特效)的 Process 函式
this.Process = function () {
if (state != null) {
state.Process();
}
};
}
function update(){
stateHdlr.Process();
}
this.start = new Date.now()
this.elapsed = 0;
this.duration = 1000;
this.Process = function () {
// 評估自特效開始以來的時間
this.elapsed = new Date.now() - this.start;
// 如果特效已達到其生命週期,從狀態處理器移除它
if (this.elapsed > this.duration) {
stateMgr.Pop();
}
// 如果特效仍在執行,呼叫特效 draw 函式
this.Draw();
};

特效處理器非常適合將所有較小、較輕的特效一起儲存和渲染。處理器中的每個特效都會在每次 update 呼叫時被評估,並在達到其生命週期末尾時被移除。

特效處理器只是一個儲存特效的陣列。就是這樣。

// 宣告特效陣列
let effects = [];
// (未顯示)評估 Meter,回呼函式將特效推入特效陣列
effects.push(new SpecialEffect());
// 迭代陣列,為每個特效動畫一個影格
for (let i = 0; i < effects.length; i++) {
effects[i].draw();
// 如果生命週期已結束,移除特效
if (effects[i].lifetime <= 0) {
effects.splice(i, 1);
}
}

狀態管理器專門用於優先特效,這意味著我們必須在執行期間給予它優先權。在您的 update 函式中,處理特效處理器,然後處理狀態處理器。這將在特效處理器的項目頂部繪製狀態特效。

如下所示:

function update(){
// 評估特效處理器
for (let i = 0; i < effects.length; i++) {
effects[i].draw();
if (effects[i].lifetime <= 0) {
effects.splice(i, 1);
}
}
// 然後評估狀態處理器
stateMgr.Process();
}

儲存 USB 資料是一個直接的過程,但這些程式使用的驅動程式已知會與某些系統發生衝突,有時會停用 USB 連接埠直到軟體被移除。常見的修復方法是在 BIOS/UEFI 設定中停用**「安全啟動」**。在繼續之前,強烈建議在隨身碟上準備系統還原,或有不依賴於啟動時使用者輸入的遠端存取電腦的方式。這在停用安全啟動無法解決問題且您無法存取系統解除安裝程式的情況下非常重要。在這種情況下,可能需要進行 Windows 重新整理以移除所有已安裝的程式同時保留您的個人檔案。您需自行承擔風險。如果您不願意嘗試,請在此處申請您的裝置。不要在筆記型電腦系統上使用此過程。

安裝後,過程很簡單,將擷取所有通過您 USB 裝置的資料。如果您計劃共享資料,請在擷取期間不要輸入任何敏感資訊,因為按鍵記錄包含在錄製中。可以使用的兩個第三方程式是 Usblyzer(免費試用)和 Wireshark(免費)。兩者都可以使用,但如果您選擇 Wireshark,請確保選擇 USBPcap

查看我們的下一頁回呼函式,獲取有關建構儀錶回呼和特效函式的更多詳細資訊。