Redraw after delay

Hey everyone,

I'm trying to redraw my window after a certain delay and I've already written a working method: (Shortened to simplify it)

void setup() {
  size(1000, 100);

  fill(0, 0, 0);
  show();
  delay(1000);

  fill(255, 0, 0);
  show();
  delay(1000);

  fill(0, 255, 0);
  show();
  delay(1000);

  fill(0, 0, 255);
  show();
}

void show() {
  rect(0, 0, width, height);
}

void delay(int wait) {
  int startTime = millis();
  while(millis() - startTime < wait) {
  }
}

The only problem is that the program won't redraw properly after each delay but only shows the end result. How do I fix this?

Thanks in advance

PS: Sorry if there are any grammar mistakes :)

Answers

  • @Kaes3kuch3n --

    In Processing the normal method for redrawing after a set delay (as in animation) is to use draw() and specify the delay in setup with frameRate().

    If you have a sketch with no draw() loop the screen will be updated when the sketch returns. If you have a draw() loop the screen will update each time draw() returns.

  • While I don't think you want to do animation by specifying every single frame, here is an example of your colored rectangles only using frame timing and loading of per-frame colors:

    void setup() {
      size(200, 200);
      frameRate(1);
    }
    
    void draw(){
      background(0);
      myFill(frameCount);
      rect(10, 10, width-20, height-20);
    }
    
    void myFill(int frame){
      switch(frame){
        case 1: fill(0, 0, 0);
          break;
        case 2: fill(255, 0, 0);
          break;
        case 3: fill(0, 255, 0);
          break;
        case 4: fill(0, 0, 255);
          break;
        default: fill(255, 255, 255);
          break;
      }
    }
    
  • The problem is that I need the delays to be a) variable, and b) exact so I can't use frameRate() (at least as far as I know).

    Is there any way to draw something and change it's color after a certain amount of time multiple times in a row?

  • If you need variable delays: embed your drawing code in draw() running at a high frameRate(), and skip frames until you get to your next frame using a timer. You still need for draw() to return in order to update the screen.

  • Why does my code work when I remove a delay? (It shows the red rectangle when I remove the first delay and so on)

  • edited January 2017

    Okay, this is my whole project: I'm trying to build (kind of) a simulator for an rgb led strip which uses a specific library. I don't own this led strip but I'm trying to write a program for it.

    1st tab:

    int ledCount = 10;
    
    LEDStrip strip = new LEDStrip(ledCount);
    
    void setup() {
    
      strip.begin();
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(1, strip.Color(50, 50, 50));
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(3, strip.Color(255, 255, 255));
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(5, strip.Color(255, 0, 0));
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(7, strip.Color(0, 255, 0));
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(9, strip.Color(0, 0, 255));
      strip.show();
    }
    
    void draw() {
    
      strip.setPixelColor(4, strip.Color(100, 100, 100));
      strip.show();
    
      delay(1000);
    
      strip.setPixelColor(4, strip.Color(0, 0, 0));
      strip.show();
    
      delay(1000);
    }
    

    2nd tab:

    class LEDStrip {
    
      LED[] leds;
    
      LEDStrip(int count) {
        leds = new LED[count];
      }
    
      void begin() {
        for (int i = 0; i < leds.length; i++) {
          leds[i] = new LED();
          leds[i].setColor(new int[]{0, 0, 0});
        }
      }
    
      void show() {
    
        if(debug) {
          println("Redrawing...");
        }
    
        for (int i = 0; i < strip.leds.length; i++) {
    
          int x = (i % 10);
          int y = ((i - (i % 10)) / 10);
    
          if(debug) {
            println(strip.leds[i].getColor()[0] + ", " + strip.leds[i].getColor()[1] + ", " + strip.leds[i].getColor()[2]);
          }
    
          noStroke();
          fill(strip.leds[i].getColor()[0], strip.leds[i].getColor()[1], strip.leds[i].getColor()[2]);
          rect((x * 10 * scale), (y * 10 * scale), ((x * 10 * scale) + 10 * scale), ((y * 10 * scale) + 10 * scale));
        }
    
        stroke(0);
    
        if (width > 10 * scale) {
          for (int i = 10 * scale; i < width; i += (10 * scale)) {
            line(i, 0, i, height);
          }
        }
    
        if (height > 10 * scale) {
          for (int i = 10 * scale; i < height; i += 10 * scale) {
            line(0, i, width, i);
          }
        }
    
        if(debug) {
          println("... done!");
          println();
        }
    
      }
    
      void setPixelColor(int led, int[] c) {
        leds[led].setColor(c);
      }
    
      int[] Color(int r, int g, int b) {
        return new int[]{r, g, b};
      }
    }
    
    class LED {
    
      int red = 0;
      int green = 0;
      int blue = 0;
    
      LED() {
      }
    
      void setColor(int[] rgb) {
        red = rgb[0];
        green = rgb[1];
        blue = rgb[2];
      }
    
      int[] getColor() {
        return new int[]{red, green, blue};
      }
    }
    

    3rd tab:

    int scale = 10;
    boolean debug = true;
    
    void window() {
    
      int x = 10;
      int y = 10;
    
      if (ledCount < 10) {
        x = ledCount % 10;
      }
    
      if (ledCount > 10) {
        y = ledCount;
        while (y % 10 != 0) {
          y++;
        }
      }
    
      size((x * 10 * scale), (y * scale));
    }
    
    void settings() {
      window();
    }
    
    void delay(int wait) {
    
      int startTime = millis();
    
      while(millis() - startTime < wait) {
      }
    }
    

    My goal is to write a program which can use almost the same code like the led library but instead of lighting up leds it's supposed to show the colors on my screen

  • As others have tried to communicate, draw() only updates the screen when the function ends. So using delay() (even your version of it) in draw() is not what you want. Instead, have a state variable that determines which color should be drawn, and change the value stored in that state variable by checking the elapsed time (using millis()). Like so:

    int wait = 1000;
    int time = wait;
    int state = 0;
    
    void setup() {
      size(1000, 100);
    }
    
    void draw() {
      if ( millis() > time) {
        state++;
        state%=4; // Repeat cycle.
        time = millis() + wait;
      }
      switch( state ) {
      case 0:
        background(0, 0, 0);
        break;
      case 1:
        background(255, 0, 0);
        break;
      case 2:
        background(0, 255, 0);
        break;
      case 3:
        background(0, 0, 255);
        break;
      }
    }
    
Sign In or Register to comment.