如何在p5.js中进行等待

3
我正在尝试创建一个程序,它会做一些事情,然后等待一段固定的时间再做另一件事,然后再次等待。然而,实际发生的是程序在开始时等待,然后两个事情之间没有任何延迟就同时执行了。
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)
}
3个回答

5

draw() 函数每秒执行几次(大约每秒 60 次,请参见 文档中的帧速率)。这也是我们所说的“绘图循环”。

你的逻辑似乎非常顺序化(做这个,然后等待并做那个,然后等待并做另一件事...),也许你应该考虑程序的其他流程而不是绘图循环。

如果你想要动画,简单的答案是遵循 Rabbid76 提供的答案(每次 draw 循环执行时读取并比较经过的时间 millis)。

如果你想要单次事件(只在达到所需持续时间时发生的事情),你应该研究 Promises(或 async-await 函数),也称为异步性。这个主题对于初学者来说可能会很困惑,但在 JavaScript 中非常重要。

这是一个例子:
(使用p5编辑器的链接)
// 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);
  })
}

4

你不能在draw回调中等待。当draw执行后,画布才会更新。你必须在draw中评估时间:

function draw() {
    background(220);

    let ms = millis()
    if (ms < 500) {
        // [...]
    }
    else if (ms < 1000) {
        // [...]
    }
    else {
        // [...]
    } 
}

1
如上所述,您尝试中的问题在于您正在draw()循环内等待。这是行不通的,因为draw()将会被不断调用。
一个简单的方法是以下内容:
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() {
  //...
}

它只会每delay毫秒执行一次某些操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接