如何把这个函数做成一个循环?

问题描述 投票:0回答:1
let trafficFirstLightColor = 'black';
let trafficSecondLightColor = 'black';
let trafficThirdLightColor = 'black';
let start;

function setup() {
  createCanvas(400, 400);
  trafficFirstLightColor = 'black';
  trafficSecondLightColor = 'black';
  trafficThirdLightColor = 'black';
  start = millis();
}

function draw() {
  fill(trafficFirstLightColor);
  ellipse(315, 40, 20, 20);
  fill(trafficSecondLightColor);
  ellipse(315, 40 + 25 * 1, 20, 20);
  fill(trafficThirdLightColor);
  ellipse(315, 40 + 25 * 2, 20, 20);
  
  const now = millis();
  const cycle = now - start;
  
  if (cycle < 3000) {
    if (trafficFirstLightColor === 'black' &&
    trafficSecondLightColor === 'black' &&
    trafficThirdLightColor === 'black') {
      trafficFirstLightColor = 'red';
      return;
    }
  } else if (cycle < 6000) {
    if (trafficFirstLightColor === 'red') {
      trafficFirstLightColor = 'black';
      trafficSecondLightColor = 'yellow';
      return;
    }
  } else if (cycle < 9000) {
    if (trafficSecondLightColor === 'yellow') {
      trafficSecondLightColor = 'black';
      trafficThirdLightColor = 'green';
      return;
    }
  }
}

我做了一个红绿灯,得到了这个社区的帮助;然而,这不是循环……

所以基本功能是,如果碰到黑色,让第一个红绿灯变成红色,然后继续。

唯一的问题是代码完成时,它刚刚完成。我们可以把它变成一个循环吗?

javascript p5.js
1个回答
1
投票

通过使用 async/await,您可以编写一个“休眠”数秒的函数,然后我们可以使用该函数而不是调用 setTimeout 和 setInterval。

(不幸的是,JavaScript 中没有内置的睡眠函数,但我们可以使用 oneliner 创建一个,基本上我们创建了一个承诺,它将在您调用睡眠函数时选择的毫秒数后解析。因为等待只是一种调用承诺的方法await sleep(milliseconds)然后在异步函数中工作正常。)

我们创建了一个数组,其中包含每个灯应该亮起的顺序和时间,易于查找和更改,因为它与其余的编程逻辑是分开的。

然后我们只是循环遍历该数组,打开右边的灯,在数组中指定的持续时间内休眠并关闭灯,在循环的下一次迭代中继续序列的下一部分,依此类推。 ..

在我们的函数结束时,我们再次调用该函数(递归)以重复序列。

您可以采用这种方法来使用画布进行输出,并保持相同的基本逻辑,在序列的不同阶段之间“休眠”——在一个循环中。

async function trafficLight() {
  // a function that let us sleep/pause for a number of ms
  const sleep = ms => new Promise(res => setTimeout(res, ms));
  // get the div for each light
  const [red, yellow, green] =
    [...document.querySelectorAll('.traffic-light div')];
  // how many seconds should each light be on in a sequence
  const onForSeconds = [
    [red, 5],
    [yellow, 1],
    [green, 4],
    [yellow, 1]
  ];
  // run the sequence forever
  while(true){
    for (let [light, seconds] of onForSeconds) {
     light.classList.add('active');
     await sleep(seconds * 1000);
     light.classList.remove('active');
    }
  }
}

trafficLight();
.traffic-light {
  display: inline-block;
  background: black;
}

.traffic-light div {
  border-radius: 50%;
  width: 50px;
  height: 50px;
  margin: 10px;
  background-color: rgba(255, 255, 255, 0.3);
  transition: background-color 0.5s;
}

.red.active {
  background-color: red;
}

.yellow.active {
  background-color: yellow;
}

.green.active {
  background-color: green;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Traffic-lights</title>
</head>

<body>
  <div class="traffic-light">
    <div class="red"></div>
    <div class="yellow"></div>
    <div class="green"></div>
  </div>
</body>

</html>

© www.soinside.com 2019 - 2024. All rights reserved.