Reputation: 163
I'm trying to create a program that does something, waits for a set amount of time does another thing, then waits again. However, what actually happens is the program waits at the beginning then does both things without any delay between them.
var start, current
function setup() {
createCanvas(500, 550);
}
function draw() {
background(220);
print('a');
wait(500);
print('b');
wait(500);
}
function wait(time)
{
start = millis()
do
{
current = millis();
}
while(current < start + time)
}
Upvotes: 3
Views: 23906
Reputation: 191
As mentioned, the problem in your attempt is that you're waiting inside the draw() loop. This doesn't work, because draw() is going to be called continually.
A simple way to do it is the following:
function setup() {
//...
}
let task_done = false;
let last_done = 0;
function draw() {
const delay = 1000 //ms
if(!task_done) {
/* do something */
doSomething();
task_done = true;
last_done = millis();
}
else {
if(millis() - last_done > delay) {
task_done = false;
}
}
}
function doSomething() {
//...
}
It only executes something every delay
ms.
Upvotes: 1
Reputation: 76
The draw()
function is executed several times per seconds (around 60 times per second, see framerate
in the doc). This is also what we call a "draw loop".
Your logic seems to be very sequential (do this, then wait and to that, then wait and do another thing...), and maybe you should consider an other flow for your program than the draw loop.
If you want animation, the easy answer would be to stick to the answer provided by Rabbid76.
(read and compare elapsed time millis
every time the draw
loop executes).
If you want one-time events (things that happen only once when a wanted duration is reached), you should look into Promises
(or async
-await
functions), also known as asynchronicity.
This subject can be confusing for beginners, but is very important in javascript.
Here is an example:
(link with p5 editor)
// notice we are NOT using the draw() loop here
function setup()
{
createCanvas(400, 400);
background('tomato')
// try commenting-out one of these:
doScheduleThings();
doAsyncAwaitThings();
}
// you can wait for a Promise to return with the javascript 'then' keyword
// the function execution's is not stopped but each '.then(...)' schedules a function for when the Promise 'sleep(...)' is resolved
function doScheduleThings()
{
sleep(2000).then(function() {
fill('orange')
ellipse(30,30, 50, 50)
})
sleep(1000).then(function() {
fill('yellow')
ellipse(130,30, 50, 50)
})
}
// you can also wait for a Promise to return with an async-await function
// the function's execution is stopped while waiting for each Promise to resolve
async function doAsyncAwaitThings()
{
await sleep(4000)
fill('blue')
rect(200,200, 50, 50)
await sleep(1000)
fill('cyan')
rect(300,200, 50, 50)
}
// a custom 'sleep' or wait' function, that returns a Promise that resolves only after a timeout
function sleep(millisecondsDuration)
{
return new Promise((resolve) => {
setTimeout(resolve, millisecondsDuration);
})
}
Upvotes: 5
Reputation: 211220
You cannot wait in the draw
callback. The canvas is just updated when after draw
was executed. You must evaluate the time in draw
:
function draw() {
background(220);
let ms = millis()
if (ms < 500) {
// [...]
}
else if (ms < 1000) {
// [...]
}
else {
// [...]
}
}
Upvotes: 4