Autor |
Beitrag |
Mozartschokokuchenasi
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 21.09.12 23:14
Hallo,
ich bin neu hier und habe eine wichtige Frage, da ich erst seit ein paar Wochen mit Delphi in der Schule arbeite.
Wir sollen einen Tag/Nacht Wechsel mithilfe EINES Timers simulieren:
Dabei soll zunächst die Sonne von links in einem Bogen nach rechts wandern. Die soll dann, wenn sie rechts angekommen ist, verschwinden und links soll ein Mond erscheinen, der dann ebenfalls in einem Bogen von links nach rechts wandert.
Hier mein Quelltext:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TFTagNacht.TiTagNachtTimer(Sender: TObject); begin If (ImSonne.Left=ImSonne.Left +-0) Then begin ImSonne.Left:=ImSonne.Left +4; ImSonne.Top:=ImSonne.Top -2; end; |
Mein Problem ist, dass ich zwar weiß, wie ich die Sonne schräg zur Mitte "flüssig" laufen lassen kann, aber keine Ahnung habe, wie ich dem Timer sagen soll wie ich von da an die Sonne weiterhin nach rechts und nun aber logischerweise nach unten laufen lassen kann.
Bei mir bewegt sie sich also aus dem Formular raus in Richtung rechts oben.
Wie lautet dieser Befehl?
Was muss ich in den Quelltext also eingeben, damit die Sonne die Richtung wechselt?
Schon mal vielen Dank im Voraus...
Moderiert von Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Fr 21.09.2012 um 23:30
Moderiert von Narses: Delphi-Tags hinzugefügt
Zuletzt bearbeitet von Mozartschokokuchenasi am Sa 22.09.12 00:00, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 21.09.12 23:36
Moin und  in der EE!
Bitte ändere den Titel des Topics, da er wenig über das eigentlich Thema verrät. Hier der entsprechende Absatz aus den Richtlinien:
3.4 Frage formulieren - Der richtige Titel: | Formuliere den Betreff deiner Themen so, dass der Leser (und damit möglicherweise dein Helfer) anhand des Titels bereits weiß, worum es in diesem Topic geht. Titel wie z.B. "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" machen nicht neugierig auf mehr, ehrlich. Auch "HILFEEEE!!!!" hat sich bisher nicht bewährt. Wenn du ein Topic eröffnest ist es höchstwahrscheinlich, dass du Hilfe brauchst. |
Einfach unten in deinem ersten Beitrag auf  klicken und den Titel ändern. Danke dir!
Vorschlag für einen neuen Titel: " Grafik bewegen - wie Richtung wechseln?"
Und noch zu deinem Problem: Wie sieht denn dein aktueller Code in dem Timer-Ereignis aus? Wenn du den zeigst, können wir dir sehr viel besser helfen. Ohne müssen wir raten, was du da tust.
Also nur ein genereller Tipp: du addierst ja irgendeinen Wert zu den aktuellen Koordinaten des Grafik-Objekts. Um die Richtung umzudrehen brauchst du nur das Vorzeichen des Änderungswertes umzukehren.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 22.09.12 00:02
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Sa 22.09.12 00:03
Das nachfolgende wirst Du nicht abgeben können, aber vielleicht aknnst Du die eine oder andere Idee daraus ziehen...
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:
| unit Unit2;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm2 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormPaint(Sender: TObject); private FWinkel:Integer; public end;
var Form2: TForm2;
implementation uses Math; {$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject); begin Fwinkel := 270; Timer1.interval := 20; DoubleBuffered := true; end;
Function WinkelToTimeStr(Winkel:Integer):String; begin Result := TimeToStr(Winkel/360 +0.5); end;
procedure TForm2.FormPaint(Sender: TObject); var x,y,Size:Integer; Tag:Boolean; AddWinkel:Integer; begin Caption := WinkelToTimeStr(FWinkel); Tag := cos(DegToRad(Fwinkel))>0; if Tag then begin AddWinkel :=0; size := 20; Canvas.Brush.Color := clYellow; end else begin size := 10; Canvas.Brush.Color := clWhite; AddWinkel := 180; end; x := Width div 2 + Round(sin(DegToRad(Fwinkel + AddWinkel)) * Width / 2); y := Height - Round(cos(DegToRad(Fwinkel + AddWinkel)) * Width / 2); Canvas.Ellipse(x-Size,y-Size,x+Size,y+Size); end;
procedure TForm2.Timer1Timer(Sender: TObject); begin Fwinkel := (Fwinkel + 1) MOD 360; invalidate; end;
end. |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 22.09.12 00:12
Das ist glaube ich etwas zu komplex an dem gemessen, was ich bisher gelernt habe.
Geht das nicht noch etwas einfacher?
Kann man vielleicht die Koordinaten des Images angeben, damit der Timer weiß, dass, sobald das Image sich auf dieser Koordinate befindet, etwas anderes - in meinem Fall die Richtungsänderung - passiert?
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Sa 22.09.12 00:32
Das gäbe dann sehr "eckige" Bewegungen, ich weiß nichts von Deinen Vorkenntnissen, aber Sinus und Cosinus denke ich sind Dir ein Begriff.
Wenn Du jetzt auf dem Papier aufmalst wie Sonne und Mond bei welchem Winkel (360° = 24 Stunden) darzustellen sind kannst Du die Positionen, ich nehme an Deiner Shapes berechnen.
Du musst nur beachten dass
-in Delphi Sin/Cos den Wert im Bogenmaß erwarten(daher DegToRad)
-0° entgegen der mathematischen Konventionen oben liegt
-die y-Achse oben, nicht unten beginnt (also spiegeln = Clientheight abziehen)
Ansonsten, wenn Du Deinen bestehenden Code hinbiegen willst wirst Du Ihn hochladen müssen damit man Dir raten kann wo man etwas ändern könnte.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 22.09.12 00:51
Das mit den eckigen Bewegungen ist kein Problem, da wir in sehr kleinen Schritten die Sonne sich bewegen lassen und zudem das Interval des Timers auf 20 eingestellt ist. Genau so wie in dem Ausschnitt von meinem Quelltext sollen wir das machen.
Und ich hatte jetzt die Idee als nächstes zu schreiben: "wenn sonne punkt xy erreicht dann bewege sie nach rechts unten"
Könnte man das so machen?
Außerdem haben wir ja nur einen 180° Winkel, da, nachdem die Sonne einen Halbkreis gemacht hat, diese verschwinden soll und der Mond dort erscheinen soll, wo die Sonne auch startete.
Es wäre am besten, wenn jemand sich auf mein Wissen herablassen könnte und meinen Quelltext wie beschrieben fortführen könnte.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TFTagNacht.TiTagNachtTimer(Sender: TObject); begin If (ImSonne.Left=ImSonne.Left +-0) Then begin ImSonne.Left:=ImSonne.Left +4; ImSonne.Top:=ImSonne.Top -2; end; |
Der Anfang ist in dieser Form richtig und funktioniert auch.
Nur wie gesagt ist das Problem, dass logischerweise die Sonne immer weiter nach rechts oben aufsteigt, ich aber nicht weiß, wie ich festlegen kann WANN der Timer die Richtungsänderung vornehmen soll.
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Sa 22.09.12 01:02
Delphi-Quelltext 1: 2: 3:
| If ImSonne.Left < Width then TopAdd := -2 else TopAdd := 2; ImSonne.Left:=ImSonne.Left +4; ImSonne.Top:=ImSonne.Top - TopAdd; |
so kannst Du Code formatiert darstellen
[ delphi]
If ImSonne.Left < Width then TopAdd := -2 else TopAdd := 2; // Bildschirmmitte erreicht ? grob genähert fehlt imgsonne.width div 2
ImSonne.Left:=ImSonne.Left +4; //Sonne nach rechts Verschieben
ImSonne.Top:=ImSonne.Top - TopAdd; //Sonne nach oben oder unter verschieben
[/delphi]
Moderiert von Narses: Code-Tag ausgetrickst und Text angepasst.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Für diesen Beitrag haben gedankt: Mozartschokokuchenasi
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 22.09.12 01:32
Danke!!!
Werde dann morgen am Projekt weiterarbeiten.
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 22.09.12 12:09
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TFTagNacht.TiTagNachtTimer(Sender: TObject); begin If (ImSonne.Left = ImSonne.Left +-0) Then begin ImSonne.Left := ImSonne.Left +4; ImSonne.Top:=ImSonne.Top -2; end; If ImSonne.Left < Width then TopAdd := -2 else TopAdd := 2; ImSonne.Left:=ImSonne.Left +4; ImSonne.Top:=ImSonne.Top +2; end; |
So sieht jetzt mein Quelltext aus. Nun kommt natürlich die Fehlermeldung "Undefinierter Bezeichner: 'TopAdd'"
Was muss ich jetzt für TopAdd eintragen?
Mein Vorhaben ist, der Sonne bei dem Punkt 0/ca.500 die nächst Anweisung, also die Richtungsänderung zu geben.
Aber ich muss ja auch irgendwie sicher gehen können, dass die Sonne den Punkt überhaupt durchläuft...
Ihr könnt euch meinen Quelltext ja kopieren und gucken, was mein Problem ist.
Wenn ich wüsste wie dieser Schritt funktioniert. Müsste ich doch vom Prinzip auch wissen, WIE ich schreiben kann, WANN die Sonne dann verschwindet und dementsprechend der Mond am Startpunkt der Sonne erscheint.
Ich wäre für eine Hilfe sehr dankbar!!!
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Sa 22.09.12 13:22
was kommt hierbei wohl raus?
Delphi-Quelltext 1:
| if (ImSonne.Left = ImSonne.Left +-0) |
TopAdd ist einfach ein Integer der je nachdem ob die X_Mitte erreicht/überschritten wurde einen negativen oder eine positive Wert enthält.
Mach Dich von dem PUNKT frei, die Mitte der X-Ausdehnung genügt.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 22.09.12 18:08
Hallo,
Mozartschokokuchenasi hat folgendes geschrieben : | Ihr könnt euch meinen Quelltext ja kopieren und gucken, was mein Problem ist. |
Können wir eben nicht, da wir nur eine Prozedur sehen und nicht die Gesamtstruktur Deines Programms, inkl. Variablen usw.! Ich vermute, dass Dein Problem nicht nur die Timer-Routine ist.
Deshalb wäre es besser, wenn Du vielleicht Dein ganzes Projekt hier veröffentlichst. Dann ist richtige Hilfe schneller möglich.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: So 23.09.12 00:14
Warum?
Mein Projekt besteht doch nur aus dem Timer mit der bereits geposteten Prozedur und den beiden Images (Sonne und Mond).
Variablen und so etwas hatten wir im Unterricht noch gar nicht..
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: So 23.09.12 00:29
Also, ganz grausamer Code, aber etwas in der Art suchst Du?
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:
| procedure TForm2.FormCreate(Sender: TObject); begin Mond.Visible := false; Mond.Left := 0; Sonne.Left :=0; Mond.Top := Clientheight; Sonne.Top := Clientheight; end;
procedure TForm2.Timer1Timer(Sender: TObject); begin if Sonne.Visible then begin Sonne.Left := Sonne.Left + 4; if Sonne.Left>Clientwidth/2 then Sonne.Top := Sonne.Top + 2 else Sonne.Top := Sonne.Top - 2; if Sonne.Left>=ClientWidth then begin Sonne.Visible := false; Sonne.Left := 0; Mond.Visible := true; end; end; if Mond.Visible then begin Mond.Left := Mond.Left + 4; if Mond.Left>Clientwidth/2 then Mond.Top := Mond.Top + 2 else Mond.Top := Mond.Top - 2; if Mond.Left>=ClientWidth then begin Mond.Visible := false; Mond.Left := 0; Sonne.Visible := true; end; end;
end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Für diesen Beitrag haben gedankt: Mozartschokokuchenasi
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 23.09.12 01:02
Moin!
Mozartschokokuchenasi hat folgendes geschrieben : | Mein Projekt besteht doch nur aus dem Timer mit der bereits geposteten Prozedur und den beiden Images (Sonne und Mond). |
Keine Angst, hier klaut dir schon keiner deinen Code.  Aber grundsätzlich hat Mathematiker recht, es ist schon etwas Aufwand, deinen Code bei sich selbst mal eben zu testen, das geht mit einem fertigen Projekt viel leichter/schneller. Ausserdem: es kommt schonmal vor, dass ein Fragesteller aus Unkenntnis des Problems die "wichtigen" Teile gar nicht gezeigt hat.
Mozartschokokuchenasi hat folgendes geschrieben : | Variablen und so etwas hatten wir im Unterricht noch gar nicht.. |
Das hatte ich schon befürchtet.
@ Mathematiker: Algorithmischer Ansatz, das solltest du eigentlich kennen...
Auch wenn bummi soeben die Lösung als c&p-Code geliefert hat  (warum kriegen hier Anfänger/Schüler eigentlich immer doch irgendwann die Hausaufgaben gemacht, und dann sogar noch von gestandenen Entwicklern, die schon lange durchschaut haben sollten, dass das langfristig nicht hilft  ), trotzdem nochmal der Versuch, das Verständnis zu fördern: - Betrachten wir doch erstmal nur Sonne oder Mond und sagen "Himmelskörper" dazu. Wenn das mit der Sonne klappt, geht das mit dem Mond nachher genau so.
- Es gibt eine horizontale Bewegung und eine vertikale. Die müssen wir getrennt betrachten, das ist der Schlüssel!
- Erstmal die horizontale, weil uns sonst der Himmelskörper immer wieder rechts raus rennt.
Wie man das grundsätzlich macht, weißt du ja schon: Delphi-Quelltext 1:
| ImSonne.Left := ImSonne.Left +4; | Jetzt muss das aber irgendwann mal aufhören, nämlich am rechten Fensterrand. Den kriegen wir mit Self.ClientWidth raus. Problem: der Himmerlskörper hat auch eine Breite, die müssen wir natürlich berücksichtigen: Delphi-Quelltext 1: 2:
| if (Himmelskoerper.Left < Self.ClientWidth -Himmelskoerper.Width) then Himmelskoerper.Left := Himmelskoerper.Left +4; | Wenn du nur diesen Code in das Timer-Ereignis schreibst, dann bewegt sich der Himmelskörper einmal nach rechts und bleibt dann da stehen. Warum? Weil er nur dann nach rechts geschoben wird, wenn er noch nicht am Rand angekommen ist.
- Das ist jetzt natürlich nicht das, was wir wollen, der soll ja am rechten Rand wieder von links loslaufen. Also müssen wir die Bedingung umdrehen, um zu erkennen, wann der Rand erreicht ist und dann den Himmelskörper wieder auf den Anfang setzen. Ist der Rand noch nicht erreicht ("else"), dann weiter schieben:
Delphi-Quelltext 1: 2: 3: 4:
| if (Himmelskoerper.Left > Self.ClientWidth -Himmelskoerper.Width) then Himmelskoerper.Left := 0 else Himmelskoerper.Left := Himmelskoerper.Left +4; | Mit diesem Code im Timer-Ereignis "läuft" der Himmelskörper jetzt immer wieder von links nach rechts.
- Jetzt zur vertikalen Bewegung, den Ansatz hattest du ja schon:
Delphi-Quelltext 1:
| ImSonne.Top:=ImSonne.Top -2; | Aber auch diese Bewegung soll irgendwann mal aufhören. Wo? In der Mitte des Formulars. Wie kriegen wir die raus? Genau so wie gerade, und genau so müssen wir wieder die Ausdehnung des Himmelskörpers berücksichtigen: Delphi-Quelltext 1: 2: 3: 4:
| if (Himmelskoerper.Left < (Self.ClientWidth -Himmelskoerper.Width) div 2) then Himmelskoerper.Top := Himmelskoerper.Top -2 else Himmelskoerper.Top := Himmelskoerper.Top +2; |
- Und zum Abschluss das Ganze nochmal am Stück:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if (Himmelskoerper.Left > Self.ClientWidth -Himmelskoerper.Width) then Himmelskoerper.Left := 0 else Himmelskoerper.Left := Himmelskoerper.Left +4; if (Himmelskoerper.Left < (Self.ClientWidth -Himmelskoerper.Width) div 2) then Himmelskoerper.Top := Himmelskoerper.Top -2 else Himmelskoerper.Top := Himmelskoerper.Top +2; | Mit diesem Code im Timer-Ereignis haben wir die Bewegung komplett.
Schau mal, ob du das bis hier nachvollziehen kannst, dann kann man sich nochmal dem Problem mit dem "Umschalten" zwischen Sonne und Mond beschäftigen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Für diesen Beitrag haben gedankt: Mozartschokokuchenasi
|
|
Mozartschokokuchenasi 
Hält's aus hier
Beiträge: 8
|
Verfasst: So 23.09.12 11:33
Vielen Dank an Narses und bummi!!
Ihr habt mir echt geholfen.
Dank bummis Lösung und Narses' Erläuterung habe ich jetzt alles verstanden.
Ihr seid echt klasse!
Noch mal vielen vielen Dank an Euch!!!
|
|