Hey there everybody!
Although I registered this account quite some time ago, I decided to start working on a 2D shooter project I've been conceptualizing for a while now and had some questions about code design. Specifically, as it pertains to game states and levels.
So far, I have a base entity class with a working player class, projectile, and parallel scrolling background class, all designed to be updated and rendered using lists and polymorphism. However, I've hit a few roadblocks as to how I should continue.
My question is whats the best approach for scripting enemy encounters for levels? I've looked around online but cannot seem to find any good tutorials or examples.
EDIT: I suppose I should kind of elaborate on this a bit. by enemy encounters, I meant designing levels in such a way that enemy spawns can be queued in some way based on the current level the player is on. My goal is to eventually design the game in such a way that I can use a level editor to make new levels and load them as files in the game. I was hoping someone might be able to point me in the right direction.
Also, I was wondering if someone could provide me with some advice for an effective approach for creating different game states for menus and such? I was thinking of using multiple entity lists instead of the single one I currently have, one for each state. Then I'd use condition branching in the main loop to determine how input behaves and which entity list to loop through for update/render. I'm pretty sure this would work, but my gut tells me there might be a more flexible approach that I might be missing. Any advice would be greatly appreciated!
If it helps, here is my main loop atm. Feel free to pick it apart. The more feedback I can get, the better!
Thanks for your time guys.
I suppose it depends on what exactly you want your game to feel like, but I see two ways of doing it:
1. Keep a list of spawns and a list of delays. Spawn all enemies contained in the group spawns[i], wait for delays[i] seconds, increment, repeat.
2. Keep a list of spawns. Spawn all enemies contained in the group spawns[i]. When all enemies in spawns[i] have been destroyed, increment and repeat.
I think you could also mix those two strategies, if you want to go a more advanced route.
Personally, I'm not a fan of using polymorphism for trivial cases like this. Compositions are a lot easier, IMO.
If you want to spawn enemy ships you have a couple options:
1) Player can't move beyond screen: enemies show up at timed intervals.
2) Player scrolls the screen: enemies are at specific coordinates.
Either way, what you want to do is to distill the data that makes each enemy unique. Let's take the first example, because that one is simpler IMO.
In order to make an enemy appear we need to know how far along the screen you want him to show up, when he shows up, what type of enemy, and possibly what level. I'll represent this data as a struct, but you can do classes or whathaveyou.
struct gen_enemy { unsigned int secs; //how long until he shows up float x; //how far along the screen unsigned int type; //the type (good use for enumeration?) unsigned int lvl; //level if applicable //more custom data }
Basically each level will consist of a list of these structs. Every second, have your code check the list for new enemy arrivals (checked vs secs since the start of the level). If it is time to make new friends... er... enemies place enemy of type, x pixels over, and have him start doing his thing.
Remove enemies when they fall below the screen or die.
The level ends when both the list is empty and there are no enemies alive.
As for game states, you will have to think ahead about that. It is rarely covered, but all that it takes is planning!
EDIT:
Ah! Schyfis beat me to it.
Note that despite our similar answers we both had slightly different ideas as to what to do and how to implement it. The trick is to break your problems down in the manner you see fit.