Reputation: 337
Given a greenLightDuration and a yellowLightDuration, I need to switch lights (including red Light) based on duration. This all happens inside a run method for the traffic light. The reason for the run method is because it is used when running the entire simulation (trafficLight is an Agent).
//Run method for agents in Model
public void run(double duration) {
if (disposed)
throw new IllegalStateException();
for (int i=0; i<duration; i++) {
time++;
for (Agent a : agents.toArray(new Agent[0])) {
a.run(time);
}
super.setChanged();
super.notifyObservers();
}
}
In Light I have the run method...
public void run(double runTime){
double check_time = runtime - time;
if(check_time >= yellowLightDuration&& color == Color.RED){
color = Color.GREEN;
time = runtime;
}else if(check_time >= greenLightDuration&& color == Color.GREEN){
color = Color.RED;
time = runtime;
}
...but it was just something silly I did to get the lights switching from red/green and obviously does not work for yellow or is not proportionate to green/yellow light duration(I don't think).
For color I use
Color.RED, Color.YELLOW, Color.GREEN
from java.awt.Color
.
public void run(double runtime){
if(this.color == Color.GREEN){
if(time%greenLightDuration==0){
color = Color.YELLOW;
}
}
if(this.color == Color.YELLOW){
if(time%yellowLightDuration == 0){
color = Color.RED;
}
}
else
color = Color.GREEN;
}
Tried this but the three colors are blinking furiously. I set green to 200 and yellow to 40.
Upvotes: 0
Views: 1914
Reputation: 894
the three colors are blinking furiously.
The first/main cause of this is the simulator/model, and not necessarily the traffic light (though your traffic light my still be a problem). The issue is that your current model for time is just some sketchy for-loop, which will run however fast it runs... and it clearly runs a lot faster than your eyes would like.
What you can do is attempt to control the time in your simulation, using Thread.sleep()
to delay the program momentarily. The following version will run an iteration roughly once per millisecond...
//Run method for agents in Model
public void run(double duration) {
if (disposed)
throw new IllegalStateException();
for (int i=0; i<duration; i++) {
time++;
try{ Thread.sleep(1); } //wait 1ms
catch(Exception e){} //just resume after interruption
for (Agent a : agents.toArray(new Agent[0])) {
a.run(time);
}
super.setChanged();
super.notifyObservers();
}
}
Now a duration of 300 for green lights takes roughly 0.3 seconds, which is brisk but not unobservable.
Upvotes: 0
Reputation: 15144
Since this is a cycle, you want to get the current phase of the cycle using the modulus operator. Something like: double phase = (runTime - startTime) % (greenDuration + yellowDuration + redDuration)
. You can take the modulus of a floating-point number in Java.
Upvotes: 1