Ho letto molto sui diversi modelli di design, i loro pro, contro, l'uso principale ecc. Tuttavia, mi piace sperimentare e provare a inventare le mie modalità di implementazione (anche se non sono le migliori). Ora sto affrontando un problema con l'implementazione del mio sistema componente Entity.
Nonostante i pro di questo modello voglio fare alcune delle cose a modo mio, ad esempio:
1.) I componenti sono racchiusi in interfacce più grandi per la manipolazione dei dati. Nella maggior parte dei casi leggo che i componenti ECS devono contenere solo dati e che i sistemi sono i loro principali manipolatori. Nel mio sistema intendo utilizzare classi wrapper per i componenti
Piccolo esempio: diciamo che vogliamo avere un componente Sprite, che rappresenta la componente visiva di ogni entità nel gioco. L'ho avvolto nella classe RenderableEntity che può essere un componente di un'entità e ha funzioni e variabili aggiuntive.
2.) Non uso un sistema per ogni tipo di componente.
Ancora un esempio del motore di gioco: Abbiamo un CollidableEntity, che viene inserito in una struttura di dati spaziali e che esegue i controlli di collisione, ma per RenderableEntity non esiste un sistema che lo gestisca (presumo che siamo in 2D adesso). Ragionare? Voglio che l'utente abbia la potenza di rendere gli sprite di ogni entità, a causa dell'ordine specifico o utilizzando diversi lotti.
3.) Le entità possono avere più di 1 componente dello stesso tipo e non vengono utilizzati set di bit per verificare se il sistema è interessato a una determinata entità. I componenti sono assegnati ai sistemi al momento della loro creazione tramite il tipo di dati.
Piccolo codice:
template<class DataType>
DataType* createComponent(GameEntity* mainEntity)
{
//Create it via default constructor
DataType* component = new DataType();
//Add it to the back of the component vector
mainEntity->_entityComponents.emplace_back(component);
//Assign it to system
ECS::assignToSystem<T>(component);
//Return it to access its functions
return component;
}
La funzione assignToSystem fa quanto segue: controlla se è il tipo di dati specificato nella nostra mappa e in caso contrario aggiunge il componente al sistema e da questo momento il sistema è il manutentore del componente. Anche i sistemi di gioco sono collegati a determinati tipi di dati tramite una funzione e assomiglia a questo:
class ColliderSystem:public ECS::System
{
void assignSystem() override
{
ECS::assignSystemToComponent<CollidableEntity>(this);
}
};
Puoi dirmi se è una buona idea sperimentare determinati schemi e provare a fare le cose a modo tuo? Soprattutto mi interessa perché voglio usare questo approccio nel mio lavoro di laurea e mi chiedo se sarà un problema se "infrangerò le regole" di alcuni schemi. Inoltre, cosa ne pensi dei miei "cambiamenti", ci sono dei contro? Grazie.