구성 요소 기반 게임 개체를 사용하는 게임을 만들고 있는데 각 구성 요소가 해당 게임 개체와 통신하는 방법을 구현하는 데 어려움을 겪고 있습니다. 한 번에 모든 것을 설명하는 대신 관련 샘플 코드의 각 부분을 설명하겠습니다.
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;
}
는 GameObjectManager
모든 게임 오브젝트 및 그 구성 요소를 보유하고 있습니다. 또한 게임 오브젝트 업데이트도 담당합니다. 구성 요소 벡터를 특정 순서로 업데이트하여이를 수행합니다. 배열 대신 벡터를 사용하므로 한 번에 존재할 수있는 게임 개체 수에 제한이 없습니다.
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;
}
이 GameObject
클래스는 구성 요소가 무엇인지 알고 메시지를 보낼 수 있습니다.
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);
}
이 Component
클래스는 순수한 가상이므로 다양한 유형의 구성 요소에 대한 클래스가 메시지 처리 및 업데이트 방법을 구현할 수 있습니다. 메시지를 보낼 수도 있습니다.
이제 컴포넌트가 및 에서 sendMessage
함수를 호출 할 수있는 방법에 대한 문제가 발생합니다 . 나는 두 가지 가능한 해결책을 생각해 냈습니다.GameObject
GameObjectManager
- 에
Component
대한 포인터를 제공 하십시오GameObject
.
그러나 게임 오브젝트가 벡터에 있기 때문에 포인터가 빠르게 무효화 될 수 있습니다 GameObject
. 게임 객체를 배열에 넣을 수는 있지만 크기에 대한 임의의 숫자를 전달해야합니다.
- 에
Component
대한 포인터를 제공 하십시오GameObjectManager
.
그러나 구성 요소가 관리자의 업데이트 기능을 호출 할 수 있기를 원하지 않습니다. 나는이 프로젝트에서 일하는 유일한 사람이지만 잠재적으로 위험한 코드를 작성하는 습관을 갖고 싶지 않습니다.
코드를 안전하고 캐시 친화적으로 유지하면서이 문제를 어떻게 해결할 수 있습니까?