Long text incoming!
What makes OOP powerful is the Inheritance and Polymorphism not knowing exactly how much you know about this I will be very basic. A very common way of structuring a game with OOP is to have a base class that all the other "game objects"(tiles, enemies, players, towers, what have you) inherits from. That is, one class that has alot of children.
So for instance, you create a base class, lets call it GameObject. This class contains all that every object in the game needs, such as posision, rotation and so on.
Class GameObject
{
public:
GameObject();
~GameObject();
virtual void update() {}; //virtual will let you rewrite the function
//in a child class.
protected: //Protected lets the children be able to modify the variables
int posX, posY;
};
Now your Tile and Enemy class can inherit from this class making them subclasses or "childs". That contains all that the "parent does so you don't have to write it again, in this case it's the "int posX, posY"
#include "GameObject.h"
Class Tile : public GameObject //Inheritance
{
public:
void update(); //Add logic
private:
bool visible;
//automaticly has int posX, posY; since we inherit.
};
What this lets you do is to "trick"(not quite but it's easier to understand) the computer into thinking that a pointer to an Enemy or Tile object is a GameObject pointer. And thereby we can put all the object-pointers to objects that inherites from the GameObject class into one list.
This will make the Game Loop look something like this:
void Loop()
{
//creates the list
std::vector<GameObject*> gameObjects; //Create a vector or a regular array
//that can hold all your gameobjects
//Fills the list
gameOjbects.push_back(new Enemy());
gameObjects.push_back(new Tile());
gameOjbects.push_back(new Enemy());
gameObjects.push_back(new Tile());
gameOjbects.push_back(new Enemy());
gameObjects.push_back(new Tile());
//UpdateLoop
while(true)
{
for(int i = 0; i < gameObjects.size(); i++)
gameObject[i]->update();
//This is where the virtual keyword comes in.
//Here the compiler will regognize this as an Enemy- or Tile-pointer, not GameObject.
//Having the update function in GameObject as "virtual"
//will make the compiler take the Enemies or Tiles version of the function
//if there is one. This is "Polymorphism".
}
}
Now your Enemy.update() function still needs an array of tiles, and spontaneously I would do it sort of like you solved it.
#include "Tile.h"
#include <vector>
Class Enemy : public GameObject //Inheritance
{
public:
void update(); //Add movement logic in .cpp file
//This will set the pointer to the tiles array or vector.
static void setTilesPointer(std::vector<Tile*>* tiles) { m_tiles = tiles; };
private:
bool health;
static std::vector<Tile*>* m_tiles; //The pointer to the tiles array or vector.
};
Then in the top of Enemy.cpp we add, so we don't get an unresolved external symbol error:
std::vector<Tile*>* Enemy::m_tiles = new std::vector<Tile*>();
And now you have to modify your loop function a bit:
void Loop()
{
//Creates the lists
std::vector<GameObject*> gameObjects; //Create a vector or a regular array
//that can hold all your gameobjects
std::vector<Tiles*> tiles;
//Sets the pointer to the tiles
Enemy::setTilesPointer(&tiles);
//Fills the lists
gameOjbects.push_back(new Enemy());
gameOjbects.push_back(new Enemy());
gameOjbects.push_back(new Enemy());
tiles.push_back(new Tile());
tiles.push_back(new Tile());
tiles.push_back(new Tile());
for(int i = 0; i < tiles.size(); i++)
gameObject.push_back(tiles[i]);
//UpdateLoop
while(true)
{
for(int i = 0; i < gameObjects.size(); i++)
gameObject[i]->update();
}
}
Since the "m_tiles" variable in Enemy is static we only have to set it once and it will be the same for all Enemy objects.
Hope you got some deeper insight to the world of OOP and that I didn't waste your time :)