State Machines - Organising Variables: Difference between revisions

From Arduboy Wiki
Jump to navigation Jump to search
(Created page with " # Overview In this section, we will look at how to organise variables in our state machine. As your games grow in complexity, you will invariably end up with numerous variables to support the various aspects (states!) of your game. It might not sound like much, but naming and remembering all the variable names you create can be quite arduous. This simple tutorial uses simple `structs` to group variables for a class together. When using the variables, the struct n...")
 
No edit summary
Line 1: Line 1:
 
== Overview ==
# Overview
 
In this section, we will look at how to organise variables in our state machine.   
In this section, we will look at how to organise variables in our state machine.   


As your games grow in complexity, you will invariably end up with numerous variables to support the various aspects (states!) of your game. It might not sound like much, but naming and remembering all the variable names you create can be quite arduous.   
As your games grow in complexity, you will invariably end up with numerous variables to support the various aspects (states!) of your game. It might not sound like much, but naming and remembering all the variable names you create can be quite arduous.   


This simple tutorial uses simple `structs` to group variables for a class together. When using the variables, the struct name is used to qualify them making it possible to have the same variable - such as a simple counter - available in each state with the same name but be independent of each other.
This simple tutorial uses simple <code>structs</code> to group variables for a class together. When using the variables, the struct name is used to qualify them making it possible to have the same variable - such as a simple counter - available in each state with the same name but be independent of each other.
 


## Defining a Structure for a State
== Defining a Structure for a State ==
If you haven't already used a <code>struct</code> before, it is a simple way to group a bunch of related variables together. But as you will see later, we can add functions to the <code>struct</code> itself that operate on the variables within.


If you haven't already used a `struct` before, it is a simple way to group a bunch of related variables together. But as you will see later, we can add functions to the `struct` itself that operate on the variables within.
Below is a simple structure for a title screen.  As you can see it is rather unimpressive with a single <code>counter</code> variable.  
 
Below is a simple structure for a title screen.  As you can see it is rather unimpressive with a single `counter` variable.  


<pre>struct TitleScreenVars {
<pre>struct TitleScreenVars {
Line 25: Line 21:
</pre>
</pre>


After the `struct` definition, we then define a variable using the structure type.  From then on, we can refer to the structure's variables using the following syntax:
After the <code>struct</code> definition, we then define a variable using the structure type.  From then on, we can refer to the structure's variables using the following syntax:


<pre>TitleScreenVars titleScreenVars;
<pre>TitleScreenVars titleScreenVars;
titleScreenVars.counter = 5;</pre>
titleScreenVars.counter = 5;</pre>


We can define structures for all our states.  The example below shows a struct with a few more variables - including one named `counter` which is a different variable to the one in the `TitleScreenVars` structure despite the same name.
We can define structures for all our states.  The example below shows a struct with a few more variables - including one named <code>counter</code> which is a different variable to the one in the <code>TitleScreenVars</code> structure despite the same name.


<pre>struct GamePlayVars {
<pre>struct GamePlayVars {
Line 46: Line 42:
</pre>
</pre>


As mentioned earlier, we can add functions to the structure which can operate on the variables contained within.  For example, a `reset()` function will set our score and lives to the values we want at the start of a game.
As mentioned earlier, we can add functions to the structure which can operate on the variables contained within.  For example, a <code>reset()</code> function will set our score and lives to the values we want at the start of a game.


<pre>struct GamePlayVars {
<pre>struct GamePlayVars {
Line 62: Line 58:
</pre>
</pre>


## Using the Structure Variables
== Using the Structure Variables ==
To demonstrate how to use the structure variable, the title state from the previous section has been modified so that the words 'Title Screen!' will scroll left to right and wrap around the screen again.  This will be controlled by increasing the <code>counter</code> variable within the structure.


To demonstrate how to use the structure variable, the title state from the previous section has been modified so that the words 'Title Screen!' will scroll left to right and wrap around the screen again.  This will be controlled by increasing the `counter` variable within the structure.
As we discussed in the previous section, we can use the <code>_Init()</code> function to initialise variables with default values prior to executing the state code. To ensure that the words start in the centre of the screen when the state is first displayed, the <code>counter</code> is set to <code>26</code> which, considering the length of the text to display, places it in the centre of the screen.
 
As we discussed in the previous section, we can use the `_Init()` function to initialise variables with default values prior to executing the state code. To ensure that the words start in the centre of the screen when the state is first displayed, the `counter` is set to `26` which, considering the length of the text to display, places it in the centre of the screen.


<pre>
<pre>
Line 77: Line 72:
</pre>
</pre>


In our main state function, we simply increase the `counter` variable of the `titleScreenVars` structure using the qualified name (`titleScreenVars.counter`) and use it to position the text.
In our main state function, we simply increase the <code>counter</code> variable of the <code>titleScreenVars</code> structure using the qualified name (<code>titleScreenVars.counter</code>) and use it to position the text.


<pre>void title() {
<pre>void title() {
Line 105: Line 100:


Simple right?  
Simple right?  
Believe me, when you are building the next CyberPunk game you will need little tricks like this to help keep your sanity.


<div  style="width: 600px; padding: 15px; border: 1px solid; background-color: ligthgrey; box-shadow: 10px 10px 5px grey;">
<div  style="width: 600px; padding: 15px; border: 1px solid; background-color: ligthgrey; box-shadow: 10px 10px 5px grey;">
<span style="font-size: 160%">Your Turn</span>
<span style="font-size: 160%">Your Turn</span>
Copy the `GamePlayVars` structure definition from above and add it to the program below the existing structure definition.  In the game play state, reset the variables in the `_Init()` function.  Increase the score continually in the main state function and render it on screen.
 
Copy the <code>GamePlayVars</code> structure definition from above and add it to the program below the existing structure definition.  In the game play state, reset the variables in the <code>_Init()</code> function.  Increase the score continually in the main state function and render it on screen.
</div>
</div>

Revision as of 05:53, 22 June 2024

Overview

In this section, we will look at how to organise variables in our state machine.

As your games grow in complexity, you will invariably end up with numerous variables to support the various aspects (states!) of your game. It might not sound like much, but naming and remembering all the variable names you create can be quite arduous.

This simple tutorial uses simple structs to group variables for a class together. When using the variables, the struct name is used to qualify them making it possible to have the same variable - such as a simple counter - available in each state with the same name but be independent of each other.

Defining a Structure for a State

If you haven't already used a struct before, it is a simple way to group a bunch of related variables together. But as you will see later, we can add functions to the struct itself that operate on the variables within.

Below is a simple structure for a title screen. As you can see it is rather unimpressive with a single counter variable.

struct TitleScreenVars {

  int8_t counter = 0;

};

TitleScreenVars titleScreenVars;

After the struct definition, we then define a variable using the structure type. From then on, we can refer to the structure's variables using the following syntax:

TitleScreenVars titleScreenVars;
titleScreenVars.counter = 5;

We can define structures for all our states. The example below shows a struct with a few more variables - including one named counter which is a different variable to the one in the TitleScreenVars structure despite the same name.

struct GamePlayVars {

  uint8_t counter = 0;
  uint8_t score = 0;
  uint8_t lives = 0;

  void reset() {
    score = 0;
    lives = 3;
  }
  
};

As mentioned earlier, we can add functions to the structure which can operate on the variables contained within. For example, a reset() function will set our score and lives to the values we want at the start of a game.

struct GamePlayVars {

  uint8_t counter = 0;
  uint8_t score = 0;
  uint8_t lives = 0;

  void reset() {
    score = 0;
    lives = 3;
  }
  
};

Using the Structure Variables

To demonstrate how to use the structure variable, the title state from the previous section has been modified so that the words 'Title Screen!' will scroll left to right and wrap around the screen again. This will be controlled by increasing the counter variable within the structure.

As we discussed in the previous section, we can use the _Init() function to initialise variables with default values prior to executing the state code. To ensure that the words start in the centre of the screen when the state is first displayed, the counter is set to 26 which, considering the length of the text to display, places it in the centre of the screen.

void title_Init() {

  titleScreenVars.counter = 26;
  gameState = GameState::Title;

}

In our main state function, we simply increase the counter variable of the titleScreenVars structure using the qualified name (titleScreenVars.counter) and use it to position the text.

void title() {

  ...

  // Update Counter ..

  titleScreenVars.counter++;

  if (titleScreenVars.counter == 127) {

    titleScreenVars.counter = -127;

  }


  // Render screen ..

  arduboy.setCursor(titleScreenVars.counter, 20);
  arduboy.print(F("Title Screen!"));

  ...

}

Simple right?

Your Turn

Copy the GamePlayVars structure definition from above and add it to the program below the existing structure definition. In the game play state, reset the variables in the _Init() function. Increase the score continually in the main state function and render it on screen.