Kodavsnitt
Det här avsnittet innehåller tre användbara kodavsnitt för dina LightScripts: mätare, tillståndshanterare och effekthanterare.
Mätaren
Section titled “Mätaren”Som en fortsättning från föregående avsnitt är Meter-klassen utformad för att hjälpa till att spåra meningsfulla förändringar i instabila mätardata. Tänk på den som ett bromspedalens bromssystem för din kod – den ger stabilitet även i komplexa zoner. Varje mätare håller en anpassningsbar matris med värden som samlats in under varje körning av din update-funktion. När alla värden i den matrisen är desamma (dvs. data är “stabila”) uppdaterar mätaren sitt värde och utlöser en kopplad återanropsfunktion för att aktivera en effekt.
| Metod | Beskrivning |
|---|---|
| Meter(size, callback) | Konstruktorn accepterar både en size och ett callback.\n\n\n\nsize – antalet gånger ett identiskt värde ska vara tillgängligt för att mätarvärdet ska anses vara tillräckligt “stabilt” för att bearbetas. Högre värden resulterar i mer noggrannhet, lägre värden resulterar i mindre latens.\n\n\ncallback – en funktion som anropas när mätarvärdet är stabilt och har förändrats. |
| Meter.setValue(value) | Du bör anropa setValue(value) varje bildruta, eller när som helst ny rådata för den här mätaren är tillgänglig. |
Processen för att samla in skärmdata bör generellt följa den här strukturen:
- Värdet engine.vision.meter uppdateras baserat på nya data från skärmen.
- Inuti update-funktionen anropas Meter.setValue(engine.vision.meter) för att registrera det nya värdet.
- Meter kontrollerar sin interna matris för att se om alla värden är identiska. Om så är fallet uppdaterar den sitt eget tillstånd och kör sin tilldelade återanropsfunktion.
- Återanropsfunktionen utvärderar sedan specifika villkor med hjälp av Meter:ns variabler och kör sin kod om dessa villkor uppfylls.
VIKTIGT:
Hoppa inte över att använda callbacks. Eftersom update-funktionen körs kontinuerligt måste den förbli så effektiv som möjligt. Dess primära roll bör vara att uppdatera Meter-värden. Undvik att kedja villkor i update för att kontrollera mätare och utlösa effekter, eftersom detta leder till onödiga kontroller vid varje cykel. Definiera istället dina effekter i separata funktioner och skicka in dem i din Meter som callbacks.
Mätarvariabler
Section titled “Mätarvariabler”När den är stabil ger Meter ett par värden till sin återanropsfunktion:
| Variabler | Beskrivning |
|---|---|
| Meter.value | Mätarens aktuella värde. |
| Meter.increased | Ett booleskt värde som indikerar om vårt värde har ökat vid den här uppdateringen |
| Meter.decreased | Ett booleskt värde som indikerar om vårt värde har minskat vid den här uppdateringen |
| Meter.diff | Det absoluta värdet av förändringen som mätaren har genomgått vid den här uppdateringen. |
Mätarexempel
Section titled “Mätarexempel”Här är en grundläggande enkelmätarkonfiguration, inklusive Meter-klasskoden:
<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");
// Initiera mätare var healthMeter = new Meter(5, healthEffect);
function update(){ // Uppdatera Meter-värden healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Utlös effekt } else if (healthMeter.value == 0){ // Utlös effekt } else if (healthMeter.diff > .3){ // Utlös effekt } }
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) { // Lägg till och skifta. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Avsluta tidigt om vi inte har en långsiktig matchning. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Vi kom hit, så vi har en matchande värdesamling. Ange variabler och kör 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");
// Initiera mätare var healthMeter = new Meter(5, healthEffect);
function update(){ // Uppdatera Meter-värden healthMeter.setValue(engine.vision.health);
window.requestAnimationFrame(update); }
function healthEffect(){ if(healthMeter.increased){ // Utlös effekt } else if (healthMeter.value == 0){ // Utlös effekt } else if (healthMeter.diff > .3){ // Utlös effekt } }
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) { // Lägg till och skifta. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Avsluta tidigt om vi inte har en långsiktig matchning. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Vi kom hit, så vi har en matchande värdesamling. Ange variabler och kör 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) { // Lägg till och skifta. values.push(updatedValue); if (values.length > this.size) { values.shift(); }
// Avsluta tidigt om vi inte har en långsiktig matchning. for (var i = 0; i < values.length - 1; i++) { if (values[i] !== values[i + 1]) return; }
// Vi kom hit, så vi har en matchande värdesamling. Ange variabler och kör 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(); } }; }Tillståndshanteraren
Section titled “Tillståndshanteraren”Tillståndshanteraren är en effektstack som specifikt hanterar effekter som har prioritet framför alla andra. Om du vill att en stor dominant animation ska köra tills den är klar utan avbrott, lägg in den i tillståndshanteraren.
| Metod | Beskrivning |
|---|---|
| StateHandler() | Konstruktorn kräver inga argument. |
| StateHandler.push(new State()) | Du kan skjuta in ett nytt tillstånd på tillståndssteget med push, och bearbetning börjar omedelbart. |
| StateHandler.pop() | Tar bort det aktuella tillståndet från tillståndssteget och börjar bearbeta det föregående tillståndet. |
Alla objekt som skjuts in i tillståndshanteraren måste implementera Process(). Process-funktionen bestämmer livslängden för en effekt i hanteraren.
Tillståndshanterarexempel
Section titled “Tillståndshanterarexempel”Följande visar en grundläggande tillståndshanterare, plus Process-funktionen som ska köras inuti dina effektfunktioner:
var stateHdlr = new StateHandler();
function StateHandler() { var stack = []; var state = null;
// Sätt aktuellt tillstånd till det översta elementet i steget var updateState = function () { if (stack.length > 0) { state = stack[stack.length - 1]; } else { state = null; } };
// Låter utvecklaren lägga till effekt i tillståndshanteraren this.Push = function (newState) { stack.push(newState); updateState(); }; // Låter utvecklaren ta bort effekt från hanteraren this.Pop = function () { stack.pop(); updateState(); }; // Anropa Process-funktionen för det aktuella tillståndet (effekten) 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 () { // Utvärdera tid sedan effekten startade this.elapsed = new Date.now() - this.start; // Om effekten har nått sin livslängd, ta bort den från tillståndshanteraren if (this.elapsed > this.duration) { stateMgr.Pop(); } // Om effekten fortfarande körs, anropa effektens draw-funktion this.Draw();};Effekthanteraren
Section titled “Effekthanteraren”Effekthanterare är utmärkta för att lagra och rendera mindre, lättare effekter tillsammans. Varje effekt i hanteraren utvärderas vid varje update-anrop och de tas bort när de når slutet av sin livslängd.
Effekthanteraren är bara en matris för att lagra effekter. Det är allt.
// Deklarera effektmatrislet effects = [];
// (Visas inte) Utvärdera Meter, återanropsfunktion lägger in effekt i effektmatriseneffects.push(new SpecialEffect());
// Iterera genom matrisen och animera en bildruta för varje effektfor (let i = 0; i < effects.length; i++) { effects[i].draw(); // Ta bort effekt om livslängden har avslutats if (effects[i].lifetime <= 0) { effects.splice(i, 1); }}VARNING: EFFEKT vs. TILLSTÅND
Section titled “VARNING: EFFEKT vs. TILLSTÅND”Tillståndshanteraren är specifikt för prioritetseffekter, vilket innebär att vi måste ge den prioritet under körning. I din update-funktion, bearbeta effekthanteraren SEDAN tillståndshanteraren. Det ritar tillståndseffekten ovanpå effekthanterarens element.
Såhär:
function update(){ // Utvärdera effekthanterare for (let i = 0; i < effects.length; i++) { effects[i].draw(); if (effects[i].lifetime <= 0) { effects.splice(i, 1); } }
// SEDAN utvärdera tillståndshanterare stateMgr.Process();}Guide för USB-datainspelning
Section titled “Guide för USB-datainspelning”Att spara USB-data är en enkel process, men drivrutinerna som används av dessa program är kända för att konflikta med vissa system och ibland inaktivera USB-portar tills programvaran tas bort. Den vanliga lösningen är att inaktivera “Secure Boot” i dina BIOS/UEFI-inställningar. Innan du fortsätter rekommenderas starkt att ha en systemåterställning tillgänglig på ett USB-minne eller ett sätt att fjärransluta till datorn som inte förlitar sig på användarinmatning vid uppstart. Det är viktigt om inaktivering av Secure Boot inte löser problemet och du inte kan komma åt systemet för att avinstallera programmet. I sådana fall kan en Windows-uppdatering vara nödvändig för att ta bort alla installerade program men bevara dina personliga filer. Du gör det här på egen risk. Om du inte känner dig bekväm med att försöka, begär din enhet här. Använd inte ett bärbardatorsystem för den här processen.
När det är installerat är processen enkel och fångar alla data som passerar genom dina USB-enheter. Skriv inte in någon känslig information under inspelning om du planerar att dela data, eftersom tangenttryckningar ingår i inspelningen. Två tredjepartsprogram som kan användas är Usblyzer (gratis provperiod) och Wireshark (gratis). Båda fungerar, men om du väljer Wireshark, se till att USBPcap är valt.
Kolla in vår nästa sida, Callbacks, för mer detaljer om att konstruera mätarcallbacks och effektfunktioner.