Perchè è un ciclo di gioco “principale” necessaria per lo sviluppo di un gioco?

StackOverflow https://stackoverflow.com/questions/2565677

  •  23-09-2019
  •  | 
  •  

Domanda

Trovo che la maggior parte lo sviluppo di giochi richiede un ciclo di gioco principale, ma non so perché è necessario. Non potremmo implementare un listener di eventi e rispondere ad ogni azione dell'utente? Animazioni (etc.) potrebbero quindi essere riprodotti quando si verifica un evento.

Qual è lo scopo di un ciclo di gioco principale?

È stato utile?

Soluzione

L'argomento che si "bisogno di un ciclo perché altrimenti quello che chiama il listener di eventi" non regge. È vero che su qualsiasi sistema operativo mainstream, si hanno davvero un tale anello, e gli ascoltatori di eventi fare il lavoro in questo modo, ma è del tutto possibile per fare sistema guidato un interrupt che funziona senza loop di qualsiasi tipo.

Ma ancora non si vuole strutturare un gioco in questo modo.

La cosa che rende un loop la soluzione più interessante è che il ciclo diventa ciò che in tempo reale programmazione è indicato come un 'executive ciclica'. L'idea è che è possibile effettuare i tassi di esecuzione relativa delle varie attività del sistema deterministico con l'uno rispetto all'altro. Il tasso complessivo del loop può essere controllato da un timer, e che il timer può in definitiva essere un interrupt, ma con moderni sistemi operativi, è probabile vedere la prova di quell'interrupt come codice che attende un semaforo (o qualche altro meccanismo di sincronizzazione) come parte del "ciclo principale".

Allora perché si vuole un comportamento deterministico? Prendere in considerazione i tassi relativi di elaborazione degli ingressi del vostro utente e i cattivi IA. Se si mette tutto in un sistema puramente evento basato, non c'è alcuna garanzia che l'IA non sarà possibile ottenere più tempo di CPU rispetto l'utente, o viceversa, a meno che non si dispone di un certo controllo sulla priorità dei thread, e anche allora, sei tendono ad avere difficoltà a tenere tempistica coerente.

Mettete il tutto in un ciclo, però, e si garantisce che l'AIS linee temporali stanno per procedere in relazione fissa rispetto al tempo del vostro utente. Questo si ottiene effettuando una chiamata dal tuo ciclo per dare l'IA un timeslice in cui decidere cosa fare, una chiamata fuori per le routine di input utente, per interrogare i dispositivi di input per scoprire come il vostro utente vuole comportarsi, e chiamare a fare il vostro rendering.

Con tale ciclo una, dovete guardare che non si è tenuto un tempo di elaborazione ogni passaggio che in realtà va da in tempo reale. Se stai cercando di ciclo di loop a 100Hz, l'elaborazione di tutto il vostro ciclo era meglio finire in meno di 10 msec, in caso contrario il sistema sta per arrivare a scatti. In programmazione in tempo reale, si chiama sovraccaricare il lasso di tempo. Un buon sistema vi permetterà di monitorare quanto sei vicino a ruota libera, e quindi è possibile ridurre il carico di elaborazione però si vede in forma.

Altri suggerimenti

Un listener di eventi dipende anche qualche invocazione ciclo se si vede o no. Chi altro sta per chiamare l'ascoltatore?

La costruzione di una ciclo di gioco esplicito dà il controllo assoluto su quello che sta succedendo in modo da non dipendere da ciò che alcuni handling library toolkit / evento fa nel suo ciclo di eventi.

Un ciclo di gioco (molto semplificato è il seguente)

initialise
do
     input
     update
     render
loop
clean up

Questo accadrà ogni fotogramma la partita è patta. Quindi, per i giochi che girano a 60fps i sessanta volte sopra viene eseguita ogni secondo.

Questo significa che il gioco senza intoppi, i soggiorni di gioco in sincronia e gli aggiornamenti / pareggi per ciclo capita abbastanza frequentemente. L'animazione è semplicemente un trucco degli occhi, oggetti spostare da un luogo all'altro, ma quando ha giocato abbastanza in fretta sembrano essere in viaggio tra queste posizioni.

Se si dovesse aggiornare solo all'input dell'utente, il gioco sarebbe solo reagito quando l'utente stava fornendo input. Altri componenti di gioco come A.I oggetti del gioco non avrebbero reagito per conto proprio. Un ciclo è quindi il modo più semplice e migliore di aggiornamento di un gioco.

Non è vero che tutti i tipi di giochi richiedono un ciclo di gioco principale dedicato.

Giochi d'azione hanno bisogno di tale ciclo di una causa di aggiornamenti degli oggetti frequenti e la precisione di ingresso del gioco.

D'altra parte, ho implementato un gioco del campo minato e ho usato la finestra
messaggi per le notifiche.

E 'perché i sistemi operativi attuali non sono completamente basata sugli eventi. Anche se le cose sono spesso rappresentati come eventi, avrai ancora per creare un ciclo in cui si attende per il prossimo evento ed elaborare a tempo indeterminato (come ad esempio il ciclo degli eventi di Windows). segnali Unix sono probabilmente la cosa più vicina si arriva a eventi a livello del sistema operativo, ma non sono abbastanza realmente efficace per cose come questa.

In termini pratici, come altre persone hanno indicato, è necessario un ciclo.

Tuttavia, la vostra idea è teoricamente suono. Non si necessità un ciclo. Operazioni necessità basati su eventi.

A un livello semplice, è possibile concettualizzare la CPU di avere un diversi timer;

  • uno incendi sul fronte di salita di 60 Hz e chiede il codice di copiarlo sul video.
  • Un altro potrebbe essere colpa a 60kHz e il rendering essere gli ultimi aggiornamenti degli oggetti nel mondo di gioco nel buffer blitter.
  • Un altro potrebbe essere colpa a 10kHz e prenderanno input da parte dell'utente. (Piuttosto alta risoluzione, lol)
  • Un altro potrebbe essere il gioco 'battito' e zecche a 60MHz; AI e la fisica potrebbero operare in fase di battito cardiaco.

Naturalmente questi timer può essere sintonizzato.

In pratica, che cosa sarebbe accadere è la tua sarebbero (un po 'eliso) in questo modo:

void int_handler1();
//...
int main() 
{ 
  //install interrupt handlers
  //configure settings
  while(1);
}

Qualsiasi programma che può solo stare lì a tempo indeterminato e risponde all'input dell'utente ha bisogno di qualche tipo di ciclo. In caso contrario, sarà solo arrivare alla fine del programma e uscire.

Il ciclo principale chiama il listener di eventi. Se siete abbastanza fortunati da avere un sistema event-driven operativo o gestore di finestre, risiede il ciclo di eventi lì. In caso contrario, si scrive un ciclo principale di mediare il "disadattamento di impedenza" tra un interfacce di sistema di chiamata che si basa su di I / O, poll o select, e un'applicazione tradizionale event-driven.

P.S. Dal momento che si contrassegnati tua domanda con funzionali-programmazione, si potrebbe voler controllare funzionale reattivo di programmazione , che fa un grande lavoro di collegamento astrazioni ad alto livello incaricato di basso livello, le implementazioni basate su eventi.

ha bisogno di un gioco per l'esecuzione in tempo reale , quindi funziona meglio se è in esecuzione su una CPU / core continuamente. Un'applicazione event-driven tipicamente cedere la CPU ad un altro filo quando non c'è nessun evento nella coda. Ci può essere un considerevole attesa prima che la CPU passa di nuovo al vostro processo. In un gioco, questo significherebbe bancarelle brevi e animazioni nervosa.

Due motivi -

sistemi di event-driven Anche di solito hanno bisogno di un ciclo di qualche tipo che legge gli eventi da una coda di qualche tipo e li invia ad un gestore così si finisce con un ciclo di eventi in Windows per esempio, in ogni caso e la potenza era ben estenderla.

Ai fini di animazione avresti bisogno di gestire una sorta di anche per ogni fotogramma dell'animazione. Si potrebbe certamente fare questo con un timer o un qualche tipo di evento di inattività, ma si sarebbe probabilmente finire la creazione di quelli in una sorta di ciclo in ogni caso quindi è solo più facile da usare il loop direttamente.

Sono sistemi che gestire tutti gli eventi che utilizzano visto, hanno un ascoltatore cornice che ascolta un evento spediti all'inizio di ogni fotogramma. Hanno ancora un piccolo ciclo di gioco internamente, ma lo fa poco più di maniglia a finestre eventi di sistema, e creare eventi telaio,

La natura dei giochi è che sono tipicamente simulazioni, e non sono solo reagire basano su eventi esterni, ma sui processi interni pure. Si potrebbe rappresentare questi processi interni da eventi invece di polling ricorrenti, ma sono praticamente equivalenti:

schedule(updateEvent, 33ms)

function updateEvent:
    for monster in game:
        monster.update()
    render()

vs

while 1:
    for monster in game:
        monster.update()
    wait(33ms)
    render()

È interessante notare, pyglet implementa il metodo basato su eventi invece del ciclo più tradizionale. E mentre questo funziona bene un sacco di tempo, a volte provoca problemi di prestazioni o comportamenti imprevedibili causati dalla risoluzione di clock, vsync, etc. Il ciclo è più prevedibile e più facile da capire (a meno che non si arriva da una esclusiva web di programmazione di fondo, forse ).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top