Gamestates: Final update

Game States

In a game, you can describe several different contexes as GAMESTATES. For example, the title screen of a game can be considered a game state, or a pause menu can be considered a game state. The point being, a gamestate is a specific snapshot at any given moment. To create the framework of my game(or any game really), I used a dynamic object oriented to create this.

The idea is this:
There will be a common Game class, it can be referred to as the engine of the game as it is what controls the actual flow of the game. This Game Class will hold an array(Vector in the example) of a generic GameState Class types. It will also contain a pushState method, which will move to the next gameState requested, and a popState to return back to the previous state. The gameloop() function will then call the currentState's common functions in sequence. This allows the ability to encapsulate different gameStates into different classes and just call that state's functions.

Each different state will have a few common functions with each other, that being: Init(), Render(), Update(), and Input(). Based on what state the game is in, each different version of the function will only call what's relevant to the current state of the game. For example, I would not render the titlescreen if I'm in the middle of gameplay, and this approach completely seperates the two to avoid this issue entirely.

Using my game's basis as an example, there are a few numerous states you can describe, but I'll keep it to a basic 4 states.

MenuState: This is a state where it shows the title screen. In a standard game, this is the introduction to the game, and may offer the ability to load a save, create a new save, or delete a new save and may hold an options menu for the player to use.

MapState: This state describes the player's ability to move a cursor around the map and select a Unit. It will only render the map, and units on the map currently.

UnitMoveState: This will now allow a player to move a unit, and only one unit at a time, and renders their move range.

UnitActionState: While not fully implemented properly, the idea is that when a player selects a valid location, the player will get a pop-up menu containing information what actions they wish for that unit to take. This state will now not allow movement of the main cursor since that code to do so is not in this version of input(), and should only allow cursor movement of the pop-up-menu.

The third image describes the flow of the game using these gamestates, and what actions cause the game to move betweens states.

Below: Visual Demonstration of these states currently implemented.
MenuState->MapState->UnitMoveState->ActionSelectState->MapState

Below: Conceptual ideas of the Game State implemented in the project

Actual Implementation in the game below:

The GameState class in C++

The Game Class

GameLoop function that is in the Game Class

Units and Sprites

For this game to even work, we need something for the player to actually control. In this game, its referred to as Units. Each Unit is (mostly)unique according to FE, and if you've read the introduction, I have no need of explaining what each Unit needs.

If you saw above, there was already a unit on screen, animated and able for the player to move.

Firstly, I had to define a Unit Class. Do not confuse this with the game's version of unit classes, that's something I will delve on further. This unit will have parameters equalling their stats, and a move range depending of what kind of unit they are. This class will also contain functions to be able to move the unit. While not implemented yet, the intent was to read the unit's personal stats from a file that I can update separately.

Currently, each unit is given an X and Y position corresponding to the tile they sit in. In the state's where the player has control over their main cursor, the game checks between the Map and the Unit and then draws the unit there. Similar code for drawing the Tiles are reused for the Unit Class as well, so no need to explain how the program draws the unit in the correct square despite the two classes being completely separated. 

Every unit has an ID number attached to them, for easy lookup. The intent is for the Player Class to have an array of Units for when the player moves into the UnitMoveState.

In the UnitMove state, the program uses the ID of the selected unit, and loops through the Units array, and draws their move range(in blue!). It does so by doing a 4 different for loops for each diagonal direction. If the tile is valid, then it passes this information to the Tile Class, which in turn affects my drawTile Function to color that tile blue. As well, since the tile is valid, the Unitclass will allow the unit to move there and updates their X and Y coordinates appropriately in the unitAction state.

In the unitActionState, the player can choose their actions to take. In this case, it's just confirm location, which will change the Unit's X and Y position to the cursor's current X and Y position.

Reusing similar code from the drawTile code, and unit position code, I am able to animate sprites by creating an array of images for the game to cycle through every so many frames. Each time the image index is updated, the game sets the new texture and its information to be passed to openGL for rendering the next time the game's draw functions for each object is called.

Demonstration of the unit animation and cursor animation

Demonstration of Unit sprite changing when in a different state

Final Thoughts:

I actually had alot of fun with this project. I got NOWHERE near where I would of liked. My original game scope was much larger, and while I still would have liked to get there, I learned alot about the design of a game engine, and then implementing a game in that engine. My original intent was to get the ability to have enemy AI and have them have objectives of their own to fufill against the player's objective. The main focus would be AI pathfinding, and I know I would have to use either A* or Djikstra's algorithm to fufill this purpose. However, that did no pan out. I managed to get as far as allowing the player to have a unit on the screen, animated and able to move them about on a tile board in 2D.

Despite this, I learned alot about the flow and design. of a game. And while I did not use it in this project, I learned about the concept of tilesheets and sprite atlasing. I also learned alot about how games graphics are drawn to the screen while building this project as well as numerous methods and algorithms to fufill certain purposes. And finally, I feel this project strengthened my core of C++, while its nowhere near professional, it helped strenghthen the concepts of OOP, classes and inheritance to use in my future endeavors.


The Code can be found here, for whatever reason you may see fit