Capire il Game Loop - Basix

Quasi tutti i giochi possono essere pensati come aventi una funzione principale che contiene tutta la logica di gioco e che viene eseguita quando l'utente fa qualcosa o dopo un certo periodo di tempo. Questo ciclo di esecuzione della stessa funzione di core più e più volte è chiamato il ciclo di gioco, ed è fondamentale per capire per qualsiasi tipo di sviluppo del gioco.

Probabilmente hai giocato al gioco da tavolo Chutes and Ladders (o Snakes and Ladders come lo chiamiamo nel Regno Unito).

(Photo credit incurable_hippie su Flickr)

Ogni giocatore tira il dado (o fa girare la ruota) e sposta in avanti il ​​numero di caselle indicato. Il quadrato su cui atterrano può indurli a scivolare all'indietro oa scalare in avanti diversi spazi. Il giocatore vince la partita quando arriva al quadrato finale.

Quindi, nell'immagine sopra, l'atterraggio su Square 6 ti fa salire quattro quadrati fino a Square 10; atterrare su Square 19 ti fa scivolare indietro di 15 quadrati fino a Square 4; e atterrando su Square 64 significa che vinci la partita.

Supponiamo ora che tu stia giocando a giocatore singolo, per esercitarti. Fai la stessa cosa di sopra, più e più volte, fino a raggiungere Square 64. Come si rappresenterebbe questo in codice?

Probabilmente inizierai creando una matrice per memorizzare i valori dei quadrati. La maggior parte degli elementi contiene zero, ma alcuni contengono un numero positivo (che indica una scala) o un numero negativo:

Nota: Questo è pseudocodice, non AS3

 var specialSquares: Array = []; specialSquares [0] = 0; // il quadrato in cui i giocatori iniziano, prima di 1Squares [1] = 0 ;? specialSquares [6] = +4 ;? specialSquares [19] = -15;

? e così via. Quindi, avresti una funzione per spostare il giocatore in base al numero sul dado:

 function movePlayer (squares: Number) newSquare = currentSquare + squares; newSquare + = specialSquares [newSquare]; currentSquare = newSquare; 

Potresti quindi inserirlo all'interno di una funzione più grande che rappresenta un intero turno:

 function takeATurn () diceNumero = casuale (1, 6); // numero casuale compreso tra 1 e 6 movePlayer (diceNumber); if (currentSquare == 64) // player ha vinto! gioco finito  

Questa funzione, Svolta(), incapsula la logica del gioco di base per scivoli e scale a giocatore singolo. Ma come facciamo a far funzionare questa funzione? Ci sono diverse opzioni:


Esegui la funzione in base all'ingresso del lettore

Potremmo posizionare un pulsante sullo schermo e chiamarlo Svolta() ogni volta che viene cliccato. Se hai mai giocato a Facebook Scrabble o Words With Friends, hai visto questa opzione in azione.


Esegui la funzione in base al tempo trascorso

Potremmo fare Svolta() correre ogni sessanta secondi.

In realtà, questa opzione è un po 'più complicata di quanto possa sembrare. In pratica non vediamo mai giochi senza alcuni input del giocatore; senza interazione, non può davvero essere considerato un gioco. Tuttavia, alcuni giochi hanno un elemento di "calendario" coinvolto. Considera FarmVille: tu, il giocatore, pianta le tue colture, e poi ogni pochi minuti (o ore) si sviluppano un po 'oltre, dai semi ai germogli alla frutta. E in alcune modalità di Civilization, ti viene data una certa quantità di tempo (diciamo cinque minuti) per fare tutte le tue mosse per un "turno"; una volta che questi cinque minuti sono scaduti, viene attivata la funzione logica di gioco principale.


Fai entrambi

Alcuni giochi usano una combinazione di queste due opzioni: ad esempio, Mafia Wars ha una risorsa chiamata "energia" che ricarica una unità ogni cinque minuti; tu fai azioni nel gioco usando questa risorsa, quindi la funzione di base del gioco è ancora attivata da un'azione dell'utente, è solo limitata dal tempo.

Questo è uno schema comune alla maggior parte dei giochi: un pezzo di codice contenente la logica del gioco di base viene attivato ripetutamente. Lo chiamiamo il ciclo di gioco.

Esiste un termine per l'azione o il periodo di tempo che attiva anche il codice di logica del gioco principale: a zecca (come il suono che fa un orologio).

Quindi, in Civilization, il segno di spunta è ogni cinque minuti. In Words With Friends, giocando il tuo turno cause un segno di spunta. In altre parole, il ciclo di gioco viene eseguito una volta per tick.


Che dire di Mario?

Super Mario Bros non sembra adattarsi a nessuna di queste categorie. Mario risponde all'input del giocatore? eppure ogni sorta di cose vanno avanti senza che tu debba fare nulla (i Goomba vanno in giro, il timer conta alla rovescia, gli oggetti cadono). Ci sono Due loop di gioco?

No. Ce n'è solo uno, ed è attivato solo dal tempo, ma con un tick di appena una frazione di secondo.

In Civilization, hai un periodo di cinque minuti per inserire tutto ciò che vuoi fare nel turno corrente, prima che il gioco "torni" e ricominci di nuovo il ciclo di gioco sulla base di tutti i tuoi input. Quindi, se tu dici, alla curva 23, che vuoi che i tuoi guerrieri attaccino un cervo, alla 24a volta tutti prendono una cervo per cena.

È lo stesso con Mario. Se premi il pulsante Salta durante un segno di spunta, quindi nella prossima iterazione del ciclo di gioco, Mario inizierà a saltare.

Nota che tu non devi fare in modo che la tua pressione di Jump si verifichi proprio mentre viene attivata la funzione di base del gioco logico: tutte le tue azioni durante un periodo di tick vengono registrate e utilizzate durante la successiva iterazione del loop di gioco.


È Qualunque cosa Controllato attraverso il gioco?

Tutta la logica di gioco viene gestita nel ciclo di gioco. Ma c'è di più in un gioco che nella sua logica, la grafica ne è l'esempio principale.

Disegnare grafica sullo schermo è un duro lavoro per il computer. Supponiamo che tu abbia un gioco d'azione con un tick di 1/60 di secondo; questo dovrebbe rendere il gioco come se reagisse fluidamente ai controlli del giocatore. Ma cosa succede se il computer del giocatore è troppo lento per eseguire tutto il codice per la logica di gioco (rispondendo all'input, simulando la gravità, eseguendo le routine AI) e Disegna tutto sullo schermo entro 1/60 di secondo?

In questo scenario, possiamo usare due circuiti separati: un ciclo di gioco e un disegnare il ciclo. Potremmo quindi eseguire il ciclo di estrazione a una frequenza molto più bassa rispetto al loop di gioco; diciamo che aggiorniamo lo schermo a metà spesso, cioè ogni 1/30 di secondo.

La quantità di potenza di elaborazione richiesta dal gioco può variare da un livello all'altro. Considera uno sparatutto: i primi livelli avranno pochissime navi sullo schermo, per facilitare il giocatore con delicatezza, mentre gli ultimi livelli potrebbero avere dozzine di navi nemiche e centinaia di proiettili che volano intorno alla stessa scena a una volta. Il loop del gioco deve capire come tutti quegli oggetti dovrebbero muoversi, e il ciclo di draw deve renderizzare ognuno, quindi mentre potrebbe essere stato possibile eseguire sia il loop di gioco che il ciclo di draw ogni 1 / 60th di secondo al inizio del gioco, alla fine qualcosa deve dare.

In genere è più semplice rallentare il ciclo di estrazione rispetto al ciclo di gioco, se devi scegliere. Regolare la lunghezza del tick del loop di gioco significa regolare tutto nel tuo gioco basato sul tempo; se Mario corre ad una velocità di 20 pixel / secondo, e si progetta il gioco con una lunghezza del tick di 1/60 di secondo, allora devi spostarlo di 1/3 di pixel per tick. Se regoli il loop del gioco per avere una lunghezza del tick di 1/30 di secondo, devi aggiustarlo a 2/3 di pixel per tick e anche questo è un semplice cambiamento rispetto al mantenimento dei calcoli fisici e delle routine di intelligenza artificiale coerente.

Per questo motivo, i giochi spesso mirano a mantenere costante il tick del circuito di gioco e rallentano il ciclo di draw se è necessaria più potenza. Se hai attivato il contatore FPS (abbreviazione di Frames Per Second, il numero di volte in cui il ciclo di disegno è in esecuzione al secondo) in uno sparatutto in prima persona, lo avrai visto cambiare a seconda di quanto è sullo schermo ; la frequenza di aggiornamento del ciclo di disegno viene regolata automaticamente. Il gioco può sembrare strano - come un video live streaming su una connessione internet lenta - ma a meno che non sia eseguito su un computer con molta meno potenza di quanto gli sviluppatori del gioco avessero in mente, tutti gli oggetti nel mondo di gioco continueranno a muoviti e interagisci alla velocità corretta.

Per un grande articolo che spiega come Flash si occupa di questo, controlla il post di Sean Christmann sull '"Elastic Racetrack".