如何用动画制作红绿灯? (p5js)

问题描述 投票:0回答:2
//traffic lights:red,yellow,green
    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)


    //if three lights with black, first light on
    x+=10
    if (trafficFirstLightColor === "black" && trafficSecondLightColor === "black" && trafficThirdLightColor === "black" && x == 3000) {
        setTimeout(() => {
            trafficFirstLightColor = 'red';
        }, x)
    } else if (trafficFirstLightColor === "red" && x == 6000) {
        trafficFirstLightColor = "black"
        setTimeout(() => {
            trafficSecondLightColor = 'yellow';
        }, x-3000)
    } else if (trafficSecondLightColor === "yellow" && x == 9000) {
        trafficSecondLightColor = "black"
        setTimeout(() => {
            trafficThirdLightColor = 'green';
        }, x-6000)
    }

我正在尝试每 3 秒为交通灯生成颜色;然而,它失败了....

我最初用了三个黑色的红绿灯,也给了他们特定的变量,我在if-else语句中给另一个变量x算作一个变量,当所有的红绿灯都是黑色的时候,第一个红绿灯变成红色.然后,当第一个交通灯变为红色时,第二个交通灯变为黄色 3 秒。最后,当第二个交通灯变成黄色时,第三个交通灯变成绿色。顺便说一句,计划很棒,但代码很糟糕。

javascript p5.js
2个回答
0
投票

假设这是一个使用

setup
draw
的 p5.js 配置,
draw
函数的执行速度高达 30/60 FPS,因此您不必手动调用
setTimeout
来触发更改。相反,您可以将当前的
millis()
与之前的
millis()
进行比较,以了解自上次调用
draw()
以来经过的时间。

这是一个尝试使用 p5.js 执行交通灯动画的示例,而不使用

setTimeout

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;
    }
  }
}

0
投票

每当您使用多个值时,请使用数据结构而不是

thing1
thing2
thing3
...。在这种情况下,我们可以创建一个数组,其中包含 3 个包含颜色和持续时间属性的对象,然后循环阵列或使用索引在我们渲染它们时逐步穿过灯光。

const lights = [
  {
    color: "green",
    duration: 10_000,
  },
  {
    color: "yellow",
    duration: 3_000,
  },
  {
    color: "red",
    duration: 10_000,
  },
];

function setup() {
  createCanvas(50, 50);
  noStroke();
  noLoop();
  renderLights();
}

const renderLights = () => {
  const {duration, color} = lights[0];
  fill(color);
  ellipse(width / 2, height / 2, width, height);
  setTimeout(renderLights, duration);
  lights.push(lights.shift());
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

不仅代码的泛化能力很好(您可以随意添加和删除灯光),而且通过分离配置和实现逻辑,调整持续时间变得更加容易,而不会冒弄乱代码的风险。

如果

draw
中的每一帧都清除了画布,则可以将光循环与绘图分开:

const lights = [
  {
    color: "green",
    duration: 10_000,
  },
  {
    color: "yellow",
    duration: 3_000,
  },
  {
    color: "red",
    duration: 10_000,
  },
];

function setup() {
  createCanvas(50, 50);
  noStroke();
  runLightCycle();
}

function draw() {
  background(0);
  renderCurrentLight();
}

const renderCurrentLight = () => {
  fill(lights[0].color);
  ellipse(width / 2, height / 2, width, height);
};

const runLightCycle = () => {
  setTimeout(() => {
    lights.push(lights.shift());
    runLightCycle();
  }, lights[0].duration);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

请记住

setTimeout
是一个粗略的估计,而不是一个精确的持续时间,所以这会随着时间的推移而变化。

如果你想避免漂移,你可以跟踪最后一次灯光变化的时间,然后反复检查自最后一次灯光变化以来已经过去的毫秒数。当它超过当前的光照持续时间时,将上次更改时间增加持续时间并重复。

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