2010-09-14 19 views
10

Immagino che questa domanda o le sue varianti siano passate molto, quindi se quello che sto dicendo è un duplicato e le risposte si trovano altrove, ti prego di informarmi.Gestione degli eventi nella progettazione di un motore di gioco basato su componenti

Ho svolto ricerche sui design dei motori di gioco e ho scoperto il modello di entità basata sui componenti. Sembra promettente, ma sto ancora elaborando la sua implementazione.

sto valutando un sistema in cui il motore è organizzato su diversi "sottosistemi", che gestiscono alcuni aspetti, come il rendering, il suono, la salute, intelligenza artificiale, ecc Ogni sottosistema ha un tipo di componente associato ad esso, come una salute componente per il sottosistema sanitario. Una "entità", ad esempio un NPC, una porta, qualche effetto visivo o il giocatore, è semplicemente composta da uno o più componenti, che quando insieme danno all'entità la sua funzionalità.

Ho identificato quattro principali canali di trasmissione delle informazioni: un componente può trasmettere a tutti i componenti nella sua entità corrente, un componente può trasmettere al suo sottosistema, un sottosistema può trasmettere ai suoi componenti e un sottosistema può trasmettere ad altri sottosistemi.

Ad esempio, se l'utente desiderava spostare i propri caratteri, premere un tasto. Questa pressione del tasto verrebbe rilevata dal sottosistema di input, che quindi trasmetterà l'evento e verrà prelevato dal sottosistema del lettore. Il sottosistema del giocatore invia quindi questo evento a tutti i componenti del giocatore (e quindi alle entità che tali componenti compongono) e tali componenti del giocatore comunicano al componente di posizione della propria entità per andare avanti e muoversi.

Tutto questo per una pressa a chiave sembra un po 'tortuoso, e sono certamente aperto a miglioramenti a questa architettura. Ma comunque, la mia domanda principale segue ancora.

Per quanto riguarda gli eventi stessi, ho considerato dove un evento si comporta come nel modello di visitatore. L'importanza di ciò che voglio è che se un evento incontra un componente che non supporta (come in un evento di mossa non ha nulla a che fare direttamente con l'intelligenza artificiale o la salute), ignorerebbe il componente. Se un evento non trova il componente che sta cercando, non importa.

Il modello di visitatore quasi funziona. Tuttavia, sarebbe necessario disporre di funzioni virtuali per ogni tipo di componente (ad esempio, visitHealthComponent, visitPositionComponent, ecc.) Anche se non ha nulla a che fare con esse. Potrei lasciare queste funzioni vuote (quindi se si imbattesse in quei componenti, sarebbe ignorato), ma dovrei aggiungere un'altra funzione ogni volta che aggiungo un componente.

Le mie speranze erano che sarei stato in grado di aggiungere un componente senza aggiungere necessariamente cose ad altri luoghi e aggiungere un evento senza fare confusione con altre cose.

Quindi, le mie due domande:

  1. ci sono eventuali miglioramenti mio progetto potrebbe consentire, in termini di efficienza, flessibilità, ecc?
  2. Quale sarebbe il modo ottimale di gestire gli eventi?

risposta

1

Ho pensato di utilizzare i sistemi di entità per uno dei miei progetti e ho attraversato un processo di pensiero simile. Il mio pensiero iniziale era quello di utilizzare un pattern di Osservatore per gestire gli eventi - anch'io, originariamente considerato una sorta di modello di visitatore, ma ho deciso contro di esso per le ragioni stesse per cui si parla.

I miei pensieri sono che i sottosistemi forniranno un'interfaccia di pubblicazione/sottoscrizione specifica per un sottosistema, e quindi le dipendenze del sottosistema verranno risolte in modo "semi-allentato".Qualsiasi sottosistema che dipende dagli eventi di un altro sottosistema conoscerà l'interfaccia del Sottoscrittore per quel sottosistema e quindi può effettivamente farne uso.

Sfortunatamente, il modo in cui questi abbonati ricevono maniglie per i loro editori è ancora un problema nella mia mente. A questo punto, sto favorendo una sorta di creazione dinamica in cui ogni sottosistema è istanziato, e quindi una seconda fase viene utilizzata per risolvere le dipendenze e mettere tutti i sottosistemi in uno "stato pronto".

Comunque, io sono molto interessato a quello che ha funzionato per voi e gli eventuali problemi che hai incontrato sul vostro progetto :)

1

Utilizzare un bus evento, alias aggregatore evento. Quello che vuoi è un meccanismo di eventi che non richiede alcun accoppiamento tra i sottosistemi, e un bus degli eventi farà proprio questo.

http://martinfowler.com/eaaDev/EventAggregator.html http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices

ecc

1

questa architettura descritta qui http://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf Ci sono almeno tre problemi Ho riscontrato l'implementazione di questo in un progetto reale:

  1. i sistemi non vengono avvisati quando succede qualcosa - l'unico modo è chiedergli - il giocatore è morto? il muro non è visibile? e così via - per evitare questo è possibile utilizzare semplici MVC anziché pattern di osservatore.
  2. E se il tuo oggetto è un composit (cioè composto da oggetti)? il sistema attraverserà tutta la gerarchia e chiederà lo stato dei componenti.
  3. E lo svantaggio principale è che questa architettura si mescola tutti insieme, ad esempio perché il giocatore deve sapere di aver premuto un tasto?

penso che risposta è architetture a strati con la rappresentazione astratta ...

1

scusa il mio cattivo inglese.

Sto scrivendo un java 3d Game Engine flessibile e scalabile basato su Entity-Component System. Ho finito alcune parti di base di esso.

Per prima cosa voglio dire qualcosa sull'architettura ECS, non sono d'accordo che un componente possa comunicare con altri componenti in una stessa entità. I componenti dovrebbero solo archiviare dati e sistemi elaborarli.

Nella parte relativa alla gestione degli eventi, ritengo che la gestione degli input di base non debba essere inclusa in un ECS. Invece, ho un sistema chiamato Intent System e ho un componente chiamato Intent Component che contiene molti intenti. Un intento significa che un'entità vuole fare qualcosa verso un'entità. il sistema Intent elabora tutti gli intent, quando elabora un intent, trasmette le informazioni corrispondenti ad altri sistemi o aggiunge altri componenti all'entità.

Scrivo anche un'interfaccia chiamata Intent Generator. Nel gioco locale, puoi implementare un Input tastiera o un Generatore di input del mouse e, nel gioco a più giocatori, puoi implementare un generatore di intenti di rete. Nel sistema AI, puoi anche generare intenti.

Si potrebbe pensare che il sistema Intent elabora troppe cose nel gioco. Ma in effetti condivide molti processi con altri sistemi e scrivo anche un sistema di script. Per specifiche entità speciali ha un componente script che fa cose speciali.

In origine, quando sviluppo qualcosa, voglio sempre creare una grande architettura che includa ogni cosa. Ma a volte lo sviluppo del gioco è molto inefficiente. Oggetti di gioco diversi possono avere funzioni completamente diverse. ECS è ottimo come sistema di programmazione orientato ai dati. ma non possiamo includere ogni cosa in esso contenuta per un gioco completo.

A proposito, il nostro motore di gioco basato su ECS sarà open source nel prossimo futuro, quindi è possibile leggerlo. Se ti interessa, ti invito anche a unirti a noi.