//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 秒。最后,当第二个交通灯变成黄色时,第三个交通灯变成绿色。顺便说一句,计划很棒,但代码很糟糕。
假设这是一个使用
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;
}
}
}
每当您使用多个值时,请使用数据结构而不是
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
是一个粗略的估计,而不是一个精确的持续时间,所以这会随着时间的推移而变化。
如果你想避免漂移,你可以跟踪最后一次灯光变化的时间,然后反复检查自最后一次灯光变化以来已经过去的毫秒数。当它超过当前的光照持续时间时,将上次更改时间增加持续时间并重复。