Snippets
Ovaj odeljak sadrži tri korisna isečka koda za LightScripts: Meter, State Handler i Effect Handler.
Kao nastavak prethodnog odeljka, klasa Meter je dizajnirana za praćenje značajnih promena u nestabilnim podacima merača. Funkcioniše kao kočnica za kod — čak i u složenim oblastima osigurava stabilnost. Svaki merač čuva prilagodljivi niz vrednosti prikupljenih na svakom prolazu funkcije update. Kada su sve vrednosti u nizu jednake (tj. podaci su “stabilni”), merač ažurira svoju vrednost i aktivira priloženu callback funkciju za pokretanje efekta.
| Metoda | Opis |
|---|---|
| Meter(size, callback) | Konstruktor prihvata size i callback.\n\n\n\nsize – broj puta koliko identična vrednost mora biti prisutna da bi se vrednost merača smatrala “dovoljno stabilnom” za obradu. Veće vrednosti rezultiraju većom preciznošću, manje vrednosti manjom latencijom.\n\n\ncallback – funkcija koja se poziva kada je vrednost merača stabilna i promenila se. |
| Meter.setValue(value) | setValue(value) treba pozivati svaki frejm ili svaki put kada su dostupni novi sirovi podaci za ovaj merač. |
Proces preuzimanja podataka sa ekrana generalno treba da prati ovu strukturu:
- Vrednost engine.vision.meter se ažurira na osnovu novih podataka sa ekrana.
- Unutar funkcije update, poziva se Meter.setValue(engine.vision.meter) za beleženje nove vrednosti.
- Meter proverava svoj interni niz da li su sve vrednosti identične. Ako jesu, ažurira sopstveno stanje i izvršava dodeljenu callback funkciju.
- Callback funkcija zatim evaluira specifične uslove na osnovu promenljivih Meter-a i izvršava kod kada su ti uslovi ispunjeni.
VAŽNA NAPOMENA:
Ne preskačite callbacks. Budući da funkcija update kontinuirano radi, mora ostati što efikasnija. Njena primarna uloga treba da bude ažuriranje vrednosti Meter-a. Treba izbegavati ulančavanje uslova unutar update za proveru merača i aktiviranje efekata, jer to dovodi do nepotrebnih provera u svakom ciklusu. Umesto toga, definirajte efekte u zasebnim funkcijama i prosleđujte ih kao callbacks u Meter.
Promenljive merača
Section titled “Promenljive merača”Kada je stabilan, merač pruža callback funkciji neke vrednosti:
| Promenljiva | Opis |
|---|---|
| Meter.value | Trenutna vrednost merača. |
| Meter.increased | Boolean koji označava da li je vrednost porasla u ovom ažuriranju |
| Meter.decreased | Boolean koji označava da li je vrednost opala u ovom ažuriranju |
| Meter.diff | Apsolutna vrednost promene koju je merač doživeo u ovom ažuriranju. |
Primer merača
Section titled “Primer merača”Evo jednostavnog podešavanja sa jednim meračem uključujući kod klase 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(); } }; }Handler stanja
Section titled “Handler stanja”Handler stanja je stack efekata koji posebno upravlja efektima koji imaju prioritet nad svima ostalima. Kada treba da se pokrene velika dominantna animacija bez prekida do kraja, ubacuje se u handler stanja.
| Metoda | Opis |
|---|---|
| StateHandler() | Konstruktor ne zahteva argumente. |
| StateHandler.push(new State()) | Push omogućava guranje novog stanja na stack stanja, a obrada počinje odmah. |
| StateHandler.pop() | Uklanja trenutno stanje sa stack-a stanja i počinje obradu prethodnog stanja na stack-u. |
Svaki objekat gurnut u handler stanja mora implementirati Process(). Funkcija Process određuje životni vek efekta u handleru.
Primer handlera stanja
Section titled “Primer handlera stanja”Sledeće prikazuje osnovni handler stanja kao i Process funkciju koja bi trebala da se izvršava unutar funkcija efekata:
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();};Handler efekata
Section titled “Handler efekata”Handler efekata je odličan za zajedničko skladištenje i renderovanje manjih, lakših efekata. Svaki efekat u handleru se evaluira pri svakom pozivu update-a i uklanja kada dostigne kraj svog životnog veka.
Handler efekata je jednostavno niz za čuvanje efekata. To je sve.
// 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); }}UPOZORENJE: EFFECT vs. STATE
Section titled “UPOZORENJE: EFFECT vs. STATE”State Manager je posebno namenjen efektima sa prioritetom, što znači da mu se mora dati prioritet pri izvršavanju. U funkciji update, najpre obradite handler efekata, a zatim handler stanja. Na taj način efekat stanja se crta preko elemenata handlera efekata.
Ovako:
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();}Vodič za snimanje USB podataka
Section titled “Vodič za snimanje USB podataka”Snimanje USB podataka je jednostavan proces, ali drajveri koje ovi programi koriste poznati su po izazivanju konflikata na određenim sistemima i ponekad onemogućavaju USB portove sve dok se softver ne ukloni. Uobičajeno rešenje je onemogućavanje “Secure Boot” u BIOS/UEFI podešavanjima. Pre nastavka, snažno se preporučuje imati USB sa opcijom obnavljanja sistema ili mogućnost daljinskog pristupa i upravljanja računarom koja ne zahteva korisnički unos pri pokretanju. Ovo je važno u slučaju da onemogućavanje Secure Boot-a ne reši problem i nema mogućnosti pristupa sistemu za deinstalaciju programa. U takvim slučajevima može biti potrebno osvežavanje Windows-a za uklanjanje svih instaliranih programa uz zadržavanje ličnih datoteka. Ovo radite na sopstvenu odgovornost. Ako niste sigurni da želite da to isprobate, možete zatražiti dodavanje svog uređaja ovde. Ne koristite laptop sistem za ovaj proces.
Nakon instalacije, proces je jednostavan i snima sve podatke koji prolaze kroz USB uređaje. Tokom snimanja ne unosite osetljive informacije ako planirate da delite podatke, jer su pritisci tastera uključeni u snimanje. Dva programa trećih strana koja se mogu koristiti su Usblyzer (besplatna probna verzija) i Wireshark (besplatno). Oba rade, ali sa Wireshark-om obavezno izaberite USBPcap.
Za više detalja o izgradnji Meter callback-ova i funkcija efekata, pogledajte naše sledeće stranice o Callbacks-ima.