Lewati ke konten

Snippets

Bagian ini mencakup tiga snippet kode yang berguna untuk LightScript Anda: meter, state handler, dan effects handler.

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.

MetodeDeskripsi
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:

  1. Nilai engine.vision.meter diperbarui berdasarkan data baru dari layar.
  2. Di dalam fungsi update, Meter.setValue(engine.vision.meter) dipanggil untuk merekam nilai baru.
  3. Meter memeriksa array internalnya untuk melihat apakah semua nilai identik. Jika ya, ia memperbarui statusnya sendiri dan menjalankan fungsi callback yang ditugaskan.
  4. 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.

Saat stabil, Meter akan menyediakan beberapa nilai ke fungsi callback-nya:

VariabelDeskripsi
Meter.valueNilai meter saat ini.
Meter.increasedBoolean yang menunjukkan apakah nilai kita telah meningkat pada update ini
Meter.decreasedBoolean yang menunjukkan apakah nilai kita telah menurun pada update ini
Meter.diffNilai absolut dari perubahan yang dialami meter pada update ini.

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();
}
};
}

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.

MetodeDeskripsi
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.

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();
};

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 array
let effects = [];
// (Not shown) Evaluate Meter, callback function pushes effect into effects array
effects.push(new SpecialEffect());
// Iterate through the array, animating a frame for each effect
for (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);
}
}

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();
}

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.