Entwickler-Ecke
Multimedia / Grafik - Animation mit TTimer oder Schleife Verzögern?
boboy162 - Do 10.06.10 12:59
Titel: Animation mit TTimer oder Schleife Verzögern?
Hallo zusammen
Ich stehe grad vor einem Problem und hoffe dass ihr mir helfen könnt.
Ich hoffe ihr kennt alle das Galtonbrett?
(Mann hauen ein par Nägel an die Wand, aber nicht irgendwie sondern ganz oben in die 1.Reihe ein Nagel dann in die 2.Reihe drunter 2 Nägel und soweiter.Es ensteht eine Pyramide aus Nägeln. Dann kann man oben eine Kugel fallen lassen und die sucht sich dann ihren Weg durch die Nägel. )
Der Code der den Weg berechnet den die Kugel nimmt, steht schon ich bin jetzt dafür zuständig eine Animation draus zumachen bei der die Kugel sichtbar ist.
Fraqe: Ich hab versucht eine Animation mit dem TTimer Objekt auf die Reihe zukriegen.Leider bin ich auf das Problem gestoßen das diese Prozedur erst ganz am Ende nach dem alle anderen Prozeduren abgelaufen wurden sind ausgeführt wird.
-->Kann man dies irgendwie regel, bzw. kann man auf die Prozedur Timer1.Timer direkt zugreifen.
Wenn nicht -->Ich könnte mir das auch mit einer Verzögerung in einer For Schleife auch vorstellen.
Wie funktuniert das ungefähr?
VIELEN DANK
GRUß
Moderiert von
Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Do 10.06.2010 um 15:01
Bergmann89 - Do 10.06.10 17:19
Hey,
sleep is bei sowas ganz böse, weil sich dann die ganze anwendung aufhängt, der Timer was rshcon die richtige lösung. bei nem INtervall von 10-50ms sieht die Bewegung auch relativ flüssig aus. Du hast 2 möglichkeiten, entweder du berechnest dir am anfang den Weg der Kugel (evtl. pixelgenau zur besseren Darstellung) und lässt die Kugel dann einfach mit dem Timer den weg abschreiten, oder du berechnest es in echtzeit, das heißt du musst die die neue Position der Kugel in anhängigkeit der Zeit un der neuen Position berechnen. Ich weiß nicht in wieweit das deine Berechnungsprozedur zulässt, un wieviel du da umschreibenmusst, aber das sind die 2 Wege, die mir jetzt auf anhiebt einfallen...
MfG Bergmann
delfiphan - Fr 11.06.10 17:58
Du könntest einen Worker-Thread nehmen, dort den nächsten Schritt berechnen, ggf. warten, und mit Synchronize im MainThread die Grafik updaten.
boboy162 - Sa 12.06.10 18:45
Ahhhh dass hört sich genau so an wie ich es gerne hätte.
Was ist aber eigentlich ein Worker-Thread? und dass Synchronize?
Google hat dazu nicht grad viel ausgespuckt.
Vielen Dank
Gruß
Bergmann89 - Sa 12.06.10 19:04
Hey,
der Worker-Thread is einfach ein Thread, der die Berechnungen passend zu deiner Animation ausführt, da kannst du dann mit Sleep arbeiten, weil dann nur der Thread hängen bleibt, du die Anwendung aber normal benutzen kannst. Synchronize dinet zum Aufrufen von Methoden aus einem Thread heraus. Methoden, die mit Synchronize aufgerufen wurden, werden IMMER im Kontext des Main-Threads ausgeführt. Sowas benutzt man, wenn man Events an den Main-Thread schicken will. (Das steht aber glaube auch in der Delpi Hilfe)
MfG Bergmann.
delfiphan - Sa 12.06.10 19:11
Sowas wie im Anhang.
Bergmann89 - Sa 12.06.10 19:17
Hey,
wenn du dir die Mühe machst un die ArbeitsForm an den Thread übergibst solltest du diese dann vlt auch im Thread benutzen ;)
Delphi-Quelltext
1: 2: 3: 4:
| procedure TWorkerThread.Draw; begin FForm1.Button1.SetBounds(FPosition.X, FPosition.Y, 50, 50); end; |
MfG Bergmann.
delfiphan - Sa 12.06.10 19:27
Nein, ich habe ein Property Form1 gemacht, das den Thread überprüft, weil das sonst die nächste Frage ist, wieso es manchmal nicht funktioniert.
Bergmann89 - Sa 12.06.10 19:41
Okay, ich nehm alles zurück, die Property hab ich übersehen, sry :oops:
boboy162 - So 13.06.10 02:04
hmmmm...hört sich bisher für mich bissle Komplex an... naja mir würds eigentlich auch reichen wenn das Programm sich während der Schleife beenden liese. Weil irgendwie blockiert dieses "Sleep" alles.
Gibts irgendie eine alternative Möglichkeit zum "Worker-Thread" um das laufenden Programm (also es befindet sich in einer Schleife mit "Sleep()") komplett zubeenden?
Also ButtenClick Ereignis mit "close;" Befehl funktuniert nicht...soweit bin ich.
Vielen Dank schonmal
Gruß
Delete - So 13.06.10 02:28
Nicht das
Sleep blockiert alles, sondern weil du in jeden Schleifendurchlauf
Synchronize aufrufst, womit der Code dann wieder im Kontext des Hauptthreads mit deinem Fenster ausgeführt wird.
boboy162 hat folgendes geschrieben : |
Ich hab versucht eine Animation mit dem TTimer Objekt auf die Reihe zukriegen.Leider bin ich auf das Problem gestoßen das diese Prozedur erst ganz am Ende nach dem alle anderen Prozeduren abgelaufen wurden sind ausgeführt wird. |
Welche Prozedur wird nach allen anderen Prozeduren ausgeführt? Das Timer Ereignis sollte immer nach dem angegebenen Intervall aufgerufen werden.
Bergmann89 - So 13.06.10 06:54
Hey,
ich glaub er hat noch gar keine Threads benutzt. Er redet noch von der normalen Anwendung. Wenn du nach dem sleep ein ProgressMessages setzt sollte es möglich sein, den Abbrechen Button zu drücken, aber wirklich ellegant ist die Lösung nich, im Gegenteil!
Und soweit ich das verstanden hab wird die Prozedur, die den Weg berechnet vor der Timer-Prozedur ausgeführt. Deshalb muss man die RechenProzedur auch von der Zeit abhängig machen un dann jedesmal im Timer-Event aufrufen.
MfG Bergmann
jaenicke - So 13.06.10 08:18
boboy162 hat folgendes geschrieben : |
Fraqe: Ich hab versucht eine Animation mit dem TTimer Objekt auf die Reihe zukriegen.Leider bin ich auf das Problem gestoßen das diese Prozedur erst ganz am Ende nach dem alle anderen Prozeduren abgelaufen wurden sind ausgeführt wird. |
Das hört sich so an als hättest du das Konzept von TTimer falsch verstanden. In jedem Timer-Event musst du
einen Schritt machen. Nach dem abgelaufenen Intervall, z.B. 500 Millisekunden, wird dann das nächste Mal das Timer-Event aufgerufen. Dann kommt der nächste Schritt.
Wenn du in dem Timer-Event eine Schleife und Sleep benutzt, dann kannst du dir das komplett sparen. Das hat dann nichts mit einem Timer zu tun.
boboy162 - So 13.06.10 19:45
ok mir ist schon klar dass das besser ist wenn ich den TTimer benutze.
Nur das ganze lief so ab, dass ich und ein Freund ein Projekt vorgeschrieben bekommen haben. Den ganzen Teil der den Weg berechnet etc. hat er gemacht, und ich soll dazu die Grafik Animieren.
Naja da man das Programm nach der Animation beenden kann denke ich reicht das, weil wenn ich jetzt den TTimer benutzten wollte dann müsste ich zuviel umschreiben.
Aber gibt es wirklich keinen Weg das Programm während der Schleife (mit sleep) dass Programm zubeenden. Ich bin für alle Lösungen offen. Sonst geb ich mich nun auch so zufrieden.
Vielen Dank
Gruß
delfiphan - So 13.06.10 20:46
Angenommen, du möchtest deine Schleife nicht auseinanderreissen und stückweise ausführen (da dir das zu aufwändig ist) hast du folgende Möglichkeiten:
1. Führe die Schleife in einem Thread aus und zeichne synchronisiert im MainThread (Beispiel oben)
2. Du verwendest Sleep oder Delay wie oben erwähnt. Das Problem hier ist, dass es Code braucht, der wie die Hauptschleife Windows-Messages dispatcht (bei Delay ist das bereits eingebaut). Du solltest nach jeder dispatchten Message auf Application.Terminated und den ModalResult der Form überprüfen und ggf. die Schleife verlassen. OnCloseQuery finde ich ist jetzt weniger geeignet dafür.
3. Du berechnest die Positionen vor und zeichnest die Kugel dann mit einem Timer.
4. Du verwendest Continuation und einen Timer. Den sequentiellen Code mit der Schleife führst du dann stückweise im Timer aus (Beispiel im Anhang).
Mehr fällt mir jetzt nicht ein...
boboy162 - Mo 14.06.10 12:08
Danke für die Zusammenfassung...so gefällts mir wenn alles auf den Punkt gebracht wird :)
Ich werd dann mal die einzelnen Lösungen nochmal überdenken und dann die geeignetste umsetzten.
Danke
Gruß
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!