Un thread separato per il loop di gioco è obbligatorio per i giochi semplici?


10

Sono nuovo allo sviluppo del gioco. Per imparare sto ricreando questo gioco su piattaforma Android. Puoi osservare il video di gioco al link sopra. È un gioco semplice.

Ho letto molti articoli su come iniziare con lo sviluppo del gioco. Quasi tutti mi hanno consigliato di utilizzare un loop di gioco su thread separati, il che ha senso per altri giochi. Tuttavia, per questo gioco particolare devo iniziare un thread separato?



Non sono sicuro che si tratti di un duplicato, poiché si tratta di Android. Ci sono alcune altre considerazioni sul threading in una piattaforma basata su Java che sono diverse da quella domanda.
Sean Middleditch,

Risposte:


8

Un loop di gioco è generalmente raccomandato perché è semplice . Quasi tutti i giochi possono essere sviluppati e eseguiti correttamente utilizzando un loop e la maggior parte dei giochi richiederebbe uno per funzionare correttamente.

Ad esempio, la maggior parte dei motori fisici richiede aggiornamenti costanti affidabili per una corretta simulazione. Le animazioni e altri contenuti dinamici e grafici devono essere aggiornati ad ogni modifica, ecc ... Qualcosa che puoi ottenere praticamente gratuito usando un loop.

Ora tieni presente che il tuo loop non deve essere eseguito su un thread separato. In effetti la maggior parte dei giochi eseguirà il loop sul thread principale per semplicità. Anche i miei progetti Android seguono questo principio.

Ora la vera questione è quale alternativa cosa si propone? Se hai un'altra idea su come ottenere input in modo affidabile, fare aggiornamenti e disegnare cornici che funzionano per te, vai avanti! Altrimenti un loop di gioco potrebbe essere il modo più semplice per iniziare.


L'alternativa che sto pensando è quella di aggiornare lo schermo usando il thread principale stesso poiché tutte le azioni sono in serie: il giocatore passa attraverso le palline dello stesso colore, quindi tutte le palline toccate scompaiono, le palline rimanenti cadono sotto gravità insieme alle palline sostitutive.
jin

Quindi non stai chiedendo se è richiesto un loop? La tua preoccupazione principale è se deve essere su un thread separato, giusto?
AturSams

1
corretta. la mia domanda riguarda il thread non il loop. per un gioco così semplice (anche se sarò fortunato a poter creare un gioco del genere) devo generare un nuovo thread o tutto può essere fatto sul thread principale?
jin

1
No, non è necessario. Finché hai un ciclo , non è necessario creare un secondo ciclo .

@jin dovresti davvero cambiare il titolo e come scrivi la tua domanda allora.
Vallentin,

5

No , non è necessario un thread separato. Se non stai facendo nulla di troppo intenso (il che non sembra essere il caso del gioco che ci hai mostrato), tutto può essere fatto sul thread principale.

È necessario un secondo thread se si esegue molta elaborazione o si verificano in altro modo problemi con l'interfaccia utente / input che non rispondono. Ad esempio, nei giochi più complessi, non si desidera che l'interfaccia utente / input non rispondano quando l'IA sta calcolando la sua prossima mossa. Poiché il tuo gioco sembra rispondere principalmente all'input dell'utente e aggiornare gli elementi visivi, non è necessario un secondo thread.


Rispondere alla domanda originale "È richiesto un ciclo".

No , ma le alternative sono più complicate, più difficili da implementare e utilizzate raramente.

I giochi sono per definizione interattivi. Come minimo, è in attesa di input e aggiornamento dell'output. Il modo più semplice per farlo è con un ciclo. Per questo non è necessario generare un nuovo thread.

Anche se il gioco che hai citato sembra semplice, ha immagini e suoni interattivi e aggiorna costantemente quelli basati sull'input dell'utente.

Non ci sono molte alternative a un loop di gioco. Potrebbe essere possibile un qualche tipo di sistema basato su interrupt. Tuttavia, tali sistemi aumentano la complessità e riducono altri fattori come il determinismo. C'è un motivo per cui i loop di gioco sono così comuni, facili da implementare, facili da capire, flessibili e fanno un ottimo lavoro.


L'unica volta che ho riscontrato interruzioni di livello inferiore è stato quando è stata eseguita una determinata attività HW e la CPU / OS doveva essere notificata in modo che potessero elaborarla correttamente (lettura dei dati dal disco in memoria e quindi notifica che è pronta per poter tornare controllare l'applicazione e consentirle di elaborarla), quindi non so cosa intendi e semplicemente l'ho interpretata male.
AturSams

2

Risposta alla domanda effettiva (un loop di gioco deve trovarsi in un thread separato):

Il motivo per cui le persone spesso raccomandano di usare un thread separato è perché non vogliono che l'elaborazione pesante interferisca con l'interattività dell'interfaccia utente. Sei l'unico che può dire se è necessario un thread separato per il tuo gioco. Dipende interamente dal motore e dal framework se il loop di gioco principale nel tuo progetto attuale può interferire con i tempi di risposta dell'interfaccia utente. In genere pensavi che non lo facesse (in piccoli progetti) a meno che tu non abbia un motivo per pensare diversamente.

Un altro motivo per mantenere il codice in thread separati è quello di mantenere il codice modulare e semplice. Avere due pezzi di codice non correlati mescolati insieme può spesso rendere il codice meno leggibile e gestibile a lungo termine.

Un loop di gioco deve essere eseguito sul proprio thread separato? Possibilmente. Se si verifica un problema con il tempo di risposta o il codice e sono necessari più elementi dell'interfaccia utente per rispondere indipendentemente dall'elaborazione pesante o si desidera semplicemente suddividere il codice in attività specifiche che si verificano contemporaneamente per motivi di progettazione, procedere con esso. Tuttavia, è considerata una pratica di programmazione avanzata .

Un esempio semplice ma forse non eccezionale da illustrare è un gioco a due giocatori. Potresti voler eseguire due istanze di una classe che gestisce l'input dell'utente e si converte in cambiamenti di stato nell'istanza del personaggio del giocatore.

Alcuni framework incoraggiano / richiedono l'utilizzo e un sistema basato su eventi / interruzioni come fa ActionScript3.0. In questi casi il codice del loop andrà normalmente OnEnterFrameall'evento o qualcosa di simile che si verifica 20 - 60 o 120 volte al secondo.


Risposta alla domanda originale (ho bisogno di un ciclo principale):

Tutto si riduce al contatore del programma . Se stai realizzando un gioco che durerà più di un periodo di tempo prestabilito e non genererà codice man mano che procede , dovrai richiedere gentilmente al pc del tuo utente di ripetere alcune istruzioni che ha già elaborato e che cosa potrebbe cambiare nel nel frattempo è lo stato (i valori memorizzati negli oggetti e nei globi del gioco).

Poiché sai che dovrai ripetere le istruzioni, esistono diversi modi per completare questa attività ed elaborare continuamente le stesse istruzioni. Tutti questi metodi comportano il ripristino del contatore del programma sull'istruzione attualmente pertinente. Le istruzioni di flusso di controllo più comuni che causano la ripetizione del codice sono chiamate loop, un'altra è l' gotoistruzione che viene raramente utilizzata nel codice moderno e ha un effetto simile in questo caso (completamente non rilevante per te).

Quindi, per rispondere alla tua domanda precedente, hai bisogno di un ciclo? Si.


1
Per quanto ne so, i framework basati sugli eventi, come AS3, hanno ancora un loop di gioco in esecuzione sotto. Sto parlando di interruzioni di livello inferiore, non di un framework che implementa un sistema di eventi.
MichaelHouse

Hmm .. Non penso che la gente usi spesso interruzioni di livello inferiore nei giochi. AFAIK sono principalmente utilizzati dalla CPU per monitorare le operazioni di I / O. Stavo pensando a un'astrazione di livello superiore come una pratica di progettazione in cui si risponde all'input dell'utente o all'attività hardware (senza polling) anziché eseguire diverse istruzioni ogni frame e quindi dire all'HW di rendere il risultato.
AturSams

1
Sì, le persone spesso non li usano più. Come ho detto, sono più difficili da usare e ora abbiamo modi molto migliori di fare le cose. Capisco quello che stai dicendo, ed è certamente un modo diverso di pensare alle cose, ma è solo in superficie che appare diverso, sotto c'è lo stesso tipo di loop.
MichaelHouse

Sono d'accordo con @ Byte56 che si riduce a un ciclo, a meno che non stiamo parlando di eventi a livello di kernel che usano gli interrupt di IO.
concept3d

1
Lo so, ma quasi tutto ciò che facciamo è lo stesso sotto la superficie (come ho detto, cambiando il valore del contatore del programma). Questo non è un segreto e l'ho sottolineato nella risposta. La programmazione basata sugli eventi è apparentemente diversa perché spostiamo il contatore del programma su funzioni diverse quando si verificano eventi diversi. Ovviamente c'è probabilmente un polling circolare per verificare se questi eventi si sono verificati di recente, ma come principio di progettazione è apparentemente diverso.
AturSams

0

Solo per aggiungere alle risposte di alcuni altri qui, qualcosa che nessuno ha esplicitamente menzionato: se corri il rischio di eseguire il tuo loop di gioco in un secondo thread e non risponde, rischi il sistema operativo che termina la tua applicazione. Ecco perché si consiglia di utilizzare un thread separato. Quindi (per esempio) l'NDK native_app_glue.c/ .hgenera un thread separato per il tuo loop.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.