Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Einfache Ampelsimulation funktioniert nicht... (https://www.delphipraxis.net/92892-einfache-ampelsimulation-funktioniert-nicht.html)

jfheins 28. Mai 2007 15:24

Re: Einfache Ampelsimulation funktioniert nicht...
 
Okay ... @deepdragon:

1. Nach RotGelb kommt grün. Zumindest in Deutschland an der Ampel.
Delphi-Quellcode:
else if IAmpelrotgelb.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelrot.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelgelb.Visible := true;
      Timer1.Interval := 1000;
    end
2. Zwei ifs mit der gleichen Bedingung ??
Delphi-Quellcode:
else if IAmpelgelb.Visible then
    begin
      IAmpelgelb.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelaus.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelrot.Visible := true;
      Timer1.Interval := 4000;
    end
    ...
   else if IAmpelgelb.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelgelb.Visible := false;
      IAmpelrot.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelgruen.Visible := true;
      Timer1.Interval := 4000;
    end
end;
Das zweite wird nie angesprungen ;)

drittens: Mein Tipp ;)

Wenn schon nicht richtig mit Klassen und Co. (was wohl ne Nummer zu groß ist) dann mach ne Prozedur und nen enum-Typ, also sowas:
Delphi-Quellcode:

TLights = (Green, Yellow, Red);
TAmpelState = set of TLights;

const
  StateGreen: TAmpelState = [Green];
  ...

procedure SetAmpelState (newState: TAmpelState)
begin
  GreenLight.Visible := Green in newState;
  etc.
end;

...

SetAmpelState([Red, Yellow]);
SetAmpelState(StateGreen);
Sollte so oder so ähnlich gehen (mehrere Wege) und ist sauberer - trennt die Anzeigelogik von der Steuerungslogik ;)

@RedBox ^^ : So wie Robert es geschrieben hat gehts natürlich auch, aber ich wollte noch das Problem aufzeigen und so ... ;)

deepdragon 28. Mai 2007 15:38

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vielen Dank an jfheins!

Dank dir, funktioniert die Ampel jetzt^^ Und danke auch für den Hinweis, dass die Ampel von rotgelb gelich auf grün schaltet^^ Ich wusste das nicht mehr so genau und habe es deshalb so gemacht^^

Hier könnt ihr den fertigen Quelltext bewundern und weiter unten dann das fertige Programm noch mal downloaden, um zu testen, ob es bei euch auch funktioniert...^^ :)

Delphi-Quellcode:
procedure TProjekt_Ampelsimulation_Form1.BBeendenClick(Sender: TObject);
begin
  close;
end;

procedure TProjekt_Ampelsimulation_Form1.BStartEinfacheSimulationClick(
  Sender: TObject);
begin
    Timer1.Enabled := true;
    IAmpelAus.Visible:=true;
end;

procedure TProjekt_Ampelsimulation_Form1.BStopEinfacheSimulationClick(
  Sender: TObject);
begin
   Timer1.Enabled := false;
end;

procedure TProjekt_Ampelsimulation_Form1.Timer1Timer(Sender: TObject);
begin
   if IAmpelaus.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelrot.Visible := false;
      IAmpelgelb.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelgruen.Visible := true;
      Timer1.Interval := 4000;
    end

   else if IAmpelgruen.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelrot.Visible := false;
      IAmpelrotgelb.Visible :=false;
      IAmpelgelb.Visible := true;
      Timer1.Interval := 1000;
    end

   else if IAmpelgelb.Visible then
    begin
      IAmpelgelb.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelaus.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelrot.Visible := true;
      Timer1.Interval := 4000;
    end

   else if IAmpelrot.Visible then
    begin
      IAmpelrot.Visible := false;
      IAmpelaus.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelgelb.Visible := false;
      IAmpelrotgelb.Visible := true;
      Timer1.Interval := 1000;
    end

   else if IAmpelrotgelb.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelrot.Visible := false;
      IAmpelrotgelb.Visible := false;
      IAmpelgruen.Visible := false;
      IAmpelgruen.Visible := true;
      Timer1.Interval := 4000;
    end
end;

end.

Jetzt funktioniert schon mal der erste Teil und wegen diesem Klassen dings da muss ich mich noch mal informieren... Ich habe auch ein Delphi-Buch, wo ich mal nachgucken könnte... :)

Vielen Dank erstmal, dass ihr mir soweit geholfen habt ;)
Deepdragon

Robert Marquardt 28. Mai 2007 15:39

Re: Einfache Ampelsimulation funktioniert nicht...
 
Der entscheidende Unterschied zwischen einem Set und einer Enumeration ist das die Enumeration mehr direkte Information traegt. azRotGelb liefert direkt die Ampelphase. [Rot, Gelb] liefert nur die Information das zwei Lampen an sind. Fuer die direkte Funktion einer Ampel ist das nicht wichtig, aber fuer eine Ampelsteuerung ist die Enumeration nuetzlicher und effizienter.

Bei einer echten Ampel kommt noch "gelb blinkend" hinzu. Spaetestens hier beginnt das Set zu versagen, da es zu sehr an die Darstellung der Lampen gekoppelt ist.

Robert Marquardt 28. Mai 2007 16:39

Re: Einfache Ampelsimulation funktioniert nicht...
 
Es faellt mir gerade auf das man am besten sowohl eine Variable mit der Enumeration als auch eine Variable mit dem Set macht.
Damit ist die es besonders klar was eigentlich gemacht wird. Die Enumeration gibt den Ampelzustand an. Dieser wird weitergeschaltet. Davon wird das Set abgeleitet welches den visuellen Zustand der Lampen repraesentiert. Davon wiederum wird die Anzeige gemacht.
"Gelb blinkend" kann dann recht einfach implementiert werden. Ein weiteres Element (azGelbBlinkend) zur Enumeration hinzufuegen. Das Weiterschalten der Enumeration wird modifiziert, um diesen Zustand auszulassen. Die Ableitung des Sets von der Enumeration wird modifiziert. Bei azGelbBlinkend ist der Blink-Zustand im Set gespeichert und wird jeweils umgeschaltet. Die Enumeration wird nicht weitergeschaltet.
Der Zustand azGelbBlinkend wird natuerlich ueber einen Button injiziert bzw. verlassen.

Damit ist der Zustand der Ampel sowohl logisch als auch physisch komplett von der konkreten Anzeige entkoppelt.

deepdragon 28. Mai 2007 16:46

Re: Einfache Ampelsimulation funktioniert nicht...
 
also entschuldigt mich bitte, aber da komme ich gar nicht mehr mit... :?:
ich habe ja für jede ampelsituation ein Bild gemacht von der Ampel... also ein bild dafür, dass sie aus ist, dann dafür das sie rot ist usw.... und dann hab ich halt die bilder visible bzw. invisible gemacht, die eben gebraucht bzw. nicht gebraucht werden... aber das wisst ihr ja...

nur das, was ihr da grad erklärt, verstehe ich echt nicht.... :( also das mit den Klassen meine ich... klar, ich verstehe, dass es viel zu kompliziert ist, wenn ich ne kreuzung mache und dann soviel If-zeugs drin hab... das is ja jetzt für eine einzige ampel schon total viel Quelltext... wie soll das dann erst bei 4 Ampeln aussehen?? ... aber wie das mit den Klassen funktioniert verstehe ich halt nich...

Apollonius 28. Mai 2007 16:55

Re: Einfache Ampelsimulation funktioniert nicht...
 
Die Idee ist, dass du einmal ein bisschen mehr Quelltext schreibst, diesen aber für alle Ampeln nutzen kannst. Stell dir einmal vor, dass du vier Ampeln und damit vier Timerprozeduren hast: Da wird das Programm richtig unübersichtlich.
Wenn ich einen Tipp geben darf: Nimm nur ein Image pro Ampel und lade das Ganze mit image1.loadfromfile('xyz.bmp'). Du ersparst dir eine Menge Arbeit, wenn du dann mehr Ampeln hast. Den Rest machst am besten, wie Robert Marquardt es beschrieben hat: Eine Aufzählung (ich hoffe, das ist dir eine Begriff, wenn nicht, musst du irgendwo mal nachschauen) für den aktuellen Zustand und im Timer wird dann weitergeschaltet.

deepdragon 28. Mai 2007 17:08

Re: Einfache Ampelsimulation funktioniert nicht...
 
also um euch erstmal zu erklären, wie es weitergehen soll... also ich will als nächstes diese einfache ampel etwas umbauen, bzw. eine etwas komplexere situation erstellen... diese sieht wie folgt aus:
es ist eine straße und eine fußgänger ampel... diese hat einen drückknopf, und wenn ich ihn drücke, springt die ampel auf rot und die fußgängerampel auf grün...
das ist erstmal schon ein nächster schritt zur kreuzung...
wenn das dann fertig ist, mache ich die kreuzung...
die wird aber auch nicht sehr komplex... denn was ich hier schon im forum gesehen habe, steigt völlig über meine kompetenzen... bspw. werde ich keine autos einfügen, da ich erstens nicht weiß, wie ich es machen kann und zweitens es viel zu schwer wäre, bestimmt... dann will ich die kreuzung auch so einfach machen, wie es geht... also nicht mit links und rechtsabbieger spuren... hmm oder vielleicht doch... aber das wird dann halt sehr sehr viel arbeit... und ich wüsste gar nicht, wie ich es machen könnte...

Robert Marquardt 28. Mai 2007 17:31

Re: Einfache Ampelsimulation funktioniert nicht...
 
Jetzt wird es Zeit eine Ampelkomponente zu bauen. Zusaetzlich brauchst du allerdings noch eine Ampelanlagen-Komponente. Fuer den Gleichtakt aller Ampeln darf der Timer naemlich nicht lokal in der Ampelkomponente sein.
Die Ampelkomponente bekommt die Methoden SetzeZustand und NaechsterZustand. Naechster Zustand schaltet den Zustand weiter fuer die Normalzustaende. Beim Sonderzustand azGelbBlinkend wird nur das Blinken umgeschaltet.
Die Verwaltung und Weiterschaltung der einzelnen Ampeln erfolgt in der Ampelanlagen-Komponente. Gleich- und Gegentakt sind ja relativ einfach zu imlementieren, wenn es vier Ampeln sind. Spannend wird es bei dem Sonderzustand azGelbBlinkend. Es macht da Sinn auf azGelb und dann auf azRot fuer alle Ampeln zu schalten und dann den Gegentakt mit einer laengeren Rotphase wiederherzustellen.

Fuer die konkrete Implementation von Komponenten habe ich jetzt aber keine Lust mehr. Da muessen andere helfen.

deepdragon 30. Mai 2007 13:06

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi^^ Also die Ampel is schon ganz gut, bis jetzt... Aber kann mir vielleicht mal jemand sagen, wieso das immer so ganz leicht flackert, wenn die Ampelphase wechselt? Kommt das daher, dass ich vier verschiedene Bilder gemacht habe, die dann immer einzeln geladen werden und diese kurz ladepause zu dem flackern führt?? Weil es ist zwar nicht schlimm, solange das Programm funktioniert, es sieht aber nicht so schön aus... :-(

Ich habe das Programm noch mal angehängt, damit ihr es euch noch mal angucken könnt und vielleicht auch dieses leichte flackern wahrnehmt... ;-)

Gremlin 30. Mai 2007 15:31

Re: Einfache Ampelsimulation funktioniert nicht...
 
Jo, scheint am Anfang ein wenig zu flimmern, wenn du neue Bilder lädst, aber es fällt fast nicht auf. Du könntest evetuell Shapes verwenden. Die Anwendung sieht ja schon mal ganz interessant aus.

Wann machst du die neue Möglichkeiten rein? :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz