Pause draw()

edited December 2016 in Library Questions

I know that is not a good practice using delay() but i'm trying different ways to pause a sketch and I can't.

I'm trying to run a simple program, with minim, when line in reaches X volume, a trigger is shot, and the program shows and image for two seconds. Then, the program continues listening to. I load the image outside the bounds of the canvas (x and y = 3000) and when the volume reaches 100, x and y is changed to 0 0, so, the image appears in the screen.

For now all works but the delay. How could I make the program pause for two seconds while is showing the image? I can make the delay when I want, but the image appears AFTER it, not before.

Thanks!

This is my code:

import ddf.minim.*;

Minim minim;
AudioInput in;
PImage img;
PFont font;

float maxValue;
float minValue;
int frameValue;
  int posX =3000;
  int posY = 3000;

void setup()
{
  size(800, 600, P3D);
 img = loadImage("/Users/pablo/Downloads/vamo.jpg");
frameValue=200;
  minim = new Minim(this);
  minim.debugOn();
  // use the getLineIn method of the Minim object to get an AudioInput
  in = minim.getLineIn(Minim.STEREO, 512);
  font = createFont ("Arial", 60);

   posX =3000;
   posY = 3000;
}

void draw()
{

  background(0);
  stroke(255);
  image(img, posX, posY);
  //actual
  text("Actual: "+in.right.level()*100, 10, height/2);

   if(in.right.level()*100>10){   //if the volume reaches 10
     println("im in");
      posX=30;
      posY=30;
      //delay(3000);
      //frameRate(10);
  }else{
      posX=3000;
      posY=3000;
  }

}
Tagged:

Answers

  • Answer ✓

    timer

    look at millis

    say startTime = millis();

    then wait :

    if (startTime + 10000<millis()) {
             //
    }
    
  • @Chirsir is giving you great advice.

    There have been several recent forum threads all looking to make simple timers with millis() if you want to look at related examples:

    https://forum.processing.org/two/search?Search=millis()

  • I know the use of millis() (at least I thought I knew) but this is not the point. I think thepoint is how to to freeze an image inside the wait. I've implemented a delay(), a timer, and a Thread, but it is always the same trouble.

    For example, If I do a wait like this:

    void setup()
    {
      println("--------------------");
      size(200, 100, P3D);
        background(0);
    }
    
    void draw()
    {
      println("listening "+millis());
    
       if(keyPressed==true){  
            text("text", 30,30);
            println("waiting");
            myDelay(3000);
          }
    
        }
    void myDelay(int ms)
    {
       try
      {   
        Thread.sleep(ms);
      }
      catch(Exception e){}
    }
    

    If you run this code, and read the console output, you can see the behaveour is ok when press a key, but the text appears AFTER the pause, not before, as expexted.

    What do I'm doing wrong?

  • I see

    The screen is not updated throughout but at the very end of draw()

    You could use if(frameCount> 2) start delay....

    When the frameCount is smaller draw your stuff

  • A little differently, what happens is that when you call delay, or any version of it, you make the execution thread wait for that much time. However, that means that the screen window (handled by PSurface I think) is not updated. So, during the delay, nothing happens. If nothing happens, you can't see your image. You just see your image in one frame, but since you call delay in that frame, it is of no use.
    If you insist on using delay, it is possible though not recommended. Instead of pausing draw in that frame, pause it in the next. It is not very accurate, but works probably.

  • edited December 2016

    @Lord_of_the_Galaxy : But how can I pause on the next frame?

    text("text", 30,30);
            println("waiting");
            myDelay(3000);
    

    I'm not pausing on the next frame using this code?

  • edited December 2016 Answer ✓

    Nope, you're pausing at the current frame in this code.
    Steps to pause in next frame (though I still don't recommend it)-

    • Create a Boolean variable (default to false) called, say, "toPause".
    • Inside draw(), where you say myDelay(3000), replace with toPause = true
    • Add in draw(), before the if(keyPressed) block, this :

      if(toPause){ myDelay(3000); toPause = false; }

    Done.

  • edited December 2016

    Thanks. Now I can see the result as expected. I'm sorry but I'm not able to implement the millis() way. As my program is quite simple, I can implement the Thread, although I don't like it either.

    The only thing I can see is not clearly well done with the thread is that the keyPressed listener is disabled while the program is stopped.

    But as I said, to my program this is not a critical issue.

  • That is why delay() is discouraged.

  • edited December 2016

    @ppordozz -- two approaches:

    1. Use noLoop() loop() if you really want to completely disable draw. Since you want to freeze on a specific draw result, don't imagine stopping "in the middle" of a draw -- because the screen gets updated at after the very end of each draw loop. Instead, stop everything once draw is over. HOWEVER restarting can be tricky and (I think) overly complicated.

    2. Just use a timer. Look again at the examples I pointed you to -- they fit your problem.

  • @ppardozz --

    Here is an example that shows an image for four seconds any time you press the space bar. Change that "keyPressed" test to checking your audio input, and this seems to do exactly what you want -- with no delaying or messing with the loop state.

    Example:

    // Countdown Timer
    // An event changes the draw state for a certain amount of time.
    // Press key or click mouse to activate timer.
    // https:// forum.processing.org/two/discussion/19514/pause-draw
    
    PImage img;
    // timer variables
    float stoptime, wait;
    
    void setup() {
      size(512, 512);
      img = loadImage("https:// processing.org/img/processing3-logo.png");
      wait = 4000; // delay in milliseconds
    }
    
    void draw() {
      background(0);
      if (keyPressed) { // fake event -- check for audio event on this line
        stoptime = millis() + wait; // set future time = now + wait
      }
      if(stoptime > millis()){ // the timer is running!
        image(img,0,0);
      } else { // the time is not running!
        ellipse(width/2,height/2,width/2,width/2);
      }
      timerTextDisplay();
    }
    
    void mouseClicked(){
      // another event example 
      stoptime = millis() + wait;
    }
    
    void timerTextDisplay(){
      // how long has the sketch been running? millis
      text((float)millis()/1000, 10, 24);
      // how long does the time have left?
      fill(255,0,0);
      text(max(0,(stoptime - millis()))/1000, 10, 36);
      // when will the timer stop? saved millis variable
      fill(255);
      text(stoptime/1000, 10, 48);
    } 
    

    TimerCountdown

  • edited December 2016 Answer ✓

    ... because the screen gets updated at the very end of each draw() loop.

    Actually, the PSurface screen is rendered based on current content of the sketch's PGraphics after all enqueued input events are dealt with! :-B

  • edited December 2016

    Thanks @jeremydouglass that's a good approach to what I was looking for.

Sign In or Register to comment.