Je crée un jeu qui utilise des objets de jeu basés sur des composants, et j'ai du mal à implémenter un moyen pour chaque composant de communiquer avec son objet de jeu. Plutôt que d'expliquer tout à la fois, j'expliquerai chaque partie de l'exemple de code pertinent:
class GameObjectManager {
public:
//Updates all the game objects
void update(Time dt);
//Sends a message to all game objects
void sendMessage(Message m);
private:
//Vector of all the game objects
std::vector<GameObject> gameObjects;
//vectors of the different types of components
std::vector<InputComponent> input;
std::vector<PhysicsComponent> ai;
...
std::vector<RenderComponent> render;
}
Le GameObjectManager
contient tous les objets du jeu et leurs composants. Il est également responsable de la mise à jour des objets du jeu. Il le fait en mettant à jour les vecteurs de composants dans un ordre spécifique. J'utilise des vecteurs au lieu de tableaux afin qu'il n'y ait pratiquement aucune limite au nombre d'objets de jeu pouvant exister à la fois.
class GameObject {
public:
//Sends a message to the components in this game object
void sendMessage(Message m);
private:
//id to keep track of components in the manager
const int id;
//Pointers to components in the game object manager
std::vector<Component*> components;
}
La GameObject
classe sait quels sont ses composants et peut leur envoyer des messages.
class Component {
public:
//Receives messages and acts accordingly
virtual void handleMessage(Message m) = 0;
virtual void update(Time dt) = 0;
protected:
//Calls GameObject's sendMessage
void sendMessageToObject(Message m);
//Calls GameObjectManager's sendMessage
void sendMessageToWorld(Message m);
}
le Component
classe est entièrement virtuelle afin que les classes pour les différents types de composants puissent implémenter comment gérer les messages et les mettre à jour. Il est également capable d'envoyer des messages.
Maintenant, le problème se pose sur la façon dont les composants peuvent appeler les sendMessage
fonctions dans GameObject
et GameObjectManager
. J'ai trouvé deux solutions possibles:
- Donnez
Component
un pointeur à sonGameObject
.
Cependant, comme les objets du jeu sont dans un vecteur, les pointeurs pourraient rapidement être invalidés (la même chose pourrait être dite du vecteur dans GameObject
, mais j'espère que la solution à ce problème peut également résoudre celui-ci). Je pourrais mettre les objets du jeu dans un tableau, mais je devrais alors passer un nombre arbitraire pour la taille, qui pourrait facilement être inutilement élevé et gaspiller de la mémoire.
- Donnez
Component
un pointeur sur leGameObjectManager
.
Cependant, je ne veux pas que les composants puissent appeler la fonction de mise à jour du gestionnaire. Je suis la seule personne à travailler sur ce projet, mais je ne veux pas prendre l'habitude d'écrire du code potentiellement dangereux.
Comment puis-je résoudre ce problème tout en gardant mon code sûr et compatible avec le cache?