Snippets
Phần này chứa ba đoạn code hữu ích cho LightScripts: Meter, State Handler và Effect Handler.
Meter
Phần tiêu đề “Meter”Là phần tiếp nối từ phần trước, lớp Meter được thiết kế để theo dõi những thay đổi quan trọng trong dữ liệu meter không ổn định. Nó hoạt động như một bộ hãm phanh cho code — ngay cả trong các vùng phức tạp, nó đảm bảo tính ổn định. Mỗi meter lưu trữ một mảng giá trị có thể điều chỉnh được thu thập ở mỗi lượt của hàm update. Khi tất cả các giá trị trong mảng bằng nhau (tức là dữ liệu “ổn định”), meter cập nhật giá trị của nó và kích hoạt hàm callback đính kèm để chạy hiệu ứng.
| Phương thức | Mô tả |
|---|---|
| Meter(size, callback) | Constructor nhận size và callback.\n\n\n\nsize – số lần một giá trị giống hệt nhau phải xuất hiện để giá trị meter được coi là “đủ ổn định” để xử lý. Giá trị lớn hơn dẫn đến độ chính xác cao hơn, giá trị nhỏ hơn dẫn đến độ trễ thấp hơn.\n\n\ncallback – hàm được gọi khi giá trị meter ổn định và đã thay đổi. |
| Meter.setValue(value) | setValue(value) nên được gọi mỗi khung hoặc mỗi khi có dữ liệu thô mới cho meter này. |
Quá trình lấy dữ liệu từ màn hình thường phải tuân theo cấu trúc này:
- Giá trị engine.vision.meter được cập nhật dựa trên dữ liệu màn hình mới.
- Bên trong hàm update, Meter.setValue(engine.vision.meter) được gọi để ghi nhận giá trị mới.
- Meter kiểm tra mảng nội bộ của nó xem tất cả các giá trị có giống hệt nhau không. Nếu có, nó cập nhật trạng thái của chính nó và thực thi hàm callback được gán.
- Hàm callback sau đó đánh giá các điều kiện cụ thể dựa trên các biến Meter và thực thi code khi các điều kiện đó được đáp ứng.
LƯU Ý QUAN TRỌNG:
Đừng bỏ qua callbacks. Vì hàm update chạy liên tục, nó phải duy trì hiệu quả nhất có thể. Vai trò chính của nó nên là cập nhật các giá trị Meter. Nên tránh việc xâu chuỗi các điều kiện bên trong update để kiểm tra meter và kích hoạt hiệu ứng, vì điều đó dẫn đến các kiểm tra không cần thiết trong mỗi chu kỳ. Thay vào đó, hãy định nghĩa các hiệu ứng trong các hàm riêng biệt và truyền chúng dưới dạng callbacks vào Meter.
Biến meter
Phần tiêu đề “Biến meter”Khi ổn định, meter cung cấp cho hàm callback một số giá trị:
| Biến | Mô tả |
|---|---|
| Meter.value | Giá trị hiện tại của meter. |
| Meter.increased | Boolean cho biết giá trị có tăng lên trong lần cập nhật này không |
| Meter.decreased | Boolean cho biết giá trị có giảm xuống trong lần cập nhật này không |
| Meter.diff | Giá trị tuyệt đối của sự thay đổi mà meter đã trải qua trong lần cập nhật này. |
Ví dụ meter
Phần tiêu đề “Ví dụ meter”Đây là cài đặt đơn giản với một meter bao gồm code lớp 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");
// Meter initialisieren var healthMeter = new Meter(5, healthEffect);
function update(){ // Meter-Werte aktualisieren healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Effekt auslösen } else if (healthMeter.value == 0){ // Effekt auslösen } else if (healthMeter.diff > .3){ // Effekt auslösen } }
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) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. 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><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");
// Meter initialisieren var healthMeter = new Meter(5, healthEffect);
function update(){ // Meter-Werte aktualisieren healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Effekt auslösen } else if (healthMeter.value == 0){ // Effekt auslösen } else if (healthMeter.diff > .3){ // Effekt auslösen } }
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) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. 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>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) { // Hinzufügen und verschieben. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Frühzeitig beenden, wenn keine langfristige Übereinstimmung vorliegt. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Hier angekommen, liegt eine übereinstimmende Wertsammlung vor. Variablen setzen und Callback ausführen. 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(); } }; }Trình xử lý trạng thái
Phần tiêu đề “Trình xử lý trạng thái”Trình xử lý trạng thái là một stack các hiệu ứng đặc biệt quản lý các hiệu ứng có độ ưu tiên cao hơn tất cả các hiệu ứng khác. Khi cần chạy một animation lớn chiếm ưu thế mà không bị gián đoạn đến cuối, nó được đẩy vào trình xử lý trạng thái.
| Phương thức | Mô tả |
|---|---|
| StateHandler() | Constructor không yêu cầu đối số. |
| StateHandler.push(new State()) | Push cho phép đẩy trạng thái mới vào stack trạng thái, và quá trình xử lý bắt đầu ngay lập tức. |
| StateHandler.pop() | Xóa trạng thái hiện tại khỏi stack trạng thái và bắt đầu xử lý trạng thái trước đó trên stack. |
Mỗi đối tượng được đẩy vào trình xử lý trạng thái phải triển khai Process(). Hàm Process xác định vòng đời của hiệu ứng trong handler.
Ví dụ trình xử lý trạng thái
Phần tiêu đề “Ví dụ trình xử lý trạng thái”Đây là trình xử lý trạng thái cơ bản cùng với hàm Process nên thực thi bên trong các hàm hiệu ứng:
var stateHdlr = new StateHandler();
function StateHandler() { var stack = []; var state = null;
// Aktuellen Zustand auf das oberste Element im Stapel setzen var updateState = function () { if (stack.length > 0) { state = stack[stack.length - 1]; } else { state = null; } };
// Ermöglicht dem Entwickler, einen Effekt zum State-Handler hinzuzufügen this.Push = function (newState) { stack.push(newState); updateState(); }; // Ermöglicht dem Entwickler, einen Effekt aus dem Handler zu entfernen this.Pop = function () { stack.pop(); updateState(); }; // Process-Funktion des aktuellen Zustands (Effekts) aufrufen 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 () { // Zeit seit Effektstart auswerten this.elapsed = new Date.now() - this.start; // Wenn der Effekt seine Lebensdauer erreicht hat, aus dem State-Handler entfernen if (this.elapsed > this.duration) { stateMgr.Pop(); } // Wenn der Effekt noch läuft, die Effekt-Zeichenfunktion aufrufen this.Draw();};Trình xử lý hiệu ứng
Phần tiêu đề “Trình xử lý hiệu ứng”Trình xử lý hiệu ứng rất tuyệt vời để lưu trữ và render các hiệu ứng nhỏ hơn, nhẹ hơn cùng nhau. Mỗi hiệu ứng trong handler được đánh giá ở mỗi lần gọi update và bị xóa khi đạt đến cuối vòng đời của nó.
Trình xử lý hiệu ứng chỉ đơn giản là một mảng để lưu trữ các hiệu ứng. Chỉ vậy thôi.
// Effekte-Array deklarierenlet effects = [];
// (Nicht gezeigt) Meter auswerten, Callback-Funktion schiebt Effekt in das Effekte-Arrayeffects.push(new SpecialEffect());
// Durch das Array iterieren und für jeden Effekt einen Frame animierenfor (let i = 0; i < effects.length; i++) { effects[i].draw(); // Effekt entfernen, wenn die Lebensdauer abgelaufen ist if (effects[i].lifetime <= 0) { effects.splice(i, 1); }}CẢNH BÁO: EFFECT vs. STATE
Phần tiêu đề “CẢNH BÁO: EFFECT vs. STATE”State Manager được dành riêng cho các hiệu ứng có độ ưu tiên, có nghĩa là nó phải được ưu tiên khi thực thi. Trong hàm update, hãy xử lý trình xử lý hiệu ứng trước, sau đó xử lý trình xử lý trạng thái. Theo cách này, hiệu ứng trạng thái được vẽ trên các phần tử của trình xử lý hiệu ứng.
Như thế này:
function update(){ // Effect-Handler auswerten for (let i = 0; i < effects.length; i++) { effects[i].draw(); if (effects[i].lifetime <= 0) { effects.splice(i, 1); } }
// DANN State-Handler auswerten stateMgr.Process();}Hướng dẫn chụp dữ liệu USB
Phần tiêu đề “Hướng dẫn chụp dữ liệu USB”Chụp dữ liệu USB là một quá trình đơn giản, nhưng các driver mà các chương trình này sử dụng được biết là gây ra xung đột trên một số hệ thống và đôi khi vô hiệu hóa các cổng USB cho đến khi phần mềm được gỡ bỏ. Giải pháp thông thường là tắt “Secure Boot” trong cài đặt BIOS/UEFI. Trước khi tiếp tục, rất nên có USB với tùy chọn khôi phục hệ thống hoặc khả năng truy cập và quản lý máy tính từ xa không yêu cầu đầu vào người dùng khi khởi động. Điều này quan trọng trong trường hợp tắt Secure Boot không giải quyết được vấn đề và không có cách nào truy cập hệ thống để gỡ cài đặt phần mềm. Trong những trường hợp như vậy, có thể cần làm mới Windows để xóa tất cả các chương trình đã cài đặt trong khi giữ lại các tệp cá nhân. Thực hiện điều này với rủi ro của riêng bạn. Nếu bạn không chắc muốn thử, bạn có thể yêu cầu thêm thiết bị của mình tại đây. Không sử dụng hệ thống laptop cho quá trình này.
Sau khi cài đặt, quá trình rất đơn giản và ghi lại tất cả dữ liệu đi qua các thiết bị USB. Trong khi chụp, đừng nhập thông tin nhạy cảm nếu bạn định chia sẻ dữ liệu, vì các phím bấm được bao gồm trong bản ghi. Hai chương trình bên thứ ba có thể sử dụng là Usblyzer (bản dùng thử miễn phí) và Wireshark (miễn phí). Cả hai đều hoạt động, nhưng với Wireshark hãy chắc chắn chọn USBPcap.
Để biết thêm chi tiết về việc xây dựng Meter callbacks và các hàm hiệu ứng, hãy xem các trang tiếp theo của chúng tôi về Callbacks.