Entwickler-Ecke
Sonstiges (Delphi) - 4 Timer, 4 Ampeln, genug Probleme
Gidi - Fr 08.09.06 21:19
Titel: 4 Timer, 4 Ampeln, genug Probleme
Hallo erstmal. Ich habe im Informatikunterricht die Aufgabe, eine Kreuzung mit 4 Ampeln zu erstellen, die natürlich passend schalten. Eine Ampel war kein Problem aber ich weiß nicht, wie ich eine weitere Ampel mit dem gleichen, oder einem neuen Timer programmiere (z.B. die Gegenüberliegende). Hier mein Versuch es mit einem Timer zu machen (Delphi 7). Die erste Ampel funktioniert gut, aber die 2. macht keine Anstalten auf den Timer zu reagieren.
Ich habe auch das Forum durchsucht, aber keine Lösung auf mein Problem gefunden.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if image1.visible=true then begin image1.visible:=false; image2.visible:=true end else |
....U.S.W. und dann die 2. Ampel; Ich weiß nicht, was ich zwischen der 1. und der 2. schreiben muss, damit auch die 2. auf den Timer reagiert.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| begin if Image13.visible=true then begin image13.visible:=false; image14.visible:=true end else |
.......U.S.W.
Moderiert von
raziel: Delphi-Tags hinzugefügt
_frank_ - Fr 08.09.06 23:21
Hi,
warum 4 timer??
mehrere timer gleichzeitig laufen zu lassen halte ich für keine gute Idee...
nehme nur einen Timer und zähle damit einen counter hoch (timeslots). Anhand des aktuellen timeslots setzt du die Ampelwerte.
hier mal ein Beispiel mit 2 Ampeln (gegensätzlich), wie ich es realisieren würde...
ließe sich ohne Probleme auf 4 erweitern.
a3 setzt du wie a1 und a4 wie a2 ;)
Du kannst die shapes natürlich auch durch TImages ersetzen und Grafiken statt Farben zuweisen.
ggf. eine steuer-classe mit allen ampeln und eine pause zwischen rot-grün (der anderen Ampel)
HTH Frank
Narses - Fr 08.09.06 23:32
Moin und :welcome: im Forum!
Naja, eigentlich wiederstrebt es mir, fertigen Code anzuliefern, noch dazu für eine Hausaufgabe... :? Auf der anderen Seite lernt man es nie, wenn man keine vernünftige Erklärung bekommt, und State-Machines sind nun mal nicht so ganz einfach, wenn man damit noch nie zu tun hatte.
Hier also ein Vorschlag, wie man sowas lösen könnte. Ein neues Projekt anlegen, das Formular anklicken, ALT+F12 drücken (in die Textdarstellung des Formulars wechseln), alles markieren, löschen, und durch den folgenden Code ersetzen, dann wieder ALT+F12, um in den Grafikmodus zurück zu wechseln:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147:
| object Form1: TForm1 Left = 208 Top = 110 BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = '2-Ampel-Simulation' ClientHeight = 440 ClientWidth = 440 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False Position = poDesktopCenter OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object Strasse1: TShape Left = 8 Top = 176 Width = 425 Height = 89 Brush.Color = clGray Pen.Style = psClear end object Strasse2: TShape Left = 176 Top = 8 Width = 89 Height = 425 Brush.Color = clGray Pen.Style = psClear end object Rasen1: TShape Left = 272 Top = 8 Width = 161 Height = 161 Brush.Color = clGreen end object Rasen2: TShape Left = 8 Top = 8 Width = 161 Height = 161 Brush.Color = clGreen end object Rasen3: TShape Left = 8 Top = 272 Width = 161 Height = 161 Brush.Color = clGreen end object Rasen4: TShape Left = 272 Top = 272 Width = 161 Height = 161 Brush.Color = clGreen end object Streifen2: TShape Left = 219 Top = 8 Width = 3 Height = 425 Brush.Style = bsHorizontal Pen.Color = clWhite Pen.Style = psDash end object Streifen1: TShape Left = 8 Top = 219 Width = 425 Height = 3 Brush.Style = bsHorizontal Pen.Color = clWhite Pen.Style = psDash end object Rot1: TShape Left = 280 Top = 280 Width = 25 Height = 25 Brush.Color = clRed Shape = stCircle end object Gelb1: TShape Left = 280 Top = 304 Width = 25 Height = 25 Brush.Color = clYellow Shape = stCircle end object Gruen1: TShape Left = 280 Top = 328 Width = 25 Height = 25 Brush.Color = clLime Shape = stCircle end object Rot2: TShape Left = 136 Top = 280 Width = 25 Height = 25 Brush.Color = clRed Shape = stCircle end object Gelb2: TShape Left = 112 Top = 280 Width = 25 Height = 25 Brush.Color = clYellow Shape = stCircle end object Gruen2: TShape Left = 88 Top = 280 Width = 25 Height = 25 Brush.Color = clLime Shape = stCircle end object Ampel1: TBevel Left = 279 Top = 279 Width = 27 Height = 75 end object Ampel2: TBevel Left = 87 Top = 279 Width = 75 Height = 27 end object Timer1: TTimer OnTimer = Timer1Timer Left = 208 Top = 208 end end |
Jetzt nochmal F12 drücken, um in das Code-Fenster zu wechseln, hier auch alles markieren, löschen und durch den folgenden Code ersetzen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Strasse1: TShape; Strasse2: TShape; Streifen1: TShape; Streifen2: TShape; Rasen1: TShape; Rasen2: TShape; Rasen3: TShape; Rasen4: TShape; Ampel1: TBevel; Rot1: TShape; Gelb1: TShape; Gruen1: TShape; Ampel2: TBevel; Rot2: TShape; Gelb2: TShape; Gruen2: TShape; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure SetState(const NewState: Integer); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin SetState(0); end;
procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Tag := (Timer1.Tag +1) mod 8; SetState(Timer1.Tag); end;
procedure TForm1.SetState(const NewState: Integer); begin Rot1.Visible := NewState in [0,1,4..8]; Gelb1.Visible := NewState in [1,3]; Gruen1.Visible := NewState in [2]; Rot2.Visible := NewState in [0..5]; Gelb2.Visible := NewState in [5,7]; Gruen2.Visible := NewState in [6]; end;
end. |
Erläuterung:
Die erste Prozedur, FormCreate, wird beim Programmstart aufgerufen und setzt den Startzustand, da ja noch kein Timerereignis eingetreten ist.
Die zweite Prozedur ist das Timerereignis, in dem zunächst der nächste Zustand bestimmt wird, wobei Zustand 8 auf Zustand 0 gesetzt wird, was wir mit der "mod 8" Anweisung erreichen. Danach setzen wir diesen neuen Zustand in der Anzeige um.
Die interessante Prozedur ist aber die Letzte und der Kommentar dazu. In der Tabelle beschreiben wir einfach waagerecht, wie die Lampen in der Ampeln geschaltet sind, ein Punkt bedeutet "aus", ein X bedeutet "an". Diese Zustände nummerieren wir einfach durch (erste Spalte). Dann gehen wir die einzelnen Spalten senkrecht durch und schreiben einfach ab, in welchen Zuständen die Lampe eingeschaltet ist.
In der Prozedur bestimmen wir dann ganz einfach die Sichtbarleit des Shapes, indem wir schauen, ob der aktuelle Zustand zu den "eingeschaltet"-Zuständen gehört. Fertig. ;)
cu
Narses
//EDIT: zu langsam... :(
Gidi - Sa 09.09.06 13:57
Danke für die ausfürlichen Antworten. Ich habe erlich gesagt mühe das zu verstehen, da ich mich mit Programmierung erst seit 2 Wochen beschäftige. Aber so langsamm komme ich dahinter. Das war erlich gesagt keine Hausaufgabe, sondern Ergeiz, da ich in der Schulstunde nicht weiter gekommen bin.
Gruß Gidi
Narses - Sa 09.09.06 22:27
Moin!
Hast du denn noch irgendwelche Fragen oder ist dir die Lösung jetzt klar geworden? Wäre schade, wenn das an dir vorbeigegangen ist, mit den Komplettlösungen... :? ;)
cu
Narses
blaueled - So 10.09.06 00:28
Hallo Narses,
könntest du das mit
Delphi-Quelltext
1:
| Rot1.Visible := NewState in [0,1,4..8]; |
nochmal erklären, ich hab das noch nicht so ganz verstanden.
blaueled
Born-to-Frag - So 10.09.06 09:22
Kannst du die vorstellen wie "Wenn NewState den Wert 0, 1, 4, 5, 6, 7 oder 8 hat dann wird Rot1 angezeigt, sonst wird es versteckt"
Dieses 4..8 schreibt man nur um es abzukürzen, man könnte auch schreiben NewState in [0, 1, 4, 5, 6, 7, 8]. Ist das selbe.
Hoffe du hasts verstanden ;)
greetz
Martok - So 10.09.06 12:35
Im Prinzip eine ganz einfache Mengenoperation.
Der Mathematiker würde das schreiben (siehe Anhang)
Edit: oha, man sollte im Browser doch öfter mal Refresh drücken. Born-To-Frag hat ja schon geantwortet.
blaueled - Mo 11.09.06 16:45
ok, danke
jetzt habe ich es verstanden
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!