Gestire elenchi di diversi tipi di entità: esiste un modo migliore?


9

Sto sviluppando un gioco spaziale 2D per dispositivi mobili, ma diventa davvero complesso e la mia soluzione è davvero confusa e produce molti segmenti di codice ripetuti.

Ho una classe mondiale in cui ho liste multiple di oggetti diversi come:

List<Enemy> enemys;
List<Projectile> projectiles;
List<Collectable> collectables;
List<Asteroid> asteroids;
List<Effect> effects;
..

Ogni elenco viene aggiornato dalla classe mondiale. ma non è tutto .. Ogni nemico ha un elenco di motori e un elenco di lanciatori di armi che viene aggiornato dal nemico. Ora ogni motore aggiunge alcuni effetti di fuoco agli "effetti" della lista mondiale e ogni lanciatore di armi aggiunge proiettili alla lista "proiettili" della lista mondiale. Tutte queste classi hanno parametri diversi, quindi ho bisogno di un aggiornamento extra e di una funzione di rendering extra per ogni classe.

Almeno sono tutti figli di "GameObject" che fornisce loro elementi di base come posizione, velocità e accelerazione, poligoni che delimitano e funzioni come applyForce e una macchina a stati finiti

C'è un modo migliore o più comune per farlo? come una classe catch-all che contiene tutti i possibili parametri e metodi per tutti i diversi oggetti. (penso che questo produrrebbe un codice ancora più confuso)


Questo è simile alla mia domanda: gamedev.stackexchange.com/questions/22559/… suggerisco di guardare le risposte che mi è stato dato.
Derek,

Risposte:


5

Esiste un modo migliore o più comune per farlo? come una classe catch-all che contiene tutti i possibili parametri e metodi per tutti i diversi oggetti.

Sì, si chiama architettura . Dai un'occhiata qui per i dettagli.

Ciò consentirebbe solo un elenco di entità nella tua classe mondiale:

List<Entity>

È un esempio di composizione sull'eredità .


3

Entro i limiti della domanda originale, un'opzione sarebbe quella di suddividere gli elenchi in Azioni anziché in Tipi come quello che hai. Ad esempio, avresti il List<HasAI>e uno per List<Collidable>e quando crei un nuovo oggetto si aggiunge a qualsiasi elenco di azioni di cui ha bisogno, quando l'oggetto viene distrutto, si rimuove da tali elenchi. Un oggetto può trovarsi in più elenchi.

Il secondo passaggio di tale opzione è il refactoring delle classi da una gerarchia in una che utilizza le interfacce, quindi il tipo HasAI è una classe che implementa l'interfaccia IBrains come esempio. Corrispondenza del fatto che l' List<HasAI>unico oggetto richiesto deve avere l'interfaccia IBrains.

Ciò dovrebbe aiutare a ripulire un po 'della complessità.


2

Penso che ciò che devi fare sia astrarre il rendering nelle sue classi, penso uno per giocatore e uno per nemico (o forse solo uno per giocatore, e quindi crearne un'istanza per giocatore e nemico - non sicuro al 100% del design del tuo gioco.)

È possibile utilizzare un modello visitatore per consentire al renderer di aggirare i vari oggetti e decidere cosa disegnare, che potrebbe essere meno complesso.


2

Usare una classe base e fare affidamento sul polimorfismo è un'ottima idea. Ma ci sono alcuni approcci alternativi. Ci sono due articoli di Noel Llopis che vale la pena leggere. Di recente ho esaminato il design orientato ai dati e penso che abbia qualche merito.

Gli articoli sono qui e qui . Potrebbe semplificare un po 'di più il tuo codice rispetto al polimorfismo. Ma come qualsiasi cosa YMMV, dai un'occhiata e vedi se si adatta a ciò che stai cercando di ottenere. Il polimorfismo usa l'ereditarietà e DOD usa l'aggregazione sia con pro che contro, quindi scegli il tuo veleno.


1

Puoi utilizzare OOP e soprattutto il polimorfismo.

Fondamentalmente, devi creare una classe base, da cui ereditano tutte le entità di gioco. Questa classe di base, il più astratta possibile, conterrà cose come una funzione Creazione, Aggiornamento e Forse una Distruzione.

Quindi trai tutti gli altri oggetti di gioco da questa classe. Probabilmente dovrai anche aggiungere una sorta di riflessione nel tuo codice se la tua lingua non lo supporta, per fare alcune cose più avanzate, ma è evitabile se sai come strutturare correttamente la tua eredità.


1
Lo ha già fatto - tutte le sue classi sono figli di GameObject. Deve solo trasformare le sue serie di elenchi in un unico elenco di GameObjects.
SomeGuy
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.