Discord
Login
Community
DARK THEME

Simple game state management / switching

Simple state manager

https://microstudio.dev/i/JimB007/simplestatemanager/

About

This demo shows how to create and manage really simple game state switcher. It works by changing a global variable state that points to any one of a number ofobject .. end state blocks.

Each state block is setup up with these functions:

  init()
  go()
  update()
  draw()

By changing the global state variable it is easy to switch to any other state during runtime.

Here is a visual overview of the basics behind the program flow/state switching. In this first set up the 'state' is set to point to the titlepage object. During the main loop the titepages update() and draw() are called.

state1

Now, according to the code here, when SPACEBAR is pressed the 'state' is set to point to the game object. From now on, during the main loop the games update() and draw() are now called.

state2

In this demo a state block is switched via:

  SwitchState(newstate)

newstate is the name of state block that you want to take control of. For example

SwitchState(titlepage) // switch to the titlepage state
SwitchState(maingame) // swith to the maingame state

When a state is switched via the above function its go() function is also called. This makes it easier to manage what you want to do whenever a state is revisited again. Such as reset sprites, variables, and so on ..


Main loop

The main game is typically set up like this. Note how all states are initiallized at the start

init = function()
  titlepage.init() // initialize the titlepage state block
  maingame.init() // initialize the maingame state block
  // .. Contine initializing all remaing state blocks
  state=titlepage // set state to one of the blocks
end

update = function()
  state.update() // Call update() function in the active state()
end

draw = function()
  state.draw() // Call draw() function in the active state()
end

Program flow

Let's suppose the active state is the titlepage code block. In it's update() loop you can switch to another state like so:

  update=function()
    if keyboard.press.SPACE then SwitchState(maingame) end
  end

Likewise from the maingame block you can switch around to any other code block:

  update=function()
    if keyboard.press.P then SwitchState(pausegame) end
  end

The main game loop just constantly calls state.update() and state.draw() so, whatever block the state variable is pointing to gets updated and drawn during runtime.


Challenges

  • See if you can make a gameover state block that is called when the sprite leaves the screen,

  • Continuing from the above challenge offer the option to play again or return to the title page.

  • How about a gamepaused state block when P is pressed?

  • How would you create a universal code block that gets called all of the time, regardless of which state is active? Hint: What is the main loop doing all of the time?

It’s funny, because I was considering asking for examples of state machines in microScript. Granted, I might not yet be literate enough to understand this style completely. But please answer if you can; do you think some of the code for “Meowy’s Adventure“ could be considered a state machine?

https://microstudio.dev/i/mrLman/meowys_adventure/

Meowys Adventure is using what I consider the classic way of controlling the game state, via a 'mode' variable. Typically done in the top-level main loop.

My method a more of a direct 'state switcher', in that the main loop just jumps to whatever object .. end code block you choose. I prefer this 'fire and forget' method, as I don't need a big chunk of if mode==SOMESTATE then checking going on (which happens when more and more modes are added).

Yeah, I can see that for big switches from the menu to actual gameplay. From what I understand though, state machines can be used for situations that are much more local, like below:

updatePlayer = function()
  // detect whether climbing or not
  player.touching_vine = check_collision(player.x, player.y, level.map_name, level.map_width,
    level.map_height).startsWith("vine")
  player.touching_ladder = check_collision(player.x, player.y, level.map_name, level.map_width,
    level.map_height).startsWith("ladder")
  player.climbing = (player.touching_vine or player.touching_ladder) and (not player.landed)
end

This is the code I was originally referring to. Your thoughts?

Yes, I agree. The above is really about controlling the players state, where as my code is all about controlling the main game state directly. In other words, telling the main loop where to put its focus. Image for example a game with this many states:

  • PlayGame
  • GameOver
  • TutorialScreen
  • TitleScreen
  • Settings
  • PauseScreen

My code is all about switching to one of these directly without having to care about much else. The main loop can be told 'Settings' is your new focus, and the others are just dormant.

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community