Problem with text command

Hi, I am trying to run a simple hangman game, and when the game ends I wanted the system to exit. To do this I inserted a delay after the screen ‘notified’ the user they had won or lost, and then used the exit command. But the code seems to be using the delay, then writing the text, and immediatly exiting with no time for the user to view the final result. (It’s line 63 and 64 in the code). Thank you!

char t = 't';
char a = 'a';
char n = 'n';
char g = 'g';
char l = 'l';
char e = 'e';
char d = 'd';
int x = 0;
int y = 265;
int newscore = 0;
int score = 0;
char priorKey = 0;

void setup()
{
  size(500,500);
  background(200,60,90);
  textSize(20);
  stroke(255);

}

void draw()
{
  text("Welcome to Hangman!", 15,20);
  text( "_ _ _ _ _ _ _", 50,450);
  noFill();
  strokeWeight(10);
  rect(250,400,220,50); //used letters box
  
  //the following is the gallows
  line(350,100,350,150);
  line(350,100,450,100);
  line(450,100,450,350);
  line(420,350,480,350);
  
  if (keyPressed)
  {
    if (key != priorKey){
    if( key == t)       {text("t",50,440); x = x + 1;}
    else if( key == a)    {text("a",65,440); x = x + 1;}
    else if( key == n)    {text("n",80,440);  x = x + 1;}
    else if( key == g)   { text("g",98,440);  x = x + 1;}
    else if( key == l)    {text("l",118,440); x = x + 1;}
    else if( key == e)    {text("e",129,440); x = x + 1;}
    else if( key == d)    {text("d",144,440); x = x + 1;}
    else {
      text(key,y,425);
      y = y + 10;
      newscore = newscore + 1;
    }
    }
    priorKey = key;
  }
  strokeWeight(3);
    if (newscore==1)      ellipse(350,175,50,50); //head
    if (newscore==2)      line(350,200,350,275); //body
    if (newscore==3)      line(350,230,320,210); //left arm
    if (newscore==4)      line(350,230,380,210); //right arm
    if (newscore==5)      line(350,275,320,305); //left leg
    if (newscore==6)   {
    line(350,275,380,305); //right leg
    text("YOU LOSE",150,200);
    delay(3000);
    exit();
    }
  if (x == 7){
   text("Congradulations, you've figured it out!", 100,200); 
   delay(3000);
   exit();
  }
  
}

delay() is not the function you want. It does not do what you think it does. It is not useful in this context.

So the first thing to do is: REMOVE ALL CALLS TO delay().

I’m serious. Your code will be 200% better off without them.

What your sketch needs next is the concept of having some internal state. There are three states we care about. The first state is when we are playing the game. The second state is when we have won the game. The third state is when we have lost the game.

We’ll get back to how to do a time delay in a second.

Add a new variable, state that is the number of the state your sketch is in. When the sketch starts, you want to be in state 1, the playing-game state.

int state;
int time;

void setup(){
  size( ... ):
  state = 1;
  // ...
}

Now in draw(), you can do different things depending one which state your sketch is in.

void draw(){
  if( state == 1 ){
    // Playing te game state...
  }
  if( state == 2 ){
    // You won! state...
  }
  if( state == 3 ){
    // You lost... state.
  }
}

What goes in the playing-game state is what you already have in draw() - except for what is drawn when the game’s over. Those you can put in the win and lost states. Then (in the game playing state!) when you detect that the game has been won or lost, you simply update the state variable.

Now the timer bit. When you go into one of the win/loss states, record the current time!

if( newScore == 6 ){
  state = 3; // Lost!
  time = millis();
}
if( x == 7 ){
  state = 2; // Won!
  time = millis();
}

Now in states 2 or 3, check to see if 3 seconds have passed since you entered that state:

if( millis() > time + 3000 ){
  exit();
}

Thank you so much, the code works smoothly now.
Also, if you don’t mind, would you be able to explain why its incorect to use the delay functon here?

1 Like

Sure.

Imagine someone is painting a picture. They start with a blank canvas, and put some paint on it. When they are done, they turn the canvas around and let you see the picture.

Now pretend that the painter is a robot. The robot paints very fast - so fast that you can’t even see him painting. Seriously, he’s doing 60 painting a SECOND. But like the previous painter, he doesn’t show you the paintings until he’s DONE with one of them. So while you’re seeing a lot of painting happening very fast, you only get to see finished paintings.

draw() is this robotic painter.

So, what does delay() do? It tells the robotic painter to TAKE A BREAK. This means that he’s going to stop painting for a while. But it also means that HE’S NOT GOING TO SHOW YOU ANY NEW PAINTINGS while he’s on his break.

What you wanted him to do was to paint this image, and then show it to you, and then take a break for 3 seconds.

But that code with delay() isn’t saying that. Instead, it says “start work on a painting, take a three second break where you’re not doing anything, and then show me the painting”. Which is a little different, and not what you want at all!

This isn’t to say that delay() is a useless function. It does have uses when you are using multiple threads. But it’s a constant source of trouble for (especially new) people who just want to have their draw() functions take a break.

In short: it’s not “show me a painting and stop for a while”, it’s “just stop painting for a while, and don’t bother showing me the one you’re working on”.

2 Likes

Great question! and Great explanation on the delay() function.