Sprites come attori


12

Non ho esperienza nelle domande sullo sviluppo del gioco, ma come programmatore. Nella lingua Scala, puoi avere un multitasking scalabile con gli attori, molto stabile, come ho sentito. Puoi persino avere centinaia di migliaia di loro in esecuzione contemporaneamente senza problemi.

Quindi ho pensato, forse puoi usarli come classe base per 2D-Sprite, per uscire dalla cosa del loop di gioco che richiede di passare attraverso tutti gli sprite e spostarli. Si sarebbero sostanzialmente mossi, guidati dagli eventi.

Avrebbe senso per un gioco? Avendolo multitasking in quel modo? Dopotutto, funzionerà su JVM, anche se al giorno d'oggi non dovrebbe essere un grosso problema.

MODIFICARE:

Dopo essermi dilettato per un po ', ho notato che esiste solo un vero vantaggio in questa idea: il supporto multicore. Un semplice loop di gioco verrà eseguito su un solo core e funzionerà in modo sequenziale su tutto.

Poiché i computer moderni, anche a casa, al giorno d'oggi hanno due o più core integrati, penso che sia una buona idea consentire ai programmatori di giochi di utilizzare in modo efficiente gli altri core. Dopotutto, penso che di solito il giocatore avrà solo il gioco in esecuzione sulla sua macchina a otto core, quindi perché no.

L'altro vantaggio che vedo è che in Scala puoi avere RemoteActors, che può essere trattato allo stesso modo ma può essere eseguito su un altro computer. Quindi forse questo può semplificare anche i giochi in rete.

Ho intenzione di incorporarlo nel mio motore Scala 2D non appena posso.


Sarei molto interessato a sapere come andrà a finire. Ho guardato Scala un paio di volte ma non mi sono mai tuffato prima.
Davy8,

Molti sosterrebbero che per un esplicito supporto multi-core, stai meglio con i thread piuttosto che con i processi (e con i processi modello degli attori Scala). Questo perché puoi sfruttare la memoria condivisa tra i thread. Naturalmente, ciò è soggetto a errori in modi in cui il modello di attore non lo è.
Kylotan,

Gli attori Scala sono multiplati su un pool di thread, in modo che possano essere più leggeri dei thread. Ciò significa che possono manipolare la memoria condivisa per comunicare, a condizione che sia sincronizzata correttamente. Se usi attori remoti, potrebbero essere su processi diversi e l'unico modo per comunicare è l'invio di messaggi.
axel22,

Risposte:


7

Non ci ho provato, ma sono un programmatore della Scala e direi che questo non è l'approccio migliore. Gli sprite devono essere animati in modo sincrono. Gli attori non hanno alcuna garanzia che saranno eseguiti in modo equo: alcuni sprite potrebbero quindi essere più veloci di altri, il che non è quello che vuoi. Potresti voler usare una barriera per sincronizzarli, ma poi - perché usare gli attori. Se fai affidamento solo sul passaggio dei messaggi, l'implementazione di questo tipo di sincronizzazione (implementazione di una barriera per oltre 1000 attori) è eccessiva.

Un altro problema è: per cosa useresti il ​​passaggio dei messaggi? Hai bisogno dei tuoi sprite per comunicare? Potresti inviare un messaggio dall'attore principale, dicendo a ogni sprite di passare al fotogramma successivo, ma in termini di prestazioni, questo è magnitudini e magnitudini più che invocare metodi direttamente e iterare attraverso una serie di sprite.

Mi sembra che ciò di cui hai bisogno qui sia una specie di multitasking molto leggero, e nessun messaggio che passi affatto. L'implementazione della tua implementazione simile ad un attore che garantisce l'equità è probabilmente il modo migliore se vuoi assicurarti questo, ma è troppo lavoro per un guadagno troppo piccolo. Un'altra cosa da guardare è la programmazione reattiva funzionale e scala.react, credo, sia una corrispondenza migliore per questo caso d'uso.

Ho implementato un motore di gioco isometrico 2d in Scala. Ho usato solo 1 attore globale per aggiornare gli sprite visibili che erano animati.

Potresti voler implementare la tua logica di gioco usando attori - ad esempio, per distribuire calcoli su diverse parti della tua mappa di gioco a attori diversi, in modo che aggiornino lo stato del gioco in parallelo - e ottenere un miglioramento delle prestazioni. Non userei un singolo attore per oggetto di gioco, piuttosto un attore per regione. Se vai troppo bene, le prestazioni ne risentono.

Tuttavia, se fossi in te, lo proverei, solo per vedere cosa succede.


1

Quindi ho pensato, forse puoi usarli come classe base per 2D-Sprite, per uscire dalla cosa del loop di gioco che richiede di passare attraverso tutti gli sprite e spostarli. Si sarebbero sostanzialmente mossi, guidati dagli eventi.

Quale sarebbe l'evento che li muove?

Sarebbe un evento che emetti una volta per frame?

E se è così, come ha cambiato il sistema in qualche modo pratico?

Quando studiavo originariamente l'orientamento agli oggetti nel contesto del C ++, ho appreso che ad alcune persone piaceva pensare a un'affermazione come xyz.doThis(x)il significato "invia il doThis messaggio a xyz (con payload di x) e aspetta una risposta immediata". Se visto a questo livello, non c'è alcuna differenza intrinseca tra un sistema basato su eventi o messaggi e un normale procedimento.


Gli attori sono una soluzione multi-thread. Le comunicazioni non sono sincrone. Gli attori Scala (concept di Erlang) consentono una facile programmazione multi core.
Ellis

Hai un punto lì, ma la differenza qui sarebbe che lo sprite basato sull'attore non blocca il loop del gioco durante l'esecuzione dell'azione, mentre l'approccio metodologico attende fino al xyz.doThis(x)termine. Penso che questo potrebbe anche aiutare a rendere la logica di gioco più veloce, specialmente su sistemi multi-core.
Lanbo

Semplifica la distribuzione della gestione delle entità su più core, vero. Ma il costo di ciò è che non puoi facilmente riferirti da un attore all'altro senza messaggi aggiuntivi o dati aggiuntivi inviati nei messaggi. Quindi ti rendi presto conto che l'approccio ingenuo qui non ti aiuta - puoi formulare un modo basato sull'attore di eseguire gli aggiornamenti?
Kylotan,

Attualmente, sto sperimentando un qualche tipo di aggiornamento distribuito: i miei attori sono come nodi in una struttura ad albero, e aggiornando gli aggiornamenti di root dei bambini, mediante distribuzione dei messaggi. Inoltre, il vero vantaggio sarà il networking: in Scala, un attore e un RemoteActor (attore su un altro sistema) possono essere indirizzati allo stesso modo, con gli stessi messaggi.
Lanbo

Sì, ma il problema non è l'attivazione dell'aggiornamento in quanto tale, è garantire al destinatario del messaggio tutte le informazioni necessarie per agire su di esso.
Kylotan,

0

È un approccio interessante al pensiero di aggiornare gli oggetti di gioco. Non conosco Scala, ma dico di provarci e vedere come va a finire, e ancora meglio pubblicare i tuoi risultati!

Le domande principali che mi vengono in mente sono: come gestisci la frequenza con cui alcuni oggetti di gioco si aggiornano rispetto ad altri? Dovrai preoccuparti che gli attori dello sprite eseguano troppi cicli in modo tale che il sistema di rendering non abbia il tempo di disegnare un fotogramma ogni 1/60 | 30 | | 24 di secondo?

Un'altra cosa da considerare è come ciò influenzerà la risoluzione delle interazioni giocatore contro AI che si basano sull'ordine di una sequenza di eventi molto rapidi. A seconda del tipo di gioco, questo potrebbe non avere molta importanza.


La cosa grandiosa degli attori della Scala è che sono guidati dai messaggi. Ognuno di loro ha un proprio messaggio / coda eventi. Non sono sicuro che "Disegna" debba essere un messaggio o un metodo per la chiamata. Penso che sarà quest'ultimo, in modo che uno Sprite possa essere disegnato in qualsiasi momento, indipendentemente dallo stato della loro coda di eventi. E possono scambiarsi messaggi per assicurarsi che le cose vengano eseguite in un determinato ordine.
Lanbo,

Fai attenzione, non credo che avere ogni sprite abbia un metodo Draw o un evento sarebbe utile, tranne forse come una bandiera per attivare la visibilità. Nella fase di rendering di un loop di gioco, l'ordine in cui gli sprite sono resi sullo schermo ha un grande effetto sul risultato. Se hai uno sprite che si trova di fronte all'altro (la dimensione è rivolta verso il monitor), vuoi che venga disegnato per secondo. Vedo gli attori di Scala essere utili per la parte di aggiornamento / logica del loop di gioco.
michael.bartnett,

Di solito, hai solo un metodo di disegno lì, quindi implementandolo in questo modo non dovrebbe esserci molta differenza rispetto al modo normale di trattare gli sprite.
Lanbo,

Ah va bene, ho capito male quello che stavi descrivendo. In qualche modo immaginavo che gli sprite si rendessero ogni volta e comunque piacessero. Facci sapere come va a finire!
michael.bartnett,

0

Beh, non sono nemmeno un programmatore, ma non vedo alcun problema nella tua proposta. Non ho nemmeno pensato a un tale modo di sviluppare attori.

Potrebbe essere piuttosto una sfida, dal momento che l'IA deve essere molto preciso, per evitare comportamenti non rispettati, ma a parte questo, vedo che è una buona proposta


0

Se per sprite intendi entità di gioco, allora certo.

Le entità di gioco non devono mai disegnare se stesse. Dovrebbero aggiornare un handle grafico che descrive dove e come devono essere disegnati. Il sistema di rendering o il grafico della scena o qualunque cosa faccia il disegno reale. Esiste una scheda grafica, inoltre la scheda grafica deve essere sincronizzata ogni 16ms. Una configurazione del genere non funziona bene per l'elaborazione asincrona distribuita.

Il sistema di rendering dovrebbe essere un attore (o possibilmente una coppia se sei difficile). Quando le entità di gioco aggiornano la maniglia grafica, invia messaggi al sistema di rendering. Il sistema di rendering può prendere qualsiasi tipo di decisione e / o ottimizzazione, ad esempio rendering batch, occlusione, smoothing del jitter fisico, ecc.

Non sono uno sviluppatore di Scala, ma ho fatto parecchio con Erlang. Quindi, se una parte della mia terminologia di Scala non è corretta, ti prego di perdonarmi.

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.