Timing with millis()

hey guys i am currently trying to recreate the game bang which is for mobile phone i wanted to give the player a second to get ready so i wrote this code:

long previous;

void setup() {
  size(600, 600);
}

void draw() {
  previous = millis();
  while (millis() - previous <= 1000) {
  }
  background(0);
  previous = millis();
  while (millis() - previous <= 1000) {
  }
  background(255);
}

But when i start the skecth it waits a second background becomes white and does nothing else. What can i do to solve this problem?

Thanks.

Tagged:

Answers

  • Answer ✓

    Draw updates the screen only once at the very end of it

    So everything that happens before adds up and could disappear

    So instead of using while set a boolean playerGetsReady which directs if you show screen A or B (or use a int state which can have 3 or more states

    Set this boolean var depending on your timer

    see reference for boolean

  • edited July 2017

    thanks for your advices guys i have read Chrisir's comment and koogs's links and i finally came up with this code:

        int frame;
        String s[];
        void setup()
        {
          s = new String[2];
          s[0] = "Ready";
          s[1] = "Steady";
          size(600, 600);
          textAlign(CENTER);
          textSize(64);
        }
    
        void draw()
        {
          background(0);
          text(s[frame], width / 2, height / 2);
          delay(1000);
          frame = ++frame % s.length;
        }
    

    i know that its not the best it can be but it works Thanks

    i will try to remove the function delay() from my code later

  • edit post, highlight code, press ctrl-o to format code.

  • That approach doesn't give you space to work further with the code and make a game

  • You were closer to a solution before. You should not use delay().

    int time;
    boolean is_white;
    
    void setup(){
      size(440,440);
      is_white = true;
      time = millis() + 1000;
    }
    
    void draw(){
      if( is_white ){
        background(255);
      } else {
        background(0);
      }
      if( millis() > time ){
        time = millis() + 1000;
        is_white = !is_white;
      }
    }
    

    Here there is a boolean, is_white, that tracks if we are in the white state or not. When draw runs, it draws a white background if you are in the white state (when is_white is true). If you are not in the white state (is_white is false), it draws a black background instead.

    Then it checks to see if a second has passed since the last time a second had passed. If it has, it remembers when the next time that a second will have passed will be, and toggles the value of is_white. This causes the background to change every second.

  • OK TfGuy44 i fixed my code and this is what it looks like now:

    int previous;
    int frame;
    String words[];
    boolean state = false;
    void setup()
    {
      words = new String[2];
      words[0] = "Ready";
      words[1] = "Steady";
      size(500, 500);
      background(0);
      textSize(64);
      textAlign(CENTER);
      previous = millis();
    }
    
    void draw()
    {
      background(0);
      if (state)
      {
        text(words[frame], width / 2, height / 2);
        if(millis() - previous >= 1000) frame++;
        if(frame == 2) noLoop();
      }
    }
    
    void mousePressed()
    {
      state = true;
      previous = millis();
    }
    
  • this is even worse.

    with noLoop you can't play...

  • // timer
    int previousTime;
    
    // array of words for start of the game 
    String words[];
    
    // constants 
    final int stateReady  =0; 
    final int stateSteady =1;
    final int stateGame   =2;
    int state = stateReady;
    
    void setup()
    {
      size(500, 500);
    
      words = new String[3];
      words[0] = "Ready";
      words[1] = "Steady";
      words[2] = "Play";
    
      background(0);
      textSize(64);
      textAlign(CENTER);
      previousTime = millis();
    }//setup
    
    void draw()
    {
      background(0);
      // using state to know what to do 
      // nothing allowed in draw() outside this if...else if-clause (except background())
      if (state==stateReady)
      {
        text(words[0], width / 2, height / 2);
        if (millis() - previousTime >= 1000) {
          state=stateSteady;
          previousTime = millis();
        }
      } else if (state==stateSteady) 
      {
        fill(255, 0, 0); 
        text(words[1], width / 2, height / 2);
        if (millis() - previousTime >= 1000) { 
          state=stateGame;
          previousTime = millis();
        }
      }// else if
      else if (state==stateGame) 
      {
        fill(0, 0, 255); 
        text(words[2], width / 2, height / 2);
        if (millis() - previousTime >= 1000) { 
          words[2]+=".";
          previousTime = millis();
        }
      }// else if
      else {
        // error
      }
    }// draw 
    
    // --------------------------------------------
    // Inputs 
    
    void mousePressed()
    {
      // using state to know what to do with mouse inputs
      if (state==stateReady)
      {
        state=stateSteady;
        previousTime = millis();
      } else if (state==stateSteady) 
      {
        state=stateGame;
        previousTime = millis();
      }// else if
      else if (state==stateGame) 
      {
        words[2]+=".";
        previousTime = millis();
      }// else if
      else {
        // error
      }
    }//function 
    //
    
  • edited July 2017

    Hello again guys i am half way done with this game it has a lot of bugs but i wanted to share this with you

    PFont font;
    boolean showInstructions = false;
    boolean winLastLevel = false;
    boolean showTiming = false;
    boolean gameOver = false;
    boolean startTimer = false;
    int level = 1;
    boolean playing = false;
    int wait;
    int previous;
    boolean rs = true;
    int frame;
    boolean waiting = true;
    String words[];
    boolean state = false;
    float timePassed;
    int time1;
    int time2;
    int time3;
    int time4;
    
    void setup()
    {
      font = createFont("Times New Roman", 72);
      textFont(font);
      words = new String[3];
      words[0] = "Ready";
      words[1] = "Steady";
      words[2] = "BANG!!";
      fullScreen();
      background(0);
      textAlign(3);
      time1 = int(random(400, 450));
      time2 = int(random(350, 400));
      time3 = int(random(300, 350));
      time4 = int(random(250, 300));
    }
    
    void draw()
    {
      background(0);
      if (showInstructions)
      {
        textSize(32);
        textAlign(LEFT);
        text("To Return to the Game Press i", 20, height - 20);
        textSize(48);
        textAlign(CENTER);
        text("To Start the Game Press Spacebar", width / 2, 100);
        text("When You See the Word BANG on the Screen Press Spacebar", width / 2, 250);
        text("If You Lose the Game You can Restart it by Pressing r", width / 2, 400);
        text("If You Win the Game Press r to Skip to the Next Level", width / 2, 550);
      } else
      {
        textSize(32);
        textAlign(LEFT);
        text("RSBang BETA V0.1 Build 0015", 10, 30);
        text("For Instructions Press i", 20, height - 20);
        textSize(72);
        textAlign(CENTER);
        if (gameOver)
        {
          winorlose();
        }
        text("Level: " + level, width / 2, height / 2 - 300);
        if (startTimer)
        {
          text(words[2], width / 2, height / 2);
        }
        if (startTimer && gameOver)
        {
          text(timePassed / 1000 + " Seconds", width / 2, height / 2 + 300);
        }
        if (state)
        {
          if (rs)
          {
            fill(255);
            text(words[frame], width / 2, height / 2);
          }
          if (millis() - previous >= 1000 && frame < 1) frame++;
          if (frame == 1)
          {
            if (waiting)
            {
              waiting = false;
              previous = millis();
              wait = int(random(800, 10000));
            }
            if (showTiming) showTimingValues();
            if (millis() - previous >= wait)
            {
              rs = false;
              previous = millis();
              startTimer = true;
            }
          }
        }
      }
    }
    
    void keyPressed()
    {
      if (key == 'i') showInstructions = !showInstructions;
      if (key == 't') showTiming = !showTiming;
      if (key == ' ')
      {
        if (!playing)
        {
          playing = true;
          state = !state;
          previous = millis();
        }
        if (startTimer)
        {
          timePassed = millis() - previous;
          gameOver = true;
        }
      }
      if (key == 'r')
      {
        gameOver = false;
        startTimer = false;
        if (level < 4 && winLastLevel)
        {
          level++;
          winLastLevel = false;
        }
        playing = true;
        wait = 0;
        previous = 0;
        rs = true;
        frame = 0;
        waiting = true;
        state = false;
        timePassed = 0;
        time1 = int(random(400, 450));
        time2 = int(random(350, 400));
        time3 = int(random(300, 350));
        time4 = int(random(250, 300));
        state = true;
        previous = millis();
      }
    }
    
    void showTimingValues()
    {
      if (!(millis() - previous >= wait) && !startTimer) text(millis() - previous, width / 2, height / 2 + 100); 
      else text(wait, width / 2, height / 2 + 100);
      text(wait, width / 2, height / 2 + 200);
    }
    
    void winorlose()
    {
      if (level == 1)
      {
        if (time1 >= timePassed)
        {
          win();
        }
      }
      if (level == 2)
      {
        if (time2 >= timePassed)
        {
          win();
        }
      }
      if (level == 3)
      {
        if (time3 >= timePassed)
        {
          win();
        }
      }
      if (level == 4)
      {
        if (time4 >= timePassed)
        {
          win();
        }
      }
      if (level == 1)
      {
        if (time1 < timePassed)
        {
          lose();
        }
      }
      if (level == 2)
      {
        if (time2 < timePassed)
        {
          lose();
        }
      }
      if (level == 3)
      {
        if (time3 < timePassed)
        {
          lose();
        }
      }
      if (level == 4)
      {
        if (time4 < timePassed)
        {
          lose();
        }
      }
    }
    
    void lose()
    {
      winLastLevel = false;
      background(255, 0, 0);
      fill(0);
      text("You LOSE! You SUCKER!", width / 2, height / 2 + 365);
    }
    
    void win()
    {
      winLastLevel = true;
      background(0, 255, 0);
      fill(0);
      text("You WIN!", width / 2, height / 2 + 365);
    }
    
  • Great progress here!!!

    Congrats!!!

    Remark:

    When you stick with my variable state as an integer and implement new states into it like instructions gameOver rs etc., your draw would be much clearer

    Also you might want to make functions to call from draw() so draw becomes leaner

  • thank you for your suggestions chrisir i will post my finished code here when i finish it

  • Great !

Sign In or Register to comment.