This time I'll talk about the process of creating the main game loop. Let me remind you that Godot was chosen as the engine, and I will program in C#.
So, due to the fact that the project is microscopic, I do not plan any clean architectures and beautiful code. This time we will manage with one state machine for the game loop and several singleton controllers. Of the main controllers - level controller, mob controller, player controller, projectile controller.
The main game loop in this case would look like this:
In the old version of the game there is no menu and pause, we will limit ourselves to the entry point directly into the room. For the initial setup of the game, you will need a starting state, which will flow into the first room without mobs. The first room should show the player the instructions with the controls and give him the moves to the next rooms. Moving between rooms will cause the creation of a new instance of the Room state, and when it is created, it will determine how many and which mobs will be added to the map.
The map in the new version will be pulled out as an overlay on top of the game room, blocking input but not pausing the game. As a result, the player will be able to open the map only when no one bothers him at the level. However, in order not to create a new instance of the room upon exiting the map, the state of the map will take as a parameter the state of the room to which you want to switch.
OK. Enough theory, let's move on to practice. We create the state machine and the basis for the controllers. We add its controller to the player object and throw it on the stage. We force the level controller to load the very first level as the main one, it will be our introductory one. In the projectile controller, we add actual links to two types of projectiles - the player and enemies, and allow the player to spawn them by clicking on the arrows. As a result, we get the finished functional of movement between levels.
By the way. The game starts with the main "game" scene, the scene structure at the moment is:
At the root is a 2D node for the world and a regular node for game_manager, which carries the manager script and the state of the game machine. Level, mobs, projectiles, player - objects with corresponding controllers.
Next, we throw door exit points onto the stage, draw a splash screen with controls for the first room, and block the controls in the first room until the splash screen is displayed. Next, when touching the door trigger, we make calls to a new room state with loading a random room from the list. We move the player to the opposite door, following the direction of his movement.
Note: triggers report events to the conditional event bus. But this time, I didn’t make my own bus, but used the Godot input system, creating my own trigger event instance and sending it to the input system. As a result, my events from triggers come to all _Input in the game. In a slightly larger game, this should not be done, as an overabundance of events can clog the input channel. The best solution would be to create your own event bus with different themes/channels/subscriptions.
Next time I'll talk about working on enemies and on the boss.