Questo è un seguito a questa domanda, a cui ho risposto, ma questa affronta un argomento molto più specifico.
Questa risposta mi ha aiutato a capire Entity Systems anche meglio dell'articolo.
Ho letto l'articolo (sì, l'articolo) su Entity Systems e mi ha detto quanto segue:
Le entità sono solo un ID e una matrice di componenti (gli articoli affermano che la memorizzazione di entità nei componenti non è un buon modo di fare le cose, ma non fornisce un'alternativa).
I componenti sono pezzi di dati che indicano cosa si può fare con una determinata entità.
I sistemi sono i "metodi", eseguono la manipolazione dei dati sulle entità.
Questo sembra davvero pratico in molte situazioni, ma la parte sul fatto che i componenti siano solo classi di dati mi dà fastidio. Ad esempio, come posso implementare la mia classe Vector2D (posizione) in un sistema di entità?
La classe Vector2D contiene dati: coordinate xey, ma ha anche dei metodi , che sono cruciali per la sua utilità e distinguono la classe da un solo array di due elementi. Metodi di esempio sono: add()
, rotate(point, r, angle)
, substract()
, normalize()
, e tutti gli altri standard metodi utili, e assolutamente necessario che le posizioni (che sono istanze della classe Vector2D) dovrebbe avere.
Se il componente fosse solo un detentore di dati, non sarebbe in grado di disporre di questi metodi!
Una soluzione che potrebbe probabilmente apparire sarebbe quella di implementarli all'interno dei sistemi, ma sembra molto controintuitivo. Questi metodi sono cose che voglio eseguire ora , che siano completi e pronti per l'uso. Non voglio aspettare MovementSystem
che legga un costoso set di messaggi che gli dicono di eseguire un calcolo sulla posizione di un'entità!
E l'articolo afferma chiaramente che solo i sistemi dovrebbero avere alcuna funzionalità, e l'unica spiegazione per quello, che ho potuto trovare, era "evitare OOP". Prima di tutto, non capisco perché dovrei astenermi dall'utilizzare metodi in entità e componenti. L'overhead di memoria è praticamente lo stesso e, se abbinato a sistemi, questi dovrebbero essere molto facili da implementare e combinare in modi interessanti. I sistemi, ad esempio, potrebbero fornire la logica di base solo a entità / componenti, che conoscono l'implementazione stessa. Se me lo chiedi, questo in pratica sta prendendo le chicche sia da ES che da OOP, qualcosa che non può essere fatto secondo l'autore dell'articolo, ma a me sembra una buona pratica.
Pensaci in questo modo; ci sono molti diversi tipi di oggetti disegnabili in un gioco. Vecchie immagini, animazioni ( update()
, getCurrentFrame()
ecc.) Semplici , combinazioni di questi tipi primitivi e tutte potrebbero semplicemente fornire un draw()
metodo al sistema di rendering, che quindi non deve preoccuparsi di come viene implementato lo sprite di un'entità, solo sull'interfaccia (disegno) e la posizione. E poi, avrei solo bisogno di un sistema di animazione che chiamasse metodi specifici dell'animazione che non hanno nulla a che fare con il rendering.
E solo un'altra cosa ... Esiste davvero un'alternativa agli array quando si tratta di immagazzinare componenti? Non vedo altro posto dove archiviare i componenti se non gli array all'interno di una classe Entity ...
Forse, questo è un approccio migliore: archiviare i componenti come semplici proprietà delle entità. Ad esempio, un componente di posizione verrebbe incollato entity.position
.
L' unico altro modo sarebbe avere una sorta di strana tabella di ricerca all'interno dei sistemi, che fa riferimento a entità diverse. Ma questo sembra molto inefficiente e più complicato da sviluppare rispetto alla semplice memorizzazione di componenti nell'entità.