Snippets
Bagian ini mencakup tiga snippet kode yang berguna untuk LightScript Anda: meter, state handler, dan effects handler.
The Meter
Section titled “The Meter”Sebagai kelanjutan dari bagian sebelumnya, kelas Meter dirancang untuk membantu melacak perubahan yang berarti dalam data meter yang tidak stabil. Anggap saja sebagai rem pedal untuk kode Anda - memberikan stabilitas bahkan di zona yang kompleks. Setiap meter menyimpan array nilai yang dapat dikustomisasi yang dikumpulkan selama setiap jalannya fungsi update Anda. Ketika semua nilai dalam array tersebut sama (yaitu, data “stabil”), meter memperbarui nilainya dan memicu fungsi callback yang terhubung untuk mengaktifkan efek.
| Metode | Deskripsi |
|---|---|
| Meter(size, callback) | Konstruktor menerima size dan callback.\n\n\n\nsize - jumlah kali nilai yang identik harus ada agar nilai meter dianggap cukup ‘stabil’ untuk diproses. Nilai lebih tinggi menghasilkan akurasi lebih, nilai lebih rendah menghasilkan latensi lebih rendah.\n\n\ncallback - fungsi yang dipanggil ketika nilai meter stabil dan telah berubah. |
| Meter.setValue(value) | Anda harus memanggil setValue(value) setiap frame, atau kapan pun data mentah baru untuk meter ini tersedia. |
Proses pengumpulan data layar umumnya harus mengikuti struktur ini:
- Nilai engine.vision.meter diperbarui berdasarkan data baru dari layar.
- Di dalam fungsi update, Meter.setValue(engine.vision.meter) dipanggil untuk merekam nilai baru.
- Meter memeriksa array internalnya untuk melihat apakah semua nilai identik. Jika ya, ia memperbarui statusnya sendiri dan menjalankan fungsi callback yang ditugaskan.
- Fungsi callback kemudian mengevaluasi kondisi tertentu menggunakan variabel Meter dan mengeksekusi kodenya jika kondisi tersebut terpenuhi.
CATATAN PENTING:
Jangan lewati penggunaan callback. Karena fungsi update berjalan terus-menerus, ia harus seefisien mungkin. Peran utamanya harus memperbarui nilai Meter. Hindari merantai kondisional dalam update untuk memeriksa meter dan memicu efek, karena ini menyebabkan pemeriksaan yang tidak perlu pada setiap siklus. Sebaliknya, definisikan efek Anda dalam fungsi terpisah dan teruskan ke Meter Anda sebagai callback.
Variabel Meter
Section titled “Variabel Meter”Saat stabil, Meter akan menyediakan beberapa nilai ke fungsi callback-nya:
| Variabel | Deskripsi |
|---|---|
| Meter.value | Nilai meter saat ini. |
| Meter.increased | Boolean yang menunjukkan apakah nilai kita telah meningkat pada update ini |
| Meter.decreased | Boolean yang menunjukkan apakah nilai kita telah menurun pada update ini |
| Meter.diff | Nilai absolut dari perubahan yang dialami meter pada update ini. |
Contoh Meter
Section titled “Contoh Meter”Berikut adalah pengaturan meter tunggal dasar, termasuk kode kelas 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");
// Initialize meter var healthMeter = new Meter(5, healthEffect);
function update(){ // Update Meter values healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Trigger effect } else if (healthMeter.value == 0){ // Trigger effect } else if (healthMeter.diff > .3){ // Trigger effect } }
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) { // Add and shift. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Exit early if we don't have a long-term match. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// We got here, so we've got a matching value collection. Set variables and execute callback. 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");
// Initialize meter var healthMeter = new Meter(5, healthEffect);
function update(){ // Update Meter values healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Trigger effect } else if (healthMeter.value == 0){ // Trigger effect } else if (healthMeter.diff > .3){ // Trigger effect } }
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) { // Add and shift. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Exit early if we don't have a long-term match. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// We got here, so we've got a matching value collection. Set variables and execute callback. 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) { // Add and shift. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Exit early if we don't have a long-term match. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// We got here, so we've got a matching value collection. Set variables and execute callback. 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(); } }; }The State Handler
Section titled “The State Handler”State handler adalah stack efek yang secara khusus menangani efek yang memiliki prioritas di atas semua yang lain. Jika Anda ingin satu animasi besar yang dominan berjalan hingga selesai tanpa gangguan, masukkan ke state handler.
| Metode | Deskripsi |
|---|---|
| StateHandler() | Konstruktor tidak memerlukan argumen. |
| StateHandler.push(new State()) | Anda dapat mendorong status baru ke stack status menggunakan push, dan pemrosesan akan dimulai segera. |
| StateHandler.pop() | Mengeluarkan status saat ini dari stack status, dan mulai memproses status sebelumnya di stack. |
Objek apa pun yang didorong ke state handler harus mengimplementasikan Process(). Fungsi Process menentukan masa hidup efek dalam handler.
Contoh State Handler
Section titled “Contoh State Handler”Berikut adalah state handler dasar, beserta fungsi Process yang harus berjalan di dalam fungsi efek Anda:
var stateHdlr = new StateHandler();
function StateHandler() { var stack = []; var state = null;
// Set current state to the top item in the stack var updateState = function () { if (stack.length > 0) { state = stack[stack.length - 1]; } else { state = null; } };
// Allows dev to add effect to state handler this.Push = function (newState) { stack.push(newState); updateState(); }; // Allows dev to remove effect from handler this.Pop = function () { stack.pop(); updateState(); }; // Call the Process function of the current state (effect) 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 () { // Evaluate time since effect start this.elapsed = new Date.now() - this.start; // If the effect has reached its lifespan, remove it from the state handler if (this.elapsed > this.duration) { stateMgr.Pop(); } // If the effect is still running, call the effect draw function this.Draw();};The Effect Handler
Section titled “The Effect Handler”Effect handler sangat baik untuk menyimpan dan merender efek yang lebih kecil dan lebih ringan secara bersamaan. Setiap efek dalam handler akan dievaluasi pada setiap panggilan update, dan dihapus saat mencapai akhir masa hidupnya.
Effect handler hanyalah sebuah array untuk menyimpan efek. Hanya itu.
// Declare effects arraylet effects = [];
// (Not shown) Evaluate Meter, callback function pushes effect into effects arrayeffects.push(new SpecialEffect());
// Iterate through the array, animating a frame for each effectfor (let i = 0; i < effects.length; i++) { effects[i].draw(); // Remove effect if the lifetime has ended if (effects[i].lifetime <= 0) { effects.splice(i, 1); }}PERINGATAN EFFECT VS. STATE
Section titled “PERINGATAN EFFECT VS. STATE”State manager khusus untuk efek prioritas, yang berarti kita harus memberinya prioritas selama eksekusi. Dalam fungsi update Anda, proses effect handler KEMUDIAN state handler. Ini akan menggambar efek state di atas item effect handler.
Seperti ini:
function update(){ // Evaluate effects handler for (let i = 0; i < effects.length; i++) { effects[i].draw(); if (effects[i].lifetime <= 0) { effects.splice(i, 1); } }
// THEN evaluate state handler stateMgr.Process();}Panduan Tangkapan Data USB
Section titled “Panduan Tangkapan Data USB”Menyimpan data USB adalah proses yang mudah, tetapi driver yang digunakan oleh program-program ini diketahui berkonflik dengan sistem tertentu, terkadang menonaktifkan port USB hingga software dihapus. Solusi umumnya adalah menonaktifkan ‘Secure Boot’ di pengaturan BIOS/UEFI Anda. Sebelum melanjutkan, sangat disarankan untuk memiliki pemulihan sistem yang tersedia di flash drive atau cara untuk mengakses komputer Anda dari jarak jauh yang tidak bergantung pada input pengguna saat booting. Ini penting jika menonaktifkan Secure Boot tidak menyelesaikan masalah dan Anda tidak dapat mengakses sistem untuk menghapus instalasi program. Dalam kasus seperti itu, penyegaran Windows mungkin diperlukan untuk menghapus semua program yang diinstal sambil menjaga file pribadi Anda. Anda melakukan ini dengan risiko Anda sendiri. Jika Anda tidak merasa nyaman mencoba, minta perangkat Anda di sini. Jangan gunakan sistem laptop untuk proses ini.
Setelah diinstal, prosesnya sederhana dan akan menangkap semua data yang melewati perangkat USB Anda. Jangan mengetik informasi sensitif apa pun saat menangkap jika Anda berencana untuk berbagi data, karena penekanan tombol termasuk dalam rekaman. Dua program pihak ketiga yang dapat digunakan adalah Usblyzer (uji coba gratis) dan Wireshark (gratis). Keduanya berfungsi, tetapi jika Anda memilih Wireshark, pastikan USBPcap dipilih.
Lihat halaman berikutnya, Callbacks, untuk lebih detail tentang membuat callback meter dan fungsi efek.