Creazione di entità come aggregazione


10

Di recente ho chiesto come separare le entità dal loro comportamento e la risposta principale collegata a questo articolo: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Il concetto ultimo qui scritto è quello di: OGGETTO COME UN'AGGREGAZIONE PURA.

Mi chiedo come potrei fare per creare entità di gioco come pura aggregazione usando C #. Non ho ancora capito il concetto di come potrebbe funzionare ancora. (Forse l'entità è una matrice di oggetti che implementano una determinata interfaccia o un tipo di base?)

Il mio pensiero attuale implica ancora avere una classe concreta per ogni tipo di entità che implementa quindi le interfacce pertinenti (immobile, ICollectable, ISpeakable ecc.).

Come posso creare un'entità puramente come aggregazione senza avere alcun tipo concreto per quell'entità?


Se sei ancora interessato, posso inviarti il ​​mio sistema di piccole entità in C #. Non è sorprendente , ma funziona.
Il comunista Duck il

Risposte:


6

L'approccio di "pura aggregazione" descritto da West in quell'articolo collegato evita del tutto un oggetto "entità". Ci sono componenti che fluttuano nella memoria, ma sono legati solo da relazioni implicite, se non del tutto.

Un modo per farlo è un cosiddetto approccio fuoribordo . In un tale sistema, i componenti sono detenuti da sistemi che li gestiscono o li controllano in altro modo (qui uso il termine "gestisci", ma non dovresti intendere questo per indicare che sto suggerendo che hai un sacco di * classi Manager da tenere tipi di componenti). Ad esempio, il tuo sistema fisico può aggrapparsi a un mucchio di cose che rappresentano ciascun corpo rigido nel suo mondo di simulazione e può esporre quelle cose come componenti della fisica. I componenti possono essere gli oggetti reali gestiti dal sottosistema in questione o possono essere proxy per tali oggetti, se necessario.

In un tale sistema non è necessariamente necessario che una classe "Entity" contenga una raccolta di riferimenti ai componenti che la compongono; invece viene generata una notifica relativa alla creazione o alla distruzione di una "entità" e ciascun sottosistema che gestisce i componenti esamina la descrizione dell'entità creata / distrutta (che in genere viene caricata da alcuni dati) e determina se un componente è necessario per essa.

Uno dei vantaggi di questo approccio è che si ottiene un'ottima località di riferimento per ciascun componente. Sfortunatamente è un po 'strano, nel complesso, e non il sapore più amichevole delle entità basate su componenti che ho incontrato. A volte è davvero conveniente avere un oggetto reale che rappresenta un'entità, anche se quell'oggetto fa poco di più quindi aggregare riferimenti deboli a componenti che sono ancora detenuti da altri sottosistemi (se non altro fornisce un modo semplice per instradare i messaggi tra i componenti) .

Esistono diversi modi per implementare sistemi di oggetti di gioco orientati ai componenti; E 'davvero, davvero, davvero utile se si dispone di una solida idea dei requisiti desiderati dal vostro sistema - si può guardare a ciò che i quadri popolari come l'Unità fanno per gli esempi. Senza fissare severi requisiti per te stesso, potresti imbatterti nel problema della "progettazione" infinita del sistema senza mai realmente costruirlo, cercando invano di colpire l'implementazione perfetta. Per qualsiasi motivo l'ho visto molto con i sistemi componenti.


3

Il modo in cui Unity fa è che tutti gli script (nel tuo caso, il codice di gioco specifico per un tipo di oggetto di gioco) derivano da una classe base MonoBehaviour, che a sua volta deriva dalla classe più rilevante per il tuo caso Component. Non modifichi mai (e non hai accesso al codice di) la classe GameObject.

L'oggetto del gioco ha il compito di contenere tutti quei messaggi Component. È anche apparentemente incaricato di richiamare su di essi le funzioni pertinenti (ad es Update.). Unity usa la riflessione per determinare quali funzioni chiamare (guarda la sezione "Funzioni sostituibili" in questa pagina ), ma probabilmente vorrai renderle virtuali.

Quindi uno dei meccanismi che usi in Unity è ottenere componenti sul tuo oggetto di gioco attuale (o sui suoi figli) per tipo. Ci sono alcune proprietà di aiuto che avvolgono alcune delle cose comuni. Ad esempio, se vuoi accedere al Transformcomponente dell'oggetto di gioco (per controllare la posizione / rotazione / scala dell'oggetto di gioco), dovresti normalmente fare qualcosa del genere this.GetComponent<Transform>().position, ma lo avvolgono in una this.transform.positionchiamata di aiuto . Un altro modello comune sta accedendo al Renderercomponente dell'oggetto di gioco corrente . Quindi, se vuoi fare qualcosa come cambiare il materiale dell'oggetto di gioco corrente, da un altro script potresti fare qualcosa del genere this.renderer.material = someOtherMateriale il tuo oggetto di gioco si aggiorna in modo appropriato.

Uno dei modi in cui funziona in Unity è che il loro editor è impostato in modo tale da poter creare oggetti di gioco nella tua scena con componenti già collegati. Nel caso di Unity, tutti gli oggetti di gioco hanno un Transformcomponente, ma può anche contenere tipi incorporati come AudioListenero Renderer, che fanno ciò che ti aspetteresti. Oppure puoi aggiungere i tuoi componenti che fanno qualunque cosa tu voglia che facciano. L'editor espone anche campi pubblici / serializzabili sui componenti in modo da non dover creare script diversi se si desidera utilizzare lo stesso codice di base ma modificare alcuni numeri magici.

Tutto sommato è piuttosto fluido, e suggerirei di scaricare la versione gratuita di Unity e di giocare con il modo in cui il loro sistema di scripting è impostato come una prova abbastanza decente del concetto di ciò che vuoi ottenere.


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.