Einzelnen Beitrag anzeigen

oldmax

Registriert seit: 27. Apr 2006
Ort: Gieboldehausen
167 Beiträge
 
#30

Re: Einfache Ampelsimulation funktioniert nicht...

  Alt 10. Jun 2007, 05:58
Hi
Bisher hast du schon eine Menge Programmcode bekommen und auch selbst geschrieben, doch ich glaube, genauso wichtig ist ein Hinweis auf die „Problemlösung“. Ein Programm ohne Probleme gibt es nicht und daher werden auch die Programmierer so gut bezahlt. ( meistens jedenfalls..)
Also, gut ist, das du dich nicht mit der Einzelampel zufrieden gibst. Gut ist, das du erkannt hast, das 1 Anpel schon viel Code ist, eine Kreuzung scheinbar das vielfache... doch ich möchte dir mal eine einfache Lösung vorstellen, die du relativ einfach umsetzen und ausbauen kannst.
Betrachten wir einmal eine Ampel in ihrer Funktion stellen wir fest, es sind immer die gleichen Abläufe in Schritten, die Ampelphasen. Listen wir diese einmal auf und beginnen mit Rot
1 : Rot sagen wir mal 20 sek (20 000ms)
2: RotGelb setzen wir z.B. auf 5 sek (5 000ms)
3: Grün muss kürze wie Rot sein daher 15 sek (20 000ms)
4: Gelb da nehmen wir mal 4 sek (4 000ms)
5: Rot -> wieder 1
Wie setzt nun ein Programmierer diese Schritte um, sind doch fast alle Schritte unterschiedlich lang...
Ein Timer wird bekanntlich durch die Intervallzeit getriggert, also nehmen wir ein Array
Zeiten : Array[1..4] of Integer;
und tragen dort die ms für die einzelnen Schrittzeiten ein.
Zeiten[1]:=20000;
Zeiten[2]:=5000;
Zeiten[3]:=15000;
Zeiten[4]:=4000;
Nun brauchen wir noch einen Zähler, der bis 4 zählt und dann wieder von vorn begint. Das ist in der Regel mit einer Interger-Variablen realisierbar

In der Timer-Ereignisroutine schreiben wir folgenden Code:

Delphi-Quellcode:
......
    Zaehler :=Zaehler+1; // alternativ Inc(Zaehler)
    If Zaehler=5 then Zaehler:=1;
    Timer.Intervall:=Zeiten[Zaehler]; // Zuweisung der Zeit für die Anpelphase
    Case Zaehler of 1: Show_Rot;
                             2: Show_Rotgelb;
                             3: Show_Gruen;
                             4. Show_Gelb;
    end;
Mit diesem Code hast du erst mal die Ampelsequenzen festgelegt. Was steckt aber hinter Show_Irgendwas ? Nun, das sind Proceduren, die nichts anderes tun, als die einzelnen Ampelphasen anzuzeigen und die mußt du programmieren und das machen wir einmal gaaaanz einfach.
Du ziehst dir ein Panel auf das Formular. In dieses Panel setzt du drei Shapes mit der Eigenschaft stCircle und gestaltest nun so ein Abbild einer Ampel. Bei den Shapes findest du die Eigenschaft Color unter Brush. Also setzt du z.B. das oberste Shape auf ClRed und die anderen zwei auf clBlack.. Nun clickst du das Panel an und mit Copy & Paste setzt du dir 4 von diesen Ampelbildern in deine Form. Anschließend setzt du die Farben der Shapes entsprechend der Ampelphasen. Dann benennst du die Panels entsprechend der Phase so wie Pn_Rot, Pn_Gelb, Pn_Gruen und Pn_RotGelb. Pn_ steht dabei für Panel.
Dann legst du alle 4 Panels direkt aufeinander.
Und nun kommen wir nun zu den Proceduren....
Delphi-Quellcode:
Procedure TmyForm,Show_Rot;
Begin
  Pn_Gruen.Visible:=False;
  Pn_RotGelb.Visible:=False;
  Pn_Gelb.Visible:=False;
  Pn_Rot.Visible:=True; // dieses Panel ist als einziges sichtbar
End;
TmyForm steht für deine Form. Daher mußt du die Procedure und auch die anderen drei unter Private vorher deklarieren, ohne TmyForm. Einfach gehts auch hier mit C&P (man ist ja schreibfaul) und der entsprechenden Umbenennung und Anpassung der Visible-Eigenschaft.
um eine ausgeschaltete Ampel mit gelben Blinklicht zu versehen, würd ich einen zweiten Timer aktivieren und den Countertimer ausblenden.
die zweite Timerprocedure wäre dann ganz einfach:

Pn_Gelb.Visible:=NotPn_Gelb.Visible; In deinem Schalter setzt du alle Ampelbilder auf Visible.False bevor du die Timer aktivierst bzw.deaktivierst.
Wenn du nun genau so an deine Kreuzung gehst, dir Gedanken machst, wieviele Schritte du brauchst und wann du welches Ampelbild wo sehen willst, ist es einfach, diesen Code entsprechend zu erweitern. Anschließend kannst du dir ja mal Gedanken machen, ob es vielleicht ausreicht, nur das aktuell sichtbare Ampelbild beim Phasenwechsel auszublenden, denn alle anderen sind ja bereits ausgeblendet.
Ich hoffe, dir einen einfachen Weg gezeigt zu haben, der relativ wenig Programmierarbeit erforderlich macht und auch übersichtlich ist. Der Weg, über ein Ampelobjekt zu gehen, ist hier in etwa angedeutet, dies jedoch zu erklären, würde diesen Tread sprengen. Er ist so schon lang genug.
Gruß oldmax
Noch ist mein Rechner mir zu Diensten.... ansonsten habe ich die Macht ihn zu vernichten !
  Mit Zitat antworten Zitat