//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)
}
I am trying to generate colors every 3 second for a traffic light; however, it failed….
I was initial with three traffic light with black color, and gives them specific varibale as well, I give another variable x to count as a varible in if-else statement, when all of traffic lights are black, the first traffic light become red. Then, when first traffic light became red, the second traffic light become yellow by 3 seconds. Last, the third traffic light become green when the second traffic light became yellow. By the way, plan is great but code is bad.
2
Answers
Assuming this is a p5.js configuration using
setup
anddraw
, thedraw
function is executed up to 30/60 FPS, so you don’t have to manually callsetTimeout
to trigger the change. Instead you can compare the currentmillis()
with the previousmillis()
for the time elapsed since last call todraw()
.Here’s an example trying to perform the traffic light animation using p5.js without the use of
setTimeout
:Whenever you’re working with multiple values, use a data structure rather than
thing1
,thing2
,thing3
…. In this case, we can create an array that holds 3 objects containing color and duration properties, then cycle the array or use an index to step through the lights as we render them.Not only does the code generalize well (you can add and remove lights at will), but by separating configuration and implementation logic, it becomes easier to adjust the durations without risking messing something up in the code.
If your canvas is cleared on every frame in
draw
, you can separate light cycling from drawing:Keep in mind
setTimeout
is a rough estimate, not a precise duration, so this will drift over time.If you want to avoid drift, you can keep track of the time of the last light change, then repeatedly check the elapsed milliseconds that have elapsed since the last light change. When it exceeds the current light duration, increment the last change time by the duration and repeat.