I'm currently developing a tile-based RPG from scratch using C++ and SFML2.
So far, I got the map rendering and collision detection working just fine and in a clean, maintainable way. The next step is to implement objects on the map with which the player can interact and it feels like this is a bigger problem than it should be.
Here is an example what I want to do: Let's say there is a switch object, that has the property if it is on or off. Additionally there is a door object that has the property if it is open or closed and a list of switches. The controller will now iterate through all objects, if it is a Door, check all the switches assigned to it and if all of them are on, open the door.
My first, naive approach would look like this:
class GameObject
{
//some common attributes
}
class Switch: GameObject
{
bool isOn;
};
class Door: GameObject
{
bool isOpen;
vector<Switch> switches;
};
The problem is that different objects have different attributes and using inheritance would cause a ton of classes and I had to implement a new class every time I want to introduce a new object. Additionally to the clutter that causes, it would also not be very efficient as the controller had always look up the concrete type of the object it is iterating over and casting it to that type. Constantly having to look up the derived types of a type is also a sign of bad design.
Is there a better way to organize the objects than using classes and inheritance? I looked up the Entity-Component-System Pattern which looks like it's addressing this problem but it feels like an overkill for what I want to do. Also ECS don't fit in with my current architecture and seems in general not very suitable to be used in a tile-based game.
I'd really appreciate any ideas or hints! Thanks a lot in advance!
Edit:
To clarify, here are my issues I have with ECS and tile maps: I currently organized the data of the map like this:
map<Coordinate,Tile> mapData
This is pretty efficient when it comes to collision detection. So with an ECS, I have following options:
I could create a tile entity with coordinates and tiletype as components. That would make collision detection very inefficent. I'll have to iterate over every entity to look up if there is even a tile at the given position.
I could have an entity that holds the whole tile map in a tile map component but that would be a misuse of components as far as I understood the concept.
Using the tile map as an external, non-entity object and inject it to systems that needs it. That's kind of the opposite of what I want to achieve. I want to have a list of dynamic entities to be used on a map and end up building everything around entities, and build exceptions into the architecture.