I am trying to create a basic game engine in C and I want an Engine
object to be able to loop through all the GameObject
children to run their update methods, to do this I want to use a vector of all children within the Engine
class.
For example:
This is similar to what I have been trying to do:
Parent Engine Class
class Engine {
public:
Engine() {};
std::vector<GameObject> GameObjects; //Vector to store all GameObjects
void AddNewObject(GameObject& obj) {
GameObjects.push_back(obj); //Add new object to the vector array
}
void Run() {
for (int i = 0; i < GameObjects.size(); i ) {
GameObjects[i].Update(); //Run the update method of each GameObject
}
}
}
GameObject Child Class
class GameObject : public Engine {
public:
GameObject() {}
void Update() {
//Do stuff
}
}
Main code loop
int main(void) {
Engine engine;
GameObject object;
engine.AddNewObject(object); //Add object
engine.run();
}
Any help would be greatly appreciated, Thanks.
CodePudding user response:
There are a few issues here. First, your vector needs to be a vector of references or pointers, otherwise GameObjects.push_back(obj);
makes a copy of obj
to place into the vector (unless you move it) and polymorphism won't work (you can't hold subclasses of GameObject
).
How you approach this depends on which object you want to own the memory associated with each GameObject
. A trivial fix is is by using a vector of pointers:
class Engine {
public:
Engine() {};
std::vector<GameObject*> GameObjects; //Vector to store all GameObjects
void AddNewObject(GameObject& obj) {
GameObjects.push_back(&obj); //Add new object to the vector array
}
void Run() {
for (int i = 0; i < GameObjects.size(); i ) {
GameObjects[i]->Update(); //Run the update method of each GameObject
}
}
}
However, with modern, C you would want to probably use a smart pointer like unique_ptr:
class Engine {
public:
Engine() {};
std::vector<std::unique_ptr<GameObject>> GameObjects; //Vector to store all GameObjects
void AddNewObject(std::unique_ptr<GameObject> obj) {
GameObjects.push_back(std::move(obj)); //Add new object to the vector array
}
void Run() {
for (int i = 0; i < GameObjects.size(); i ) {
GameObjects[i]->Update(); //Run the update method of each GameObject
}
}
}
By using a unique pointer, you would have to change your other code:
int main(void) {
Engine engine;
std::unique_ptr<GameObject> object = std::make_unique<GameObject>();
// Transfers memory ownership of `object` into `engine`
engine.AddNewObject(std::move(object)); //Add object
engine.run();
}
Lastly, your class hierarchy looks invalid. You probably don't need or want GameObject
to be a subclass of Engine since they don't share anything in common. GameObject
may likely be a good base class itself and other game objects would inherit it.