Delphi-PRAXiS

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)

deepdragon 28. Mai 2007 13:53


Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Leute,

Ich habe mich hier neu angemeldet, weil ich ein Problem mit meiner Ampelsimulation habe... Wir sollen für die Schule jeder einzeln ein Projekt erarbeiten... Ich habe mir das Thema Ampelsimulation ausgesucht... Ich soll eine Ampelsimulation machen und der Umfang, also wie komplex wir das Thema gestalten, ist uns überlassen... Nur ist die Note natürlich umso besser, umso komplexer das Programm ist^^ Ich dachte mir, dass ich in einem ersten Formular erstmal eine einzige Ampel zeige, die automatisch mit einem Timer die Farben in einem vorher definiertem Intervall wechselt... Das geht völlig automatisch und man kann nicht eingreifen, außer dass man auf Start und Stop klicken kann... Das hört sich ziemlich einfach an, deshalb will ich in einem zweiten Formular dann eine Kreuzung oder zumindest etwas komplexeres machen... Aber jetzt bin ich schon beim ersten Formular hängen geblieben... :(

Ich denke, ich habe alles richtig programmiert und wenn ich das Programm testen will, meckert Delphi auch nicht wegen irgendwelchen Fehlern... Aber wenn ich jetzt auf Start klicke, passiert nichts... :( Ich habe schon rumgerätselt, an was es liegen könnte, aber mir ist es einfach nicht aufgefallen...

Vielleicht kann da mal einer von euch drüber gucken und mir sagen, was ich falsch gemacht habe??
Und ich will nicht, dass ihr meine Hausaufgaben macht, es ist nur so, dass ich absolut nicht weiß, was falsch sein könnte und euer geschultes Auge das sicher sofort erkennt^^

Vielen Dank schon mal im voraus... :)
Deepdragon

P.S.: Bei der Angabe, welche Programmiersprache ich nutzen würde, wusste ich nicht, was das für eine ist, also habe ich einfach mal Delphi Win32 ausgewählt... Ich habe als Programm Delphi 7 Personal benutzt und mein Betriebssystem ist Windows XP... naja ich denke, ihr wisst, was damit gemeint ist ;)

Jelly 28. Mai 2007 14:03

Re: Einfache Ampelsimulation funktioniert nicht...
 
Du hast den Fehler im Timer. Wenn du die Ampel von "Aus" auf "grün" stellst (deine erste if-Bedingung), vergisst du dein IAmpelAus.visible auf false zu setzen. Folglich ist beim 2. Timerdurchlauf deine erste Bedingung immer noch erfüllt, und es wird nie ein else-Zweig abgehandelt.

Ich würde versuchen, das Ganze etwas übersichtlicher zu gestalten, und dir eine TAmpel Klasse zu bilden. Denn spätestens wenn du deine Kreuzung mit mehreren Ampeln abbilden willst, wird deine if-Abfragerei ziemlich unübersichtlich. Wie die TAmpel Klasse aussehen könnte, wäre noch zu überlegen.

messie 28. Mai 2007 14:05

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von deepdragon
Aber wenn ich jetzt auf Start klicke, passiert nichts... :( Ich habe schon rumgerätselt, an was es liegen könnte, aber mir ist es einfach nicht aufgefallen...

Vielleicht kann da mal einer von euch drüber gucken und mir sagen, was ich falsch gemacht habe??

Also, bei mir passiert schon etwas mit Deinem Beispiel... nur bleibt die Ampel immer grün, weil der Block
Delphi-Quellcode:
if IAmpelaus.Visible then
    begin
      IAmpelgruen.Visible := true;
      IAmpelrot.Visible := false;
      IAmpelgelb.Visible := false;
      IAmpelrotgelb.Visible := false;
      Timer1.Interval := 4000;
    end
noch die Zeile
Delphi-Quellcode:
IAmpelaus.Visible := false;
braucht, sonst fährst Du immer in den ersten if-Block rein.

Übrigens ist es übersichtlicher, den Quelltext hier zu posten, und zwar ohne die Deklarationen..

Grüße, Messie

deepdragon 28. Mai 2007 14:07

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von Jelly
Du hast den Fehler im Timer. Wenn du die Ampel von "Aus" auf "grün" stellst (deine erste if-Bedingung), vergisst du dein IAmpelAus.visible auf false zu setzen. Folglich ist beim 2. Timerdurchlauf deine erste Bedingung immer noch erfüllt, und es wird nie ein else-Zweig abgehandelt.

Also ich habe jetzt "IAmpelaus.Visible := false;" eingegeben... hattest recht, das hatte ich noch vergessen... jetzt ist es aber trotzdem so, dass sich nichts tut, wenn ich auf Start klicke...??

Zitat:

Ich würde versuchen, das Ganze etwas übersichtlicher zu gestalten, und dir eine TAmpel Klasse zu bilden. Denn spätestens wenn du deine Kreuzung mit mehreren Ampeln abbilden willst, wird deine if-Abfragerei ziemlich unübersichtlich. Wie die TAmpel Klasse aussehen könnte, wäre noch zu überlegen.
Tut mir leid, aber das habe ich gar nicht verstanden... :( Was ist denn ein TAmpel? sry, aber das habe ich noch nie gehört... :(

deepdragon 28. Mai 2007 14:09

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von Jelly
Du hast den Fehler im Timer. Wenn du die Ampel von "Aus" auf "grün" stellst (deine erste if-Bedingung), vergisst du dein IAmpelAus.visible auf false zu setzen. Folglich ist beim 2. Timerdurchlauf deine erste Bedingung immer noch erfüllt, und es wird nie ein else-Zweig abgehandelt.

Also ich habe jetzt "IAmpelaus.Visible := false;" eingegeben... hattest recht, das hatte ich noch vergessen... jetzt ist es aber trotzdem so, dass sich nichts tut, wenn ich auf Start klicke...??

Hier noch mal der aktuelle Quelltext:

Delphi-Quellcode:
procedure TProjekt_Ampelsimulation_Form1.Timer1Timer(Sender: TObject);
begin
   if IAmpelaus.Visible then
    begin
      IAmpelaus.Visible := false;
      IAmpelgruen.Visible := true;
      IAmpelrot.Visible := false;
      IAmpelgelb.Visible := false;
      IAmpelrotgelb.Visible := false;
      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;
      IAmpelgelb.Visible := true;
      Timer1.Interval := 1000;
    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;
Wíe gesagt, bei mir gehts immer noch nicht... :(



Zitat:

Ich würde versuchen, das Ganze etwas übersichtlicher zu gestalten, und dir eine TAmpel Klasse zu bilden. Denn spätestens wenn du deine Kreuzung mit mehreren Ampeln abbilden willst, wird deine if-Abfragerei ziemlich unübersichtlich. Wie die TAmpel Klasse aussehen könnte, wäre noch zu überlegen.
Tut mir leid, aber das habe ich gar nicht verstanden... :( Was ist denn ein TAmpel? sry, aber das habe ich noch nie gehört... :(

Robert Marquardt 28. Mai 2007 14:24

Re: Einfache Ampelsimulation funktioniert nicht...
 
Ich wuerde mal das Forum absuchen. Ampelsteuerung hatten wir schon mal.

Apollonius 28. Mai 2007 14:26

Re: Einfache Ampelsimulation funktioniert nicht...
 
TAmpel ist, wenn man das Ganze richtig ordentlich machen will, aber ich glaube, das ist momentan ein paar Nummern zu groß für dich :shock: . Allerdings hatten meine Vorredner schon recht: Ohne eine Klasse (das war mit TAmpel gemeint) wird es extrem unübersichtlich, wenn es auf mehrere Ampeln hinauslaufen soll. Also liest du dich entweder mal in objektorientierte Programmierung ein oder du beschränkst das Ganze auf maximal 3 Ampeln.

Klaus01 28. Mai 2007 14:28

Re: Einfache Ampelsimulation funktioniert nicht...
 
Wenn der Startbutton gedrückt wird einen definierten Anfangszustand für IAmpelAus.visible schaffen.

Delphi-Quellcode:
procedure TProjekt_Ampelsimulation_Form1.BStartEinfacheSimulationClick(
  Sender: TObject);
begin
    Timer1.Enabled := true;
    IAmpelAus.Visible:=true;
end;
Grüße
Klaus

deepdragon 28. Mai 2007 14:58

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von Klaus01
Wenn der Startbutton gedrückt wird einen definierten Anfangszustand für IAmpelAus.visible schaffen.

Delphi-Quellcode:
procedure TProjekt_Ampelsimulation_Form1.BStartEinfacheSimulationClick(
  Sender: TObject);
begin
    Timer1.Enabled := true;
    IAmpelAus.Visible:=true;
end;
Grüße
Klaus

Vielen Dank Klaus :)

Dank dir, startet die Ampel^^ Aber jetzt habe ich ein Problem... Die Ampel ist zuerst aus, so wie es sein soll... klicke ich auch Start, springt sie auf grün, wartet dann vier sekunden und springt dann auf gelb, dann auf rot und wartet bei rot wieder vier sekunden... das läuft alles prima. Dann springt die Ampel auf RotGelb und dann auf Gelb. Nur jetzt sollte sie auf Grün springen und wieder vier sekunden warten und dann wieder alles von vorne starten. Nur das geschieht nicht. Die Ampel springt nach Gelb wieder auf Rot und dann wiederholt sich nur die Prozedur: rot --> rotgelb --> gelb --> rot --> rotgelb --> gelb --> rot ... usw... Also da muss irgendwie ein Fehler sein... Ich gucke selbst noch mal drüber, aber wäre nett, wenn ihr es auch machen könntet. :)

Vielen Dank aber bis jetzt schon mal. Ihr seid echt spitze :)

Robert Marquardt 28. Mai 2007 15:18

Re: Einfache Ampelsimulation funktioniert nicht...
 
Ich habe in einem anderen Thread hier erklaert wie man eine Ampel repraesentiert.
Delphi-Quellcode:
type
  TAmpelZustand = (azRot, azRotGelb, azGruen, azGelb);
Man sollte nun eine Zustandsvariable einrichten die man im Timer weiterschaltet (von azGelb auf azRot zuruecksetzen natuerlich). Das ist die eigentliche Ampel. Vom Zustand der Ampel leitet man nun die visuelle Repraesentation ab.

Delphi-Quellcode:
var
  Ampel: TAmpelZustand;
...
begin
  // immer schoen Pascal ausnutzen
  // den kleinsten und groessten Wert einer Enumeration kann man per Low bzw. High bestimmen
  if Ampel = High(TAmpelZustand) then
    Ampel := Low(TAmpelZustand)
  else
    // Succ gibt das naechste Element einer Enumeration
    Ampel := Succ(Ampel);

  case Ampel of
    azRot:
      begin
        // Darstellung selber machen
      end;
    ...

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:

deepdragon 2. Jun 2007 19:25

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von Gremlin
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:

Wie meinst du das mit Shapes?? Das habe ich net verstanden... :(

Naja wir haben mit dem Projekt noch bis zum 15. Juni zeit... und da ich noch einige Klausuren schreibe, haben die erstmal vorrang... aber wenn ich die dann geschrieben habe, werde ich mitte bis ende nächster Woche weitermachen...^^ Naja wenns dann fertig ist, werde ich es euch noch mal zeigen... oder wenn ich noch mal Hilfe brauche^^

Bis dann Deepdragon^^

Gremlin 2. Jun 2007 19:39

Re: Einfache Ampelsimulation funktioniert nicht...
 
Hallo deepdragon,

Shapes (von der Klasse TShape) sind einfache geometrische Figuren. Du musst dann keine Bilder mehr laden und kannst stattdessen die Ampel selbst darstellen (jeweils ein Shape für rot, gelb und grün). Um die Farbe zu setzen, kannst du die Property Brush.Color verwenden. Die Figur kann über Shape=stCircle gesetzt werden. Sollte nur als einfache Anregung gedacht sein. :)

Viel Erfolg.

deepdragon 3. Jun 2007 13:14

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Gremlin
Hallo deepdragon,

Shapes (von der Klasse TShape) sind einfache geometrische Figuren. Du musst dann keine Bilder mehr laden und kannst stattdessen die Ampel selbst darstellen (jeweils ein Shape für rot, gelb und grün). Um die Farbe zu setzen, kannst du die Property Brush.Color verwenden. Die Figur kann über Shape=stCircle gesetzt werden. Sollte nur als einfache Anregung gedacht sein. :)

Viel Erfolg.

Vielen Dank :D

Ich hab das jetzt mit Shapes gemacht... Und es klappt ganz gut^^ Ich habe wieder einmal einen Fehler drin gehabt über den ich ne halbe Stunde gebrütet habe^^ Dann hab ich ihn aber gefunden und es hat alles funktioniert ;-)

Ihr könnt euch das fertige Shape Projekt noch mal angucken... Nur damit ich weiß, dass ich das mit den Shapes auch richtig verstanden habe und ich es auch so gemacht habe, wie ihr es gemeint habt... ;-)


Aber noch ne Frage... Ich will ja jetzt ein neues Formular einbinden... Das ist ja ganz einfach mit 'Form2.show' ... Aber die Frage ist jetzt, ob ich die Ampel wieder neu machen muss oder ich auf das erste Formular zurückgreifen kann? Also die Frage ist etwas kompliziert und wenn ihr sie nicht verstanden habt, macht das nichts^^ Aber ich will jetzt im zweiten Formular eine Ampel mit einer Fußgängerampel koppeln... Und auf der Fußgängerampel ist dann ein Button und wenn man den drückt, geht logischerweise die "Auto"-Ampel auf rot und dann die Fußgängerampel auf grün.. ;-) ...
Und muss ich da jetzt wieder den ganzen Quellcode aufschreiben?? Weil wenn ich daran denke, wenn ich erstmal die Kreuzung mache (obwohl ihr euch die net so spektakulär vorstellen müsst... ich werde nur eine einfache machen, auf der es keine Abbiegerspuren gibt... ;-)), wird das ja noch komplizierter wenn ich dann so einen ellenlangen Quelltext hab^^

Naja aber danke schon mal bis hierher ;-)
Deepdragon

Gremlin 3. Jun 2007 14:45

Re: Einfache Ampelsimulation funktioniert nicht...
 
Ha das sieht ja schonmal ganz gut aus und ist sicher ausbaufähig :)

Ich würd mal die erste Seite lassen und ein komplett neues Formular machen. Dann hast du einerseits immer noch eine funktionierende erste Seite und du hast eine Vorlage für deine Ampel mit Fussgängerfunktion. Kopier einfach alle Komponenten des ersten Formulars auf dein 2. Formular und ergänze deine Ampel um eine Fussgängeranzeige und einem zusätzlichen Button. Dann brauchst du noch einen zusätzlichen Timer für die Fussgängerperiode.

Wenn du dann davor bist eine gesamte Ampelanlage simulieren zu wollen und deine erste Lösung anschaust, wirst du bemerken, das deine sichtbaren Komponenten an die Steuerung der Ampel direkt gebunden sind. Das kann man sicher so machen, nur wird es sehr schwierig diese Art von Code zu erweitern. Besser wäre es jetzt vielleicht für dich, wenn du dir eine Procedure überlegen würdest, die du zur Kontrolle der Anzeige benutzen kannst, zb. "AmpelAnzeigen" mit Parametern für die Angabe der anzuzeigenden Signale (rot, gelb, grün). Diese kannst du in deiner Steuerung (Timer) aufrufen.
Da du aber nicht mehr die Shapes als Information über deinen Ampelstatus verwenden solltest, musst du dir dafür etwas anderes überlegen, zb. könntest du alle Ampelzustände (grün, gelb, rot, rotgelb) als Reihe betrachten, die nacheinander alle Zustände durchschaltet.

Versuch dich jetzt aber mal zuerst in der Fussgängererweiterung und arbeite dich dann Schritt für Schritt an bessere Lösungen für deine Probleme heran :-D

deepdragon 3. Jun 2007 19:38

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
So... also ich hab jetzt das zweite Formular gemacht...
Wundert euch nicht, es funktioniert noch nicht vollständig und es sieht auch noch nicht gut aus... Ich habe erstmal nur das Hauptprogramm gemacht, und nicht auf die Optik geachtet... ;-) also damit meine ich sachen wie Überschrift und Anleitungstext... Ihr müsst einfach nur auf Erweiterte Simulation klicken und dann öffnet sich das zweite Formular... Ich muss den Text im ersten noch ändern, weil dort ja steht, dass im 2. Formular die Kreuzung kommt, was aber nicht der Fall ist... Aber das ist wie gesagt erstmal zweitrangig... die optikfehler merze ich dann aus, wenn das prg. läuft... und da ist ein erheblicher fehler drin... nämlich wenn fußgänger ampel auf grün ist und die Autoampel auf rot, springt die Fußgängerampel nach drei Sekunden nicht mehr auf rot und somit läuft der letzte Teil des Quelltextes erst gar nicht ab... Ich habe schon seit zwei Stunden dran gesessen und weiß echt nicht mehr, was ich falsch gemacht habe... :-(

Hier ist der komplette Quelltext:

Delphi-Quellcode:
procedure TForm1.BAmpelOClick(Sender: TObject);
begin
  BAmpelO.Caption := 'Signal kommt!';
  BAmpelU.Caption := 'Signal kommt!';
  Timer1.Enabled := true;
end;

procedure TForm1.BAmpelUClick(Sender: TObject);
begin
  BAmpelU.Caption := 'Signal kommt!';
  BAmpelO.Caption := 'Signal kommt!';
  Timer1.Enabled := true;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if ARL.Visible and ARR.Visible then
   begin
     FRL.Visible := false;
     FRR.Visible := false;
     FGRL.Visible := true;
     FGRR.Visible := true;
     Timer3.Enabled := true;
   end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

   if not ARL.Visible and not ARR.Visible and not AGL.Visible and not AGR.Visible and not AGRL.Visible and not AGRR.Visible then
    begin
      ARL.Visible := false;
      ARR.Visible := false;
      AGL.Visible := false;
      AGR.Visible := false;
      AGRL.Visible := true;
      AGRR.Visible := true;
      Timer1.Interval := 4000;
    end

   else if AGRL.Visible and AGRR.Visible and not AGL.Visible and not AGR.Visible then
    begin
      AGRL.Visible := false;
      AGRR.Visible := false;
      ARL.Visible := false;
      ARR.Visible := false;
      AGL.Visible := true;
      AGR.Visible := true;
      Timer1.Interval := 1000;
    end

   else if AGL.Visible and AGR.Visible and not ARL.Visible and not ARR.Visible then
    begin
      AGL.Visible := false;
      AGR.Visible := false;
      AGRL.Visible := false;
      AGRR.Visible := false;
      ARL.Visible := true;
      ARR.Visible := true;
      Timer1.Interval := 4000;
    end;

Timer2.Enabled := true;
end;

procedure TForm1.Timer3Timer(Sender: TObject);
begin
     Timer3.Interval := 3000;
     BAmpelO.Caption := 'Drücken';
     BAmpelU.Caption := 'Drücken';
     Timer4.Enabled := true;
end;

procedure TForm1.Timer4Timer(Sender: TObject);
begin
  if ARL.Visible and ARR.Visible then
   begin
    FRL.Visible := true;
    FRR.Visible := true;
    FGRL.Visible := false;
    FGRR.Visible := false;
    Timer5.Enabled := true;
   end;
end;

procedure TForm1.Timer5Timer(Sender: TObject);
begin

if FRL.Visible and FRR.Visible then
    begin
      if not AGL.Visible and not AGR.Visible and not AGRL.Visible and not AGRR.Visible then
        begin
          ARL.Visible := true;
          ARR.Visible := true;
          AGL.Visible := true;
          AGR.Visible := true;
          AGRL.Visible := false;
          AGRR.Visible := false;
          Timer3.Interval := 1000;
        end

      else if ARL.Visible and ARR.Visible and AGL.Visible and AGR.Visible then
         begin
          ARL.Visible := false;
          ARR.Visible := false;
          AGL.Visible := false;
          AGR.Visible := false;
          AGRL.Visible := true;
          AGRR.Visible := true;
          Timer3.Interval := 4000;
         end
    end;
end;

end.
Die Datei hab ich auch noch beigefügt, damit ihr mal seht, was ich meine... Und tut mir leid, aber der Quelltext ist ziemlich krass...^^ Ich hab 5 Timer verwendet^^ hehe

Naja und die Bezeichnungen sollte ich euch vielleicht noch kurz erklären:
ARL heißt AmpelRotLinks... mit Ampel meine ich die beiden AutoAmpeln... Mit Rot eben die Farbe und mit Links, dass es die auf der linken Seite des Zebrastreifens ist... ARR heißt dann logischerweise AmpelRotRechts...
FRL heißt FußgängerampelRotLinks... also steht das F für Fußgängerampel und R wieder für Rot und L für Links, also auf der linken Seite des Zebrastreifens...
G = Gelb
GR = Grün
R = Rot
A = Autoampel
F = Fußgängerampel
L = Links
R = Rechts

Es ist für einen außenstehenden echt sehr kompliziert, aber ich weiß ganz genau, was mit was gemeint ist... ich komme nicht durcheinander... Aber da muss eben ein Fehler drin sein ;-)

deepdragon 7. Jun 2007 13:01

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi...

kann mir denn keiner helfen? :( das ist natürlich schade... ich habe das programm jetzt noch mal etwas verändert... aber es funktioniert immer noch nicht... Ich habe diesmal die ganze Source mit angehängt... Vielleicht könnt ihr mir so leichter helfen... ich komme wirklich nicht drauf, was ich falsch gemacht haben könnte... :(

waldforest 7. Jun 2007 17:56

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
das Teil sah doch schon super aus
:thumb: , es fehlte meiner Meinung nach nur ne Kleinigkeit.

Mit den ganzen Timern kommt man schon mal durcheinander. Ein Tipp.
wenn man etwas einschaltet, hilft es manchmal dieses auch wieder aus zu schalten. (mir gehts manchmal genau so, vor lauter Bäumen sieht man den Wald nicht mehr. :shock:

Ich hoffe, mir gings nicht genau so und habe noch etwas vergessen.


mfg waldforest

waldforest 7. Jun 2007 18:05

Re: Einfache Ampelsimulation funktioniert nicht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
:wall: Siehest, und schon ist es mir auch passiert, hab den Timer 5 nicht ausgeschaltet und schon käme es zu einer brutalen kollision zwischen Fußgänger und Autofahrer.

deepdragon 8. Jun 2007 16:13

Re: Einfache Ampelsimulation funktioniert nicht...
 
Zitat:

Zitat von waldforest
:wall: Siehest, und schon ist es mir auch passiert, hab den Timer 5 nicht ausgeschaltet und schon käme es zu einer brutalen kollision zwischen Fußgänger und Autofahrer.

mensch, das ist ja echt geil^^ naja auf die dumme idee, die schalter auch wieder ausstellen zu müssen, hätte ich natürlich auch kommen können.... :wall:
aber echt vielen dank... So... und bevor ich mich jetzt an die einfache Kreuzung wage, habe ich noch eine Frage:
Euch ist sicher aufgefallen, dass in der Ampelsimulation mit der Fußgängerampel die Shape-Formen nicht ganz die alten abdecken... und das sieht nicht so professionell aus... ;-) Gibts da nicht einen Weg das ganze abdeckend darzustellen? Weil wenn dann noch ein kleiner Rand von dem unteren ausgeschalteten "Ampellicht" hinter dem leuchtenden Ampellicht zu sehen ist, sieht das nicht grad schön aus... naja aber das wäre nur rein optisch gesehen... schlimm ist es jetzt auch nicht, sieht aber nicht so schön aus ;-)

Vielen Dank,
Deepdragon

oldmax 10. Jun 2007 05:58

Re: Einfache Ampelsimulation funktioniert nicht...
 
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:

Delphi-Quellcode:
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:37 Uhr.

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