Help a noob with some code


(Celine) #1

Arduboy community assemble!

Ok, so i’m trying to come up with a simple text game and @crait’s tutorials have been a big help, but I can’t figure out why when I select a player, it would only flash the image + text for arduboy.pressed (A_BUTTON), instead of displaying it till another action is taken.

Technically I could just use the do while function again, but i’m sure there’s a better way to do it…

Let me know how I can continue!

There’s the code:


#include <Arduboy2.h>
Arduboy2 arduboy;

int playerwin = 0;

const unsigned char playerhappy[] PROGMEM  = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 
};

const unsigned char playerdied[] PROGMEM  = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x19, 0xd3, 0xe7, 0xc7, 0x13, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x31, 0x87, 0xcf, 0x87, 0x33, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 
};


void setup() {
  arduboy.begin();
  arduboy.clear();

  delay(400);
  arduboy.setCursor(0,10);
  arduboy.print("Simple text adventure");
  arduboy.print("\n");
  arduboy.print("by celine");
  arduboy.print("\n");
  arduboy.print("Press A to start!");
  arduboy.display();  

  do{
    
  } while( !arduboy.pressed(A_BUTTON) );

}

void loop() {

    //Ask the player to pick a character
    arduboy.clear();
    arduboy.setCursor (0,0);
    arduboy.print("Choose a Player");
    arduboy.print("\n");
    arduboy.print("A: Player 1");
    arduboy.print("\n");
    arduboy.print("B: Player 2");
    arduboy.display();
    
    if (arduboy.pressed(B_BUTTON) == true){
      //press B, player lose
        playerwin = 0;
        arduboy.clear();
        arduboy.drawBitmap(0,0,playerdied,48,48,WHITE);
        arduboy.setCursor (0,50);
        arduboy.print("You Lose!");
        arduboy.display();
    } 
    if (arduboy.pressed(A_BUTTON) == true) {
    // press A, player win
        playerwin = 1;
        arduboy.clear();
        arduboy.drawBitmap(0,0,playerhappy,48,48,WHITE);
        arduboy.setCursor (0,50);
        arduboy.print("You Win!");
        arduboy.display();
  }
 
  arduboy.display();
}

(Holmes) #2

There are two ways to think about buttons on computers… 1) The button was pressed for a moment, or 2) The button is currently being held down.

But before you can do that, at the top of your loop(), be sure to include the following code:

  if (!arduboy.nextFrame())
    return;
  arduboy.pollButtons();

Now, for most cases, @MLXXXp’s great Arduboy2 library supports a function to check if the button was just pressed for a moment, which is called arduboy.justPressed(). I would suggest using this as an expirement to see how things change.

If you’re going to test if a button is currently being held down, that’s when you could use the arduboy.justPressed() function. In the current code, you are only displaying the new text during the time the button is being held down, which may be a fraction of a second.

Now, an alternative would be to have a variable that changes value to record if the button was pressed or not.

You can read more about @MLXXXp’s tips in this thread: Best practices for button handling


(Scott) #3

@Celinebins,
@crait has done a good job of answering you’re question, so I won’t say anything more about it.

However, after looking at your code I’d like to point out that there’s a function, println(), which works just like print but adds a newline at the end of whatever is printed. The print commands at the start of loop() in your posted code could be simplified to:

    arduboy.println("Choose a Player");
    arduboy.println("A: Player 1");
    arduboy.print("B: Player 2");

But going further, if you have multiple print() calls in a row that are all quoted strings, you can combine them into just one print() call:

    arduboy.print("Choose a Player\nA: Player 1\nB: Player 2");

And finally, if you’re writing a sketch that contains lots of quoted text to print, you may find yourself running out of RAM to hold all that text. You can instead place these strings in program memory using the F() macro (see the topic at the end of this link):

    arduboy.print(F("Choose a Player\nA: Player 1\nB: Player 2"));

(Celine) #4

so i added the justpressed and it recognizes that i just mean to press it once, but it also only displays the winning / losing screen for just a second, instead of keeping it there till another action is taken… what’s missing?


(Mike McRoberts) #5

Can we see your code please.


(Celine) #6
#include <Arduboy2.h>
Arduboy2 arduboy;

int playerwin = 0;

const unsigned char playerhappy[] PROGMEM  = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 
};

const unsigned char playerdied[] PROGMEM  = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x19, 0xd3, 0xe7, 0xc7, 0x13, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x31, 0x87, 0xcf, 0x87, 0x33, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 
};


void setup() { 
  arduboy.begin();
  arduboy.clear();

  delay(400);
  arduboy.setCursor(0,10);
  arduboy.println("Simple text adventure");
  arduboy.println("by celine");
  arduboy.println("Press A to start!");
  arduboy.display();  

  do{
    
  } while( !arduboy.pressed(A_BUTTON) );

}

void loop() {

    if (!arduboy.nextFrame())
    return;
  arduboy.pollButtons();

    //Ask the player to pick a character
    arduboy.clear();
    arduboy.setCursor (0,0);
    arduboy.println("Choose a Player");
    arduboy.println("A: Player 1");
    arduboy.println("B: Player 2");
    arduboy.display();
    
    if (arduboy.justPressed(B_BUTTON) == true){
      //press B, player lose
        playerwin = 0;
        arduboy.clear();
        arduboy.drawBitmap(0,0,playerdied,48,48,WHITE);
        arduboy.setCursor (0,50);
        arduboy.print("You Lose!");
        arduboy.display();
    } 
    if (arduboy.justPressed(A_BUTTON) == true) {
    // press A, player win
        playerwin = 1;
        arduboy.clear();
        arduboy.drawBitmap(0,0,playerhappy,48,48,WHITE);
        arduboy.setCursor (0,50);
        arduboy.print("You Win!");
        arduboy.display();
  }
  
  arduboy.display();
  
}

(Mike McRoberts) #7

Your code does the actions after the key is pressed and then jumps right back into the main loop so yes, this is what you’ve programmed it to do.

An IF statement will run the code inside its block only once and then return to the function it is inside.

What did you mean for it to do ?


#8

@Celinebins try this, the code should be self explaining :smiley:

#include <Arduboy2.h>
Arduboy2 arduboy;

#define GAME_INTRO                0
#define GAME_START                1
#define PLAYER_ONE_WINS           2
#define PLAYER_TWO_WINS           3

byte gameProgress = 0;

const unsigned char playerhappy[] PROGMEM  = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00,
};

const unsigned char playerdied[] PROGMEM  = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x19, 0xd3, 0xe7, 0xc7, 0x13, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x31, 0x87, 0xcf, 0x87, 0x33, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00,
};


void setup() {
  arduboy.begin();
  arduboy.setFrameRate(30);
}

void loop() {

  if (!arduboy.nextFrame()) return;
  arduboy.pollButtons();
  arduboy.clear();

  switch (gameProgress)
  {
    case GAME_INTRO:
      arduboy.setCursor(0, 10);
      arduboy.println("Simple text adventure");
      arduboy.println("by celine");
      arduboy.println("Press A to start!");
      if (arduboy.justPressed(A_BUTTON)) gameProgress = GAME_START;
      break;
    case GAME_START:
      arduboy.setCursor (0, 0);
      arduboy.println("Choose a Player");
      arduboy.println("A: Player 1");
      arduboy.println("B: Player 2");
      if (arduboy.justPressed(A_BUTTON)) gameProgress = PLAYER_ONE_WINS;
      else if (arduboy.justPressed(B_BUTTON)) gameProgress = PLAYER_TWO_WINS;
      break;
    case PLAYER_ONE_WINS:
      arduboy.drawBitmap(0, 0, playerhappy, 48, 48, WHITE);
      arduboy.setCursor (0, 50);
      arduboy.print("You Win!");
      if (arduboy.justPressed(A_BUTTON | B_BUTTON)) gameProgress = GAME_INTRO;
      break;
    case PLAYER_TWO_WINS:
      arduboy.drawBitmap(0, 0, playerdied, 48, 48, WHITE);
      arduboy.setCursor (0, 50);
      arduboy.print("You Lose!");
      if (arduboy.justPressed(A_BUTTON | B_BUTTON)) gameProgress = GAME_INTRO;
      break;
  }
  arduboy.display();
}

(Josh Goebel) #9

Even better split the states out into their own functions instead of having a huge loop.


(Celine) #10

The states… meaning in multiple files?

Thanks @JO3RI! spent some time reading up on the switch function https://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm

I noticed however that there isn’t any “default” in the above code, but it was given in the example… I guess defaults for switch function are not 100% necessary?


#11

Word of caution, the switch statement can work out a lot larger than an if/elseif/else statement


(Josh Goebel) #12

Please show some real proof of this. They are both really just syntactic sugar for the same thing if that is how you are using them. IE: There shouldn’t be much of a real difference after compiled and optimized.


#13

I believe the following are equivalent (not able to run on arduboy to confirm, so might have a bug).

Switch statement, 494 bytes

 uint8_t some_state = 0;

 #define DO_A 1
 #define DO_B 2
 #define DO_C 3
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {
    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
    }
/*
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
    */
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_A;
 }

If Else. 480 bytes.

 uint8_t some_state = 0;

 #define DO_A 1
 #define DO_B 2
 #define DO_C 3
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {
  /*
    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
    }
*/
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
    
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_A;
 }  

Likewise, if I replace the uint8_t with an enum (to ensure exhaustive cases, just in case that is the issue.
Swicth is 514 bytes.

enum todo {
  DO_A,
  DO_B,
  DO_C  
};

todo some_state = DO_A;
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {

    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
    }

/*
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
  */  
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_A;
 }

If Else is 500 bytes

enum todo {
  DO_A,
  DO_B,
  DO_C  
};

todo some_state = DO_A;
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {
/*
    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
    }
  */
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
   
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_A;
 }   

Adding in a DO_D with the same format increases the code accordingly as follows.
Switch has 534 bytes.

enum todo {
  DO_A,
  DO_B,
  DO_C,
  DO_D  
};

todo some_state = DO_A;
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {

    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
      case DO_D: dofunc_d(); break;  
    }

  /*
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
    else if (some_state == DO_D){ dofunc_d(); }
  */ 
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_D;
 }
 
 void dofunc_d() {
   some_state = DO_A;
 }

If else has 512 bytes.

enum todo {
  DO_A,
  DO_B,
  DO_C,
  DO_D  
};

todo some_state = DO_A;
 
 void setup() { 
   some_state = DO_A;
 }

 void loop() {
/*
    switch (some_state) {
      case DO_A: dofunc_a(); break;  
      case DO_B: dofunc_b(); break;  
      case DO_C: dofunc_c(); break;  
      case DO_D: dofunc_d(); break;  
    }
   */
    if (some_state == DO_A){ dofunc_a(); }
    else if (some_state == DO_B){ dofunc_b(); }
    else if (some_state == DO_C){ dofunc_c(); }
    else if (some_state == DO_D){ dofunc_d(); }
  
 }

 void dofunc_a() {
   some_state = DO_B;
 }

 void dofunc_b() {
   some_state = DO_C;
 }
 
 void dofunc_c() {
   some_state = DO_D;
 }
 
 void dofunc_d() {
   some_state = DO_A;
 } 

NOW, Please note that I do not claim to understand why this is. My initial belief was that they were equivalent, and there is probably some way to make them so that I am not aware of. If so, let me know so I can implement it :smiley:

It is also why in my comment I said ‘can work out’ because in naive use cases like I demonstrated above, it does work out worse.


(Scott) #14

No, each state is made a separate function but those functions don’t have to go in separate files.

#include <Arduboy2.h>
Arduboy2 arduboy;

#define GAME_INTRO                0
#define GAME_START                1
#define PLAYER_ONE_WINS           2
#define PLAYER_TWO_WINS           3

byte gameProgress = 0;

const unsigned char playerhappy[] PROGMEM  = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x3, 0x3, 0x3, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00,
};

const unsigned char playerdied[] PROGMEM  = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x19, 0xd3, 0xe7, 0xc7, 0x13, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x31, 0x87, 0xcf, 0x87, 0x33, 0x79, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x00, 0x00, 0x00, 0x00, 0x00,
};


void setup() {
  arduboy.begin();
  arduboy.setFrameRate(30);
}

void loop() {

  if (!arduboy.nextFrame()) return;
  arduboy.pollButtons();
  arduboy.clear();

  switch (gameProgress)
  {
    case GAME_INTRO:
      gameIntro();
      break;
    case GAME_START:
      gameStart();
      break;
    case PLAYER_ONE_WINS:
      playerOneWins();
      break;
    case PLAYER_TWO_WINS:
      playerTwoWins();
      break;
  }
  arduboy.display();
}

void gameIntro() {
  arduboy.setCursor(0, 10);
  arduboy.println("Simple text adventure");
  arduboy.println("by celine");
  arduboy.println("Press A to start!");
  if (arduboy.justPressed(A_BUTTON)) gameProgress = GAME_START;
}

void gameStart() {
  arduboy.setCursor (0, 0);
  arduboy.println("Choose a Player");
  arduboy.println("A: Player 1");
  arduboy.println("B: Player 2");
  if (arduboy.justPressed(A_BUTTON)) gameProgress = PLAYER_ONE_WINS;
  else if (arduboy.justPressed(B_BUTTON)) gameProgress = PLAYER_TWO_WINS;
}

void playerOneWins() {
  arduboy.drawBitmap(0, 0, playerhappy, 48, 48, WHITE);
  arduboy.setCursor (0, 50);
  arduboy.print("You Win!");
  if (arduboy.justPressed(A_BUTTON | B_BUTTON)) gameProgress = GAME_INTRO;
}

void playerTwoWins() {
  arduboy.drawBitmap(0, 0, playerdied, 48, 48, WHITE);
  arduboy.setCursor (0, 50);
  arduboy.print("You Lose!");
  if (arduboy.justPressed(A_BUTTON | B_BUTTON)) gameProgress = GAME_INTRO;
}

At this point, you could consider changing the switch into calls to the functions by pointers in an array indexed by gameProgress, but that’s a more advanced topic better left to a later time.

A default is only needed if it’s possible that none of the case statements you provide match the value that the switch is testing. In this case (no pun intended) there will always be a match, so a default would never be executed.