In che modo i programmatori di giochi progettano le loro classi per riutilizzarle in modalità AI, rete e di gioco e passaggio?

5

Per un gioco a due giocatori in cui il tuo avversario potrebbe essere sulla rete, la CPU stessa o vicino a te dove giocherebbe girare per turno sulla stessa macchina.

In che modo le persone progettano le classi per il riutilizzo? Sono in una situazione simile e non ho esperienza nel creare giochi così complessi.

Ma ecco quello che ho pensato,

Se sono un oggetto giocatore, dovrei solo interagire con il GameManager o GameEngine Singleton, da cui riceverò varie notifiche sullo stato del gioco.

Non mi interessa dove e chi sia il mio avversario, questo GameManager dipende dalla modalità di gioco, interagirà con gameNetworkManager, o AI mi dirà che cosa ha giocato l'avversario.

Non sono sicuro dello scenario in cui suoniamo e passiamo [turno per volta sulla stessa macchina].

Sperando in una spiegazione breve ma chiara o almeno un link a una risorsa simile.:)

    
posta Amogh Talpallikar 10.07.2012 - 07:36
fonte

1 risposta

17

Non esiste una risposta chiara e il design di classe per i giochi è un argomento molto ampio. Posso tuttavia suggerirti due trabocchetti molto comuni:

  1. Si sta tentando di usare l'ereditarietà per modellare il polimorfismo sulle entità del gioco, in modo da avere un BaseEntity , un PlayerCharacter , ecc. e dare loro una dozzina di metodi per modellare come si muovono, disegnare, decidere cosa fare e interagire con il resto del mondo. Tuttavia, questo rende l'accoppiamento abbastanza stretto e non favorisce esattamente il riutilizzo. Un approccio migliore è la composizione: rendi la tua classe Entity non polimorfica, ma dagli un mucchio di membri polimorfici per descrivere aspetti diversi, ad es. un Brain (che determina il loro comportamento, questo può essere un HumanPlayerBrain , un AIBrain , un NetworkBrain , ecc.), un Appearance (che si occupa di selezionare i modelli giusti / sprite e animarli se necessario), un Physics (che descrive le proprietà del modello fisico dell'entità). Ognuno di questi ha una sua gerarchia di classi, ma per lo più sono per lo più indipendenti l'uno dall'altro, e puoi mescolarli e abbinarli se necessario.
  2. Si è anche tentati di scrivere entità autoaggiornanti e molti tutorial di gioco introduttivi raccomandano anche questo. Una palla che aggiorna la propria posizione ogni volta che chiami il suo metodo tick() suona come una soluzione elegante, ma non appena le interazioni diventano più complesse, dovrai affrontare brutti problemi - cosa succede se un centinaio di entità di tipi diversi si stanno muovendo al contemporaneamente? Chi è responsabile del controllo delle collisioni e quando viene trovato, quale dei due oggetti è "attivo" e quale "passivo"? È a.collideWith(b) o b.collideWith(a) ? La soluzione è rendere tutte le tue entità prevalentemente passive; espongono semplicemente gli accessor per interrogare e aggiornare le loro proprietà fisiche (posizione, dimensione, massa, inerzia, ecc.) e un oggetto GamePhysics complessivo è responsabile del controllo di tutti gli oggetti e dell'aggiornamento. Il gestore delle collisioni ora è world.collide(a, b) , perfettamente semplice.

E poi un'altra avvertenza: Rendere il gioco un singleton sembra una decisione logica, ma ti blocca in non più di uno stato di gioco alla volta. Questo ha due importanti svantaggi:

  1. Se vuoi un'architettura client / server, il server sarà sempre in grado di eseguire una partita alla volta.
  2. Test delle unità tutto ciò che dipende dallo stato del gioco sarà più difficile.

Personalmente, preferisco passare lo stato del gioco in giro come solo un altro oggetto. Un ulteriore vantaggio di questo è che posso passare solo parti dello stato del gioco a oggetti che non hanno attività commerciali con il resto, ad esempio, il metodo render() di un oggetto non dovrebbe modificare la logica del gioco, quindi posso passare come const ; la parte fisica non dovrebbe fare nulla di relativo alla grafica, quindi non gli passerò un riferimento al gestore delle risorse. Ciò mantiene basso il numero potenziale di dipendenze incrociate, che a sua volta comporta una minore complessità.

    
risposta data 10.07.2012 - 07:53
fonte

Leggi altre domande sui tag