We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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;
}
}
Answers
timer
look at millis
say startTime = millis();
then wait :
@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:
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.
@Lord_of_the_Galaxy : But how can I pause on the next frame?
I'm not pausing on the next frame using this code?
Nope, you're pausing at the current frame in this code.
Steps to pause in next frame (though I still don't recommend it)-
myDelay(3000)
, replace withtoPause = true
Add in draw(), before the
if(keyPressed)
block, this :if(toPause){ myDelay(3000); toPause = false; }
Done.
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.
@ppordozz -- two approaches:
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.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:
Actually, the PSurface screen is rendered based on current content of the sketch's PGraphics after all enqueued input events are dealt with! :-B
Thanks @jeremydouglass that's a good approach to what I was looking for.