Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Sonne auf- und untergehen lassen und mit mond austauschen!
Timm3r - Sa 18.09.10 12:49
Titel: Sonne auf- und untergehen lassen und mit mond austauschen!
Guten Tag zusammen,
habe das folgende Programm geschrieben:
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:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if ImSonne.Visible=true then begin
if ImSonne.left<450 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top-10; end;
if ImSonne.Visible=true
then begin if ImSonne.Left>450 then begin
if ImSonne.Left<900 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top+10; end;
if ImSonne.Left>900
then begin ImSonne.visible:=false; ImMond.visible:=true; end;
if ImMond.visible=true
then begin if ImMond.Left>395 then begin ImMond.Left:=ImMond.left-8; ImMond.Top:=ImMond.Top-7; end;
if ImMond.Left<395 then begin if ImMond.Left>16 then begin ImMond.Left:=ImMond.Left-9; ImMond.Top:=ImMond.Top+12; end;
if ImMond.Left<16 then begin ImMond.Visible:=false; ImMond.Left:=864; ImSonne.Left:=16; ImSonne.Visible:=true; end end; end; end; end; end; end; end. |
Die Sonne geht auf und unter aber der mond bleibt stehen.
was soll ich machen?
Moderiert von
Gausi: Code- durch Delphi-Tags ersetzt
Hidden - Sa 18.09.10 13:04
Moin!
Formatiere deinen Quelltext mal :shock: ;) :!:
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:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if ImSonne.Visible then begin if ImSonne.left < 450 then begin ImSonne.Left := ImSonne.Left + 10; ImSonne.Top := ImSonne.Top - 10; end; if ImSonne.Visible then begin if ImSonne.Left > 450 then begin if ImSonne.Left < 900 then begin ImSonne.Left := ImSonne.Left + 10; ImSonne.Top := ImSonne.Top + 10; end; if ImSonne.Left > 900 then begin ImSonne.Visible := false; ImMond.Visible := true; end; if ImMond.Visible then begin if ImMond.Left > 395 then begin ImMond.Left := ImMond.left - 8; ImMond.Top := ImMond.Top - 7; end; if ImMond.Left < 395 then begin if ImMond.Left > 16 then begin ImMond.Left := ImMond.Left - 9; ImMond.Top := ImMond.Top + 12; end; if ImMond.Left < 16 then begin ImMond.Visible := false; ImMond.Left := 864; ImSonne.Left := 16; ImSonne.Visible := true; end; end; end; end; end; end; end; |
Wie du jetzt sehen kannst, wird der gesamte Programmblock nur ausgeführt, wenn Sonne.Visible ist. Kann ja nicht gehen :nixweiss:
Den Rest überlasse ich mal dir, ich kann irgendwie gerade nur sehen, was der Code dem Computer sagt - nicht, was du sagen wolltest :P
lg,
*
Vergleiche auf true/false [
http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/page/4/]
*
Crashkurs von Christian S. [
http://www.christian-stelzmann.de/artikel/CrashkursReloaded/]
Timm3r - Sa 18.09.10 14:14
Nein,
das sind ja alles getrennte if-sätze, deshalb wird alles nur ausgeführt wenn die entsprechenende bedingungen erfüllt werde,
Hidden - Sa 18.09.10 14:18
Hidden hat folgendes geschrieben : |
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:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if ImSonne.Visible then begin if ImSonne.left < 450 then begin ImSonne.Left := ImSonne.Left + 10; ImSonne.Top := ImSonne.Top - 10; end; if ImSonne.Visible then begin if ImSonne.Left > 450 then begin if ImSonne.Left < 900 then begin ImSonne.Left := ImSonne.Left + 10; ImSonne.Top := ImSonne.Top + 10; end; if ImSonne.Left > 900 then begin ImSonne.Visible := false; ImMond.Visible := true; end; if ImMond.Visible then begin if ImMond.Left > 395 then begin ImMond.Left := ImMond.left - 8; ImMond.Top := ImMond.Top - 7; end; if ImMond.Left < 395 then begin if ImMond.Left > 16 then begin ImMond.Left := ImMond.Left - 9; ImMond.Top := ImMond.Top + 12; end; if ImMond.Left < 16 then begin ImMond.Visible := false; ImMond.Left := 864; ImSonne.Left := 16; ImSonne.Visible := true; end; end; end; end; end; end; end; | |
Zum markierten begin gehört das markierte end :nixweiss: Das kann man nur bei formatiertem Quelltext richtig sehen.
Dein Timer macht gar nichts, wenn die Sonne nicht sichtbar ist.
Dass das nicht so gedacht ist wie es da steht, siehst du schon dadurch, dass du in der mit Kommentar versehenen Zeile wiederholt abfragst, ob die Sonne sichtbar ist.
lg,
Jakob_Ullmann - Sa 18.09.10 14:37
Erstmal: vor
end muss kein Semikolon stehen.
Zweitens: Den Code solltest du überdenken. Da sieht niemand durch. Klar können wir erahnen, was der machen soll, aber er ist unsichtbar und die Zahlen sind nicht gerade schön. Ich würde dir eine saubere Lösung mit trigonometrischen Funktionen empfehlen, damit sich deine Objekte auch auf einer elliptischen Bahn bewegen. Außerdem hast du dann bessere Kontrolle, da du dann die Position von Sonne und Mond an Winkeln festmachen kannst.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| c := Pi / 180;
deg := (deg - 1) mod 360;
ImSonne.Left := -(ImSonne.Width div 2) + Trunc(sWidth * cos(deg * c)); ImSonne.Top := -(ImSonne.Height div 2) + Trunc(sHeight * sin(deg * c));
if deg in [0..179] then else if deg in [180..359] then |
Hidden - Sa 18.09.10 14:40
Jakob_Ullmann hat folgendes geschrieben : |
Erstmal: vor end muss kein Semikolon stehen. |
Akzeptiert, dann aber bitte konsistent ;) Ich mache immer mit, andere können gerne immer ohne machen.
Timm3r - Sa 18.09.10 16:25
wie beende ich denn diesen scheiß if-satz
Jakob_Ullmann - Sa 18.09.10 16:59
@Hidden: *zustimm*
Timm3r hat folgendes geschrieben : |
wie beende ich denn diesen schei* if-satz |
Nach if..then folgt immer nur ein Befehl oder ein Block (begin..end;).
Timm3r - Sa 18.09.10 17:01
Also ich verzweifle hier gerade fast, ich programmiere jetzt seit stunden verwerfe alles wieder und programmiere wieder.
Mein jetziger Quelltext sieht folgendermaßen aus:
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:
| procedure TSonnenlauf.Timer1Timer(Sender: TObject);
begin if ImSonne.Visible=True then begin if ImSonne.Left>0 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top-10; end;
end else if ImSonne.Left>250 then begin if ImSonne.Left<500 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top+10 end; end else if ImSonne.Left>500 then begin ImSonne.Visible:=False; ImSonne.Visible:=True; end; end; end.
begin if ImMond.visible=true then begin if ImMond.Left>250 then begin ImMond.Left:=ImMond.left-10; ImMond.Top:=ImMond.Top-10; end; end else if ImMond.Left<250 then begin if ImMond.Left<0 then begin ImMond.Left:=ImMond.left-10; ImMond.Top:=ImMond.Top+10; end; end; end. |
Aber der Fehler ist: [Fatal Error] Could not create output file 'C:\Program Files\Borland\Delphi7\Projects\Project1.exe'
Was muss ich denn ejtzt machen? Ich verzweifle hier echt.
Bitte dringend um Hilfe!
Moderiert von
Martok: Code- durch Delphi-Tags ersetzt
Hidden - Sa 18.09.10 17:02
Ausführlichst, vielleicht weißt du das teilweise schon:
Eine Anweisung nach einem if wird nur ausgeführt, wenn die Bedingung zwischen if und then zu dem Zeitpunkt erfüllt ist, zu dem der Prozessor bei der Abfrage ankommt. Durch Sprungbefehle oder Schleifen kann dies auch mehrmals geschehen, dann kann die Anweisung auch mehrmals ausgeführt werden und mehrmals nicht.
Statt einer einzelnen Anweisung kann auch ein
Block folgen. Dieser besteht aus
begin,
beliebig vielen Anweisungen, und schließlich einem
end;. Der gesamte Block wird wie eine einzelne Anweisung ausgeführt: Das heißt entweder ganz oder gar nicht, und zwar genau dann, wenn die Bedingung erfüllt ist.
In deinem Fall sind alle weiteren Abfragen nach der ersten im Block enthalten. Das heißt, dass auch nichts davon ausgeführt wird, so lange die Sonne nicht sichtbar ist.
Um das zu "reparieren", musst du einfach das markierte end; so weit nach oben schieben, bis genau noch das im Block der Sonne.Visible-Abfrage enthalten ist, was darin enthalten sein soll.
Hoffe, das hat geholfen :zwinker:
Moderiert von
Martok: Beiträge zusammengeführt.
Timm3r hat folgendes geschrieben : |
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:
| procedure TSonnenlauf.Timer1Timer(Sender: TObject);
begin if ImSonne.Visible then begin if ImSonne.Left>0 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top-10; end; end else begin if ImSonne.Left>250 then begin if ImSonne.Left<500 then begin ImSonne.Left:=ImSonne.Left+10; ImSonne.Top:=ImSonne.Top+10 end; end; end else if ImSonne.Left>500 then begin ImSonne.Visible:=False; ImSonne.Visible:=True; end; end; end. begin if ImMond.visible=true then begin if ImMond.Left>250 then begin ImMond.Left:=ImMond.left-10; ImMond.Top:=ImMond.Top-10; end; end else if ImMond.Left<250 then begin if ImMond.Left<0X then begin ImMond.Left:=ImMond.left-10; ImMond.Top:=ImMond.Top+10; end; end; end. | |
Klasse, da kann man jetzt richtig was erkennen. Editiere ich gleich noch 'was zu rein :)
Edit ist da(vgl. Quelltext).
Mit zwei Prozeduren(so ähnlich, wie du es jetzt versucht hast) kann man das auch machen. Versuche aber mal den Ansatz:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure Timer1Timer(Sender: TObject); begin if Sonne.Visible then begin end; if Mond.Visible then begin end; end; |
Timm3r hat folgendes geschrieben : |
Aber der Fehler ist: [Fatal Error] Could not create output file 'C:\Program Files\Borland\Delphi7\Projects\Project1.exe' |
Hmm, das kann verschiedene Gründe haben. Das ist kein Syntaxfehler in deinem Programm: Delphi sagt dir, dass Windows es aus irgend einem Grund nicht erlaubt, in die .exe-Datei zu schreiben. Starte einmal Delphi neu, und wenn das nichts hilft den Computer.
Timm3r - So 19.09.10 21:12
Also danke für die vielen Antworten, aber ich kriege es einfach nicht hin und eure Tips haben leider auch nichts gebracht. Ich habe jetzt mal alles in 2 Timer gepackt im einen ist der Mond und im anderen die Sonne. Jetzt öffnet der PC gar nichts mehr. Das ist jetzt mein Text:
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:
| procedure TSonnenlauf.Timer1Timer(Sender: TObject);
begin if ImSonne.Visible then begin if ImSonne.Left>0 then begin if ImSonne.Left<500 then begin ImSonne.Left:=ImSonne.Left+1; ImSonne.Top:=ImSonne.Top-1; end; end; end; end; else if ImSonne.Left>500 then begin if ImSonne.Left<1000 then begin ImSonne.Left:=ImSonne.Left+1; ImSonne.Top:=ImSonne.Top+1 end; end else if ImSonne.Left>1000 then begin ImSonne.Visible:=False; ImMond.Visible:=True; end; end; end.
procedure TSonnenlauf.Timer2Timer(Sender: TObject); begin if ImMond.visible then begin if ImMond.Left>500 then begin ImMond.Left:=ImMond.left-1; ImMond.Top:=ImMond.Top-1; end; end else if ImMond.Left<500 then begin if ImMond.Left>0 then begin ImMond.Left:=ImMond.left-1; ImMond.Top:=ImMond.Top+1; end; else if ImMond.Left<0 then begin ImMond.Visible:=False; ImSonne.Visible:=True; end
end;
end; end. |
und es kommen die folgenden Fehler:
[Error] Unit1.pas(45): Declaration expected but 'ELSE' found
[Error] Unit1.pas(47): Undeclared identifier: 'ImSonne'
[Error] Unit1.pas(49): Missing operator or semicolon
[Error] Unit1.pas(49): Missing operator or semicolon
[Error] Unit1.pas(50): Missing operator or semicolon
[Error] Unit1.pas(50): Missing operator or semicolon
[Error] Unit1.pas(51): Statement expected, but expression of type 'Integer' found
[Error] Unit1.pas(53): '.' expected but 'ELSE' found
[Error] Unit1.pas(54): Identifier redeclared: 'Finalization'
[Error] Unit1.pas(55): Missing operator or semicolon
[Error] Unit1.pas(56): Undeclared identifier: 'ImMond'
[Warning] Unit1.pas(57): Text after final 'END.' - ignored by compiler
[Error] Unit1.pas(16): Unsatisfied forward or external declaration: 'TSonnenlauf.Timer2Timer'
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
elundril - So 19.09.10 22:31
du weißt das in der klammer immer die zeilennummer steht? rechts daneben dann eine genaue beschreibung was der compiler von dir will. ;)
lg elundril
Gerd Kayser - Mo 20.09.10 02:57
Timm3r hat folgendes geschrieben : |
und es kommen die folgenden Fehler: |
Du solltest Dir angewöhnen, den Text ordentlich zu formatieren: begin und end an der gleichen Spaltenposition beginnen und nicht "then begin" in einer Zeile. Außerdem kosten Leerzeichen nichts (z. B. bei +, -, =, / usw.).
Ich habe mir mal erlaubt, Deinen Quelltext entsprechend zu formatieren:
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:
| procedure TSonnenlauf.Timer1Timer(Sender: TObject); begin if ImSonne.Visible then begin if ImSonne.Left > 0 then begin if ImSonne.Left < 500 then begin ImSonne.Left:=ImSonne.Left + 1; ImSonne.Top:=ImSonne.Top - 1; end; end; end; end; else if ImSonne.Left > 500 then begin if ImSonne.Left < 1000 then begin ImSonne.Left:=ImSonne.Left + 1; ImSonne.Top:=ImSonne.Top + 1; end; end else if ImSonne.Left > 1000 then begin ImSonne.Visible := False; ImMond.Visible := True; end; end; end. procedure TSonnenlauf.Timer2Timer(Sender: TObject); begin if ImMond.visible then begin if ImMond.Left > 500 then begin ImMond.Left := ImMond.left - 1; ImMond.Top := ImMond.Top - 1; end; end else if ImMond.Left < 500 then begin if ImMond.Left > 0 then begin ImMond.Left := ImMond.left - 1; ImMond.Top := ImMond.Top + 1; end; else if ImMond.Left < 0 then begin ImMond.Visible := False; ImSonne.Visible := True; end end; end; end. |
Damit sollte es Dir ein Leichtes sein, Deine Fehler selbst zu finden. Du brauchst nur zu jedem begin das dazugehörige end zu suchen bzw. umgekehrt.
Gerd Kayser - Mo 20.09.10 17:39
Es ist mehr als offensichtlich, daß der Threadstarter ein Problem mit der Verschachtelung seiner If-Then-Else-Konstruktionen hat. Somit kann ein Hinweis auf eine entsprechende Formatierung keinesfalls Off-Topic sein, denn damit wird das eigentliche Problem des Threadstartes angegangen.
Bei meiner Variante reicht notfalls ein Lineal, um zu sehen, was zusammen gehört und was nicht (begin und end), was voneinander abhängig ist (if und else) usw. Wenn DAS nicht lesbar sein soll, kann ich Dir leider auch nicht helfen ... ;-)
Und um auf den von Dir genannten Styleguide des Herrn Charles Calvert einzugehen: Man muß sich nicht selbst die Hose mit einer Kneifzange anziehen, nur weil es ein Herr Calvert vielleicht so macht oder alle anderen es so machen. ;-)
Oder um es mal mit den Worten meines ehemaligen Professors zu sagen: "Es gibt eine herrschende Meinung, und es gibt Leute, die eine andere Meinung haben. Nur deshalb müssen die Leute mit einer anderer Meinung nicht unbedingt falsch liegen. Sie müssen nur ihre Meinung begründen können."
Der genannte Styleguide ist (nicht nur in meinen Augen) an manchen Stellen inkonsequent. Laut Styleguide des Autoren Calvert:
1. Zwischen begin und end wird eingerückt:
Delphi-Quelltext
1: 2: 3: 4:
| begin B := C; A := B; end; |
2. Nach einem then wird eingerückt:
Delphi-Quelltext
1: 2: 3:
| if A < B then DoSomething; |
3. If und else stehen untereinander (beginnen an der gleichen Spaltenposition).
Nach einer if-Bedingung kann eine einzelne Anweisung oder ein Block mit Anweisungen folgen, die (siehe 2.) einzurücken sind. Wenn ein Block mit begin und end folgt, dann ist der auch einzurücken (siehe 1.).
Daraus folgt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| if A < B then begin B := C; A := B; end else begin C := D; D := E; end; |
Somit ist diese Formatierung keinesfalls falsch. Sie ist lesbar und ergonomisch, weil Abgängigkeiten sofort auf einen Blick erkennbar sind. Man sieht sofort, was zusammen gehört und was nicht. Man braucht nur einen Blick darauf zu werfen, um die Struktur zu erfassen.
Aber ich gestehe Dir das Recht zu, anderer Meinung zu sein. ;-)
Jakob_Ullmann - Mo 20.09.10 17:51
Ziel des Styleguides ist es aber, einen einheitlichen Programmierstil zu schaffen. Und es macht nun einmal fast jeder so:
Delphi-Quelltext
1: 2: 3: 4:
| if Condition then begin ... end; |
Eindeutig zu lesen hier:
http://de.wikibooks.org/wiki/Programmierkurs:_Delphi:_Programmierstil#Einr.C3.BCckung
Ich weiß, der ist nicht offiziell, aber hat wohl in dem Fall trotzdem seine Gültigkeit.
So etwas (in meinen Augen unleserliches) gibt es sonst nur beim GNU-C-Stil:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| int main (int argc, char *argv[]) { FILE *f; f = fopen (...); if (f != NULL) { if (!strcmp (argv[0], "")) { } } } |
Martok - Mo 20.09.10 18:09
Sowohl C als aus JS als auch Delphi kenn ich aus meinem Erfahrungsbereich nur mit hängendem Begin, also:
C oder JS
1: 2: 3:
| if (something) { doit(); } |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| if A then begin c:= 4; d:= 6; end else begin c:= 7; d:= 9; end; |
Also eher Python-Stil: man schätzt die Einrückung höher als das Schlüsselwort, was immerhin nur für den Compiler da ist - der Mensch sieht anhand der Einrückungen sofort was zusammengehört. Ein Zeilenumbruch von dem
begin ist zwar gut wenn man nach Zeilen bezahlt wird, aber sonst bringt er eher wenig.
Und zumindest bei JS gibt mir Crockford auch recht, wenn das auch eher daran liegt dass da der Zeilenumbruch tatsächlich einen Bedeutungsunterschied darstellen kann.
Wichtigster Punkt dürfte aber wohl sein, dass NIEMAND vor dem
then einen Zeilenumbruch hat.
Jakob_Ullmann - Mo 20.09.10 18:26
Naja, gerade bei C-ähnlichen Sprachen (syntaxbezogen) gibts ja tausende Stile. Um nur einige zu haben:
http://en.wikipedia.org/wiki/Indent_style
Bei Delphi gibt es da denke ich bei weitem weniger, die von mehr als einer Person benutzt werden. Ob das begin nun hängend ist oder nicht, ist, denke ich, ziemlich egal, da man beides ziemlich oft sieht. Aber dass begin zusätzlich eingerückt wird habe ich sonst noch nie gesehen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 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!