Så skiljer du mellan viloläge och interaktivt läge i en virtuell husdjurs spelloop
I ett virtuellt husdjursspel bör autonoma beteenden och spelarhandlingar hanteras i separata uppdateringsflöden. Låt sedan båda ändra husdjurets gemensamma tillstånd genom uttryckliga övergångar. Vilobeteenden bör fortskrida utifrån förfluten tid. Interaktiva beteenden bör reagera på inmatningshändelser eller aktuellt inmatningstillstånd. Det gör det enklare att pausa och testa, och förhindrar att en husdjursanimation eller behovstimer konkurrerar med ett spelarval.
Definiera vad ”viloläge” och ”interaktivt läge” innebär
Se dem som beteendelägen, inte nödvändigtvis som olika scener eller separata loopar. I viloläge följer husdjuret sina rutiner: väljer en liten omgivningsaktivitet, låter en timer fortskrida eller spelar upp en animation som inte är nödvändig. I interaktivt läge hanterar spelet en avsiktlig handling, till exempel ett tryck, en dragning eller ett valt kommando. Husdjuret kan fortfarande animera under en interaktion. Skillnaden handlar om vilket system som får fatta beslut och ändra spelets tillstånd.
Börja med en kort lista över handlingar som spelaren kan utföra och beteenden som husdjuret kan utföra autonomt. Markera vilka tillståndsvariabler varje handling får ändra. En omgivande blinkning kan till exempel bara påverka presentationen, medan en vald lekaktivitet kan ändra husdjurets pågående aktivitet och starta en timer. Den här enkla översikten över ansvar hjälper dig att upptäcka konflikter innan koden växer.
Håll den yttre loopen fristående från husdjurets beteenden
Spelmotorns bildruteanrop bör samordna arbetet, inte innehålla alla regler för husdjuret. En användbar ordning är att samla in inmatning, tillämpa giltiga kommandon, uppdatera simuleringen och sedan rendera det senaste tillståndet. Håll insamlingen av inmatning åtskild från simuleringen, så att ett tryck inte av misstag behandlas som ett timersteg. Låt också renderingen vara fri från speländringar. Game Programming Patterns beskriver den här uppdelningen som att hantera inmatning, uppdatera spelet och rendera i en upprepande loop. Uppdateringar med fasta steg är användbara när simuleringen behöver ett stabilt intervall. Game Loop, Game Programming Patterns
I ett webbläsarspel schemalägger requestAnimationFrame arbete före omritning och tillhandahåller en tidsstämpel som du kan använda för att mäta förfluten tid. Webbläsare pausar i allmänhet dessa anrop i dolda flikar, så räkna inte med att de fortsätter fungera som en tillförlitlig väggklocka när spelet körs i bakgrunden. Window.requestAnimationFrame(), MDN
Hantera spelarens inmatning via kommandon
Omvandla rå inmatning till ett enkelt kommando, till exempel start_play, stop_play eller pet_tap. En kommandohanterare kontrollerar om handlingen är giltig i det aktuella läget, uppdaterar den delade modellen en gång och skickar ut eventuella presentationssignaler som blir resultatet. Då slipper du lägga handlingslogik i knappåteranrop, animationsåteranrop och vilorutinen samtidigt.
Om spelaren till exempel trycker när husdjuret redan leker bör du bestämma vad som ska hända: ignorera trycket, välja en annan aktivitet eller avbryta den pågående aktiviteten. Låt inte både viloväljaren och tryckhanteraren tilldela en ny aktivitet under samma uppdatering. I spelmotorer med händelsespridning bör du hantera spelinmatning i rätt steg och respektera när gränssnittet tar hand om inmatningen. I Godots dokumentation om Node står det att ohanterad inmatning vanligtvis passar bättre för spelhantering när GUI-kontroller ska ha företräde. Node class, Godot documentation
Låt vilotiden fortskrida med en tydlig klocka
För beteenden som ska fortskrida kontinuerligt under en synlig spelsession kan du samla på förfluten simuleringstid och fatta ett beslut i viloläget när intervallet nås. Räkna inte bildrutor: bildrutefrekvensen varierar. I Godot får _process(delta) tiden sedan föregående bildruta i viloläget, medan _physics_process(delta) följer fysiktick. Dokumentationen påpekar också att ackumulerad delta-tid under vissa omständigheter kan avvika från verkliga sekunder. Node class, Godot documentation
Välj klocka efter beteendet. Kosmetiska rörelser kan oftast använda förfluten bildrutetid. Rörelser som påverkar kollisioner hör hemma i spelmotorns fysikuppdatering. En timer för att husdjuret ska ”välja en omgivningsaktivitet med några sekunders mellanrum” kan använda en simuleringstimer, men bestäm vad som ska hända efter en lång bildruta eller paus: begränsa den förflutna tiden, fatta ett enda beslut eller ta igen tiden i begränsade steg. Obegränsad ikappkörning kan få husdjuret att hoppa genom många tillstånd när spelet återupptas.
Gör övergångar mellan lägen uttryckliga
Skriv ned en liten övergångstabell innan du lägger till fler tillstånd. Till exempel startar idle → playing en aktivitet som spelaren valt. playing → idle inträffar när aktiviteten avslutas eller spelaren avbryter den. idle → resting kan väljas av den autonoma rutinen. Definiera vad som händer vid in- och utträde på ett ställe, till exempel att starta eller rensa en timer och välja relevant animation. Använd inte enbart animationens slut som bevis på att spelläget har ändrats: den visuella uppspelningen kan avbrytas eller hoppas över.
En övergångsfunktion bör validera det aktuella läget, uppdatera modellen och returnera ett resultat som renderaren kan visa. Då hålls ”vad husdjuret gör” åtskilt från ”hur handlingen visas”. Det ger också testerna ett tydligt mål: skicka ett kommando, kontrollera det resulterande läget och verifiera sedan att vilorutinen inte längre skriver över det.
Bestäm hur tid i bakgrunden ska fungera
Det finns två vanliga principer, och vilken som passar beror på spelets utformning. Ett husdjur som bara finns under spelsessionen kan låta simuleringen stanna när den pausas och återuppta den från det tidigare tillståndet. Ett spel som ska låta timers fortskrida medan det är stängt måste spara en tidsreferens och beräkna den förflutna tiden när spelaren kommer tillbaka. Hantera det som en separat återupptagningsberäkning i stället för att försöka köra bildruteloopen i bakgrunden. Webbläsare kan pausa animationsanrop i dolda flikar. Window.requestAnimationFrame(), MDN
För ett enkelt husdjur bör du bara räkna om de värden som verkligen ska fortskrida – kanske en timer för en aktivitet – och sätta en rimlig övre gräns för ikappkörningen. Testa sedan att stänga och öppna spelet igen efter både kort och lång tid. Valet av klocka, hur pauser hanteras och gränsen för ikappkörning är designbeslut. Spelmotorns bildruteanrop fattar dem inte åt dig.
Kontrollera att uppdateringar inte konkurrerar och att inmatning inte missas
Testa loopen med några scenarier som går att upprepa: låt spelet vara i viloläge under flera intervall, skicka ett kommando strax före ett beslut i viloläget, håll in eller upprepa en inmatning, pausa och återuppta, och starta en ny handling medan en animation fortfarande spelas upp. Kontrollera att varje kommando ändrar modellen en gång, att vilologiken inte ersätter ett tillstånd som spelaren valt och att den förflutna tiden hanteras enligt den valda pausprincipen.
Om du använder en uppdatering med fasta steg för simuleringen, tänk på att den kan köras noll, en eller flera gånger mellan renderade bildrutor. Unity beskriver detta beteende för FixedUpdate och rekommenderar det för fysikberäkningar. Inmatning och visuella uppdateringar har andra tidskrav. FixedUpdate(), Unity documentation Unitys Input System köar också enhetshändelser och behandlar dem enligt det konfigurerade uppdateringsläget. Anpassa därför hanteringen av inmatning till den loop som använder kommandona. Input event queue, Unity Input System
En praktisk uppdelning att behålla
Håll arkitekturen liten: en delad husdjursmodell, en väg från inmatning till kommando, en uppdatering för vilobeteenden, en uttrycklig övergångsfunktion och en renderare som läser modellen. Lägg bara till ett simuleringssteg med fast intervall när tidskänsliga beteenden behöver det. Låt inte varje animation eller omgivningsaktivitet vara beroende av fysiktick. När en bugg uppstår kan du undersöka vem som senast ändrade läget och vilken klocka som drev uppdateringen. Då får varje uppdatering en tydlig uppgift, och viloläge och interaktivt läge förblir förutsägbara när husdjuret får fler handlingar.
