2016-05-21 21 views
1

Ich arbeite an einer Ampelsimulation und gerade versuche ich, die Ampeln die Farbe zu wechseln (sowohl Auto- als auch Fußgängerampel). Das Problem ist, dass ich 8 Ampeln pro Kreuzung und 12 Kreuzungen habe. Ich habe versucht mit einem Timer und einem Zähler, aber das Problem ist, dass das Intervall nicht eingehalten wird:Ampelsimulation: Farbe der Ampel ändern

Wenn die Startfarbe rot ist, ist die rote Zeit 8 und die grüne Zeit ist 10 dann, wenn die Farbe grün wird In zwei Sekunden wird es wieder rot angezeigt. Hier ist der Timer-Code:

private void timerTrafficLights_Tick(object sender, EventArgs e) 
{ 
    counter++; 

    foreach(TrafficLight t in trafficLights) 
    { 
     if(counter%t.RedTime==0 &&t.TrafficColor==TrafficLightColor.RED) 
     { 
      t.SwitchLight(t, TrafficLightColor.GREEN, t.ID); 
     } 
     else if(counter % t.GreenTime==0 && t.TrafficColor==TrafficLightColor.GREEN) 
     { 
      t.SwitchLight(t, TrafficLightColor.RED, t.ID); 
     } 
    } 

    foreach(PedestrianLight p in pedestrianLights) 
    { 
     if(counter % p.RedTime==0 && p.LightColor == PedestrianLightColor.RED) 
     { 
      p.SwitchLight(p, p.ID, PedestrianLightColor.GREEN); 
     } 
     else if (counter % p.GreenTime ==0 && p.LightColor == PedestrianLightColor.GREEN) 
     { 
      p.SwitchLight(p, p.ID, PedestrianLightColor.RED); 
     } 
    } 

    UI.InvalidateEvent.InvalidatePanel(); 
} 

private void TimerTrafficLights() 
{ 
    timerTrafficLights.Interval = 1000; 
    timerTrafficLights.Tick += new EventHandler(timerTrafficLights_Tick); 
    timerTrafficLights.Start(); 
} 

Der Timer wird gestartet, wenn die Simulation gestartet und der Wert des Zählers zu Beginn der Simulation ist 0.

+0

Halten Sie zwei Zähler für rotes und grünes Licht – Steve

+0

Das würde Arbeit, wenn ich nur eine Ampel hätte oder wenn alle die gleiche grüne oder rote Zeit haben ... was sie nicht tun. – MonicaS

+0

Dispatcher läuft auf einem Timer. https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.110).aspx Vielleicht oben die Priorität und es schneller ausführen. WPF ist nicht das richtige Werkzeug für eine visuelle Simulation wie diese. – Paparazzi

Antwort

0

Ich würde diese Aufgabe aus einer objektorientierten Art und Weise angehen. Es ist nicht Ihr Timer, der die Farbe Ihrer TrafficLight (und PedestrianLight) ändert, aber es ist die Klasse selbst, die weiß, wann es Zeit ist, die Farbe zu ändern.

Ihre Trafficlight-Klasse In diesem Szenario so etwas wie dieses Und jetzt

// I show just the TrafficLight class, but the same is true for the 
// PedestrianLight class (better if both derives from the same base class) 
public class TrafficLight 
{ 
    private int counter = 0; 
    public TrafficLightColor TrafficColor { get; set; } 
    public int ID {get;set;} 
    public int RedTime { get; set; } 
    public int GreenTime { get; set; } 

    public void SwitchLight(TrafficLightColor color) 
    { 
     if(color != TrafficColor) 
     { 
      TrafficColor = color; 
      // Restart the counter everytime the color changes..... 
      // So the next change happens for the current color. 
      counter = 0; 
     } 
    } 
    public void Tick() 
    { 
     if (this.TrafficColor == TrafficLightColor.RED && counter == RedTime) 
      SwitchLight(TrafficLightColor.GREEN); 
     else if ((this.TrafficColor == TrafficLightColor.GREEN && counter == GreenTime) 
      SwitchLight(TrafficLightColor.RED); 
    } 
} 

sein könnte, ruft der Timer Tick-Ereignis nur für jede Instanz des Trafficlight (und PedestrianLight) das Verfahren Tick.

private void timerTrafficLights_Tick(object sender, EventArgs e) 
{ 
    foreach(TrafficLight t in trafficLights) 
     t.Tick(); 

    foreach(PedestrianLight p in pedestrianLights) 
     p.Tick(); 

    UI.InvalidateEvent.InvalidatePanel(); 
} 

Auf diese Weise müssen Sie keinen externen Zähler der Ticks außerhalb der Klasse halten. Jede Instanz kennt ihre Grenzen und ändert die Farbe, wenn die Zeit reif ist. Sie können sogar TrafficLights mit unterschiedlichen Timing für rote und grüne Lichter haben, weil die ganze Logik der Farbänderung in der Instanz selbst enthalten ist, die mit ihren eigenen Einstellungen für Rot und Grün arbeitet.

0

so etwas wie diese In dem Verkehr/Fußgänger-Licht Klasse

public int startTime; 

Mit diesem müssen Sie nur die Startzeit speichern. Bei jedem Häkchen prüfen Sie, ob der Unterschied größer als der Schwellenwert ist. Nach der Änderung setzen Sie die Zeit auf den aktuellen Wert zurück.

+0

Nicht so sicher, dass ich vollständig verstanden habe. Ich füge hinzu, dass als eine Eigenschaft und in der Timer-Im-Überprüfung der folgenden: if (counter-t.currentTime == t.RedTime && t.TrafficColor == TrafficLightColor.RED) { t.SwitchLight (t, TrafficLightColor.GREEN, t .ICH WÜRDE); t.currentTime = Zähler; } } if if (counter - t.currentTime = = t.GreenTime && t.TrafficColor == TrafficLightColor.GREEN) { t.SwitchLight (t, TrafficLightColor.RED, t.ID); t.currentTime = Zähler; } – MonicaS

+0

Das habe ich mir gedacht. –

+0

Jetzt funktioniert das nicht, wenn der Zähler gleich der aktuellen Zeit ist => ändern. Aber in diesem Fall wird es mit der roten Zeit verglichen. Es muss gleich 0 sein und wenn die Aussage wahr ist, muss der Zähler wieder auf 0 gesetzt werden. Ich werde es versuchen und komme mit einer Antwort zurück. – MonicaS