The biggest addition I’ve added in the last week to my game is a level system! It was difficult, confusing and seemed almost impossible, but I’ve finally done it! I tried a few ways to do this. The first way was have whole new state for each level. I liked this idea, since gameplay is actually handled in a separate ‘GameLogic’ class, so it would just be the loading that was different. However, loading a hundred object positions from a .txt file for every level was quite slow, so I went with a different idea.
The second one I tried was having one folder called level1, and another level2. In each of them would have the same enemy and block folders, but the positions would be different, hence giving a separate level. I didn’t really like this idea, and it fell apart completely when I tried to implement it. There was problems with the sizes of std::vectors changing (level 1 had 12 blocks, level 2 had 19) and basically just loading everything was a pain.
Then I got another idea. If every piece of level information was loaded at the start, then switching levels would be quick. I was going to try having a Struct or Class storing level information about each object, when I got a better idea. Each object in my game has a few stats, such as speed, acceleration, and position. They also have a initial position, which is where they’re first placed when the game starts. My idea was, create an array of initial positions, one for each level. I implement this and within 20 minutes I had a working prototype of it, where blocks stored two sets of initial values, and depending on the level a different one would load. Within a couple of hours I’d applied this to the Enemies, Player, Foreground pieces and basically every object.
Here’s a few screenshots of level 1 and 2!
Somewhat related to the level system, I’ve changed the way all the entities within my game are loaded (with the exception of the player). Previously, I’d hard-coded each entities loading; like getting positions, assigning textures, speeds etc. This proved very tedious, and error-prone, to go editing each loading method. So I made a more generic one, which I could simple pass a std::string into, with the entity name, and it would load all the entity’s in that group for me. First, it creates a new group of entity’s under that name. Then it loads which layer they’re on (their depth), then it loads their speed and size. Then it works out how many entities to load, and textures each one. Finally it loads all positions from a .txt file, and puts them into the entity. This is what each entity’s loading method already did, but the more generic one worked much smoother (and halved the size of my loading code). The player doesn’t use this, however, because they also store animation data. While, in the future I’d like all objects to have animation data, right now it’s limited to the player.
The final thing I did last week was add checkpoints. These proved harder than I originally thought they’d be. The way I’d done the game previously, was the player and camera stays still while everything else moved left. While I didn’t like this method, it gave the smoothest gameplay on low-performance machines (since blocks stuttering isn’t as annoying as the player stuttering). However, this meant I’d have to store how far along the player’s traveled for checkpoints to work, which didn’t work well in implementation.
I decided to change how this was done, and reworked the program so the player moved right like before. When they hit a checkpoint, a checkpoint variable (a simple vector storing x and y) was filled with the player’s current position. Then, when the player dies they’re put back to this position. This method worked well, so I stuck with it. The checkpoint objects are normal entities, which are set to invisible during normal gameplay and visible in Construction Mode.
I also did a lot of little things to the game. I added acceleration using the formula: currentSpeed = currentSpeed + (1 * maxSpeed ) * acceleration . I fixed a glitch where the game would call the update method once, then the render method twice (which killed performance on low-spec machines). And I found a name for my game, with the help of my girlfriend; Who Says Chickens Can’t Fly!?