I've been working on a 2d RPG for awhile now, and I've come to realize I've made some bad design decisions. Theres a few things in particular that are causing me problems, so I was wondering what sort of designs other people used to overcome them, or would use.
For a little background, I started working on it in my free time last summer. I was initially making the game in C#, but about 3 months ago, decided to switch to C++. I wanted to get a good handle on C++ since it's been awhile since I used it heavily, and figured an interesting project like this would be a good motivator. I've been using the boost library extensively and have been using SFML for graphics and FMOD for audio.
I have a fair bit of code written, but am considering scrapping it and starting over.
Here's the major areas of concern I have and wanted to get some opinions on the proper way others have solved them or would solve them.
1. Cyclical Dependencies When I was doing the game in C#, I didn't really have to worry about this since it isn't an issue there. Moving to C++, this has become a fairly major problem and made me think I may have designed things incorrectly. I can't really imagine how to decouple my classes and still have them do what I want. Here's a few examples of a dependency chain:
I have a status effect class. The class has a number of methods (Apply/Unapply, Tick, etc.) to apply it's effects against a character. For instance,
virtual void TickCharacter(Character::BaseCharacter* character, Battles::BattleField *field, int ticks = 1);
This functions would be called everytime the character inflicted with the status effect takes a turn. It'd be use to implement effects such as Regen, Poison, etc. However, it also introduces dependencies on the BaseCharacter class and the BattleField class. Naturally, the BaseCharacter class needs to keep track of what status effects are currently active on them so that's a cyclical dependency. Battlefield needs to keep track of the fighting parties, and the party class has a list of BaseCharacters introducing another cyclical dependency.
2 - Events
In C# I made extensive use of delegates to hook into events on characters, battle fields etc. (for an example, there was a delegate for when the character's health change, when a stat changed, when a status effect was added/removed, etc.) and the battlefield/graphical components would hook into those delegates to enforce their effects. In C++, I did something similar. Obviously there's no direct equivalent to C# delegates, so instead I created something like this:
typedef boost::function<void(BaseCharacter*, int oldvalue, int newvalue)> StatChangeFunction;
and in my character class
std::map<std::string, StatChangeFunction> StatChangeEventHandlers;
whenever the character's stat changed, I'd iterate and call every StatChangeFunction on the map. While it works, I'm worried this is a bad approach to doing things.
3 - Graphics
This is the big thing. It isn't related to the graphics library I'm using, but is more of a conceptual thing. In C#, I coupled graphics in with alot of my classes which i know is a terrible idea. Wanting to do it decoupled this time I tried a different approach.
In order to implement my graphics, I was imagining everything graphics related in the game as a series of screens. I.e. there's a title screen, a character status screen, a map screen, an inventory screen, a battle screen, a battle GUI screen, and basically I could stack these screens on top of each other as necessary to create the game graphics. Whatever the active screen is owns the game input.
I designed a screen manager that would push and pop screens based on user input.
For instance, if you were on a map screen (an input handler/visualizer for a Tile Map) and pressed the start button, it'd issue a call to screen manager to push a Main Menu screen over the map screen and mark the map screen to not be drawn/updated. The player would navigate around the menu, which would issue more commands to the screen manager as appropriate to push new screens onto the screen stack, then pop them as the user changes screens/cancels. Finally when the player exits the main menu, I'd pop it off and get back to the map screen, remark it to be drawn/updated and go from there.
Battle screens would be more complex. I'd have a screen to act as the background, a screen to visualize each party in the battle, and a screen to visualize the UI for the battle. The UI would hook into the character events and use those to determine when to update/redraw the UI components. Finally, every attack that has an available animation script would call an additional layer to animate itself before popping off the screen stack. In this case, every layer is consistently marked as drawable and updatable and I get a stack of screens handling my battle graphics.
While I haven't been able to get the screen manager to work perfectly yet, I think I can with some time. My question about it is, is this a worthwhile approach at all? If it's a bad design I want to know now before I invest too much more time making all the screens I'm going to need. How do you build up the graphics for your game?