2009-02-25 7 views
1

Ich habe versucht, eine Leinwand zu verschieben, aber ich habe Probleme mit den Timern.WPF: Bester (zuverlässiger) Weg, um ein Canvas UND einen Monitor zu übersetzen (Jeder Schritt)

habe ich versucht, zwei verschiedene Methoden:

Erste Methode mit der BeginAnimation Funktion war, und die zweite mit DispatcherTimer Zecken, aber sie sind beide sehr unzuverlässig.

Ich muss jeden Schritt der Übersetzung überwachen. Mit der ersten Methode, die ich versuchte (BeginAnimation), habe ich die Kollisionserkennungslogik im Changed Ereignis gemacht, und mit der zweiten Methode (DispatcherTimer) mache ich die Kollisionserkennungslogik im Tick Ereignis des Timers.

Das Problem ist, dass beide sehr unzuverlässig sind. In dem Sinne, dass in meiner Kollisionserkennungslogik die Zeichenfläche die Übersetzung stoppen sollte, wenn die TranslateTransformY Eigenschaft < = 0 ist (technisch, wenn sie jeden Schritt überwacht, sollte sie jedes Mal bei 0 enden), aber mit beiden Methoden Ich habe versucht, es variiert, wenn es aufhört. Zum Beispiel, manchmal stoppt es bei 0, manchmal bei -1, -2, -3 und manchmal sogar bei -4.

Also was ist mit den Diskrepanzen? Warum überwacht es nicht jeden Schritt so, wie es soll?

Was kann ich tun, um diese Leinwand zu animieren und wirklich jeden Schritt zu überwachen? Ich meine jeden Schritt ... jedes Pixel, das es bewegt

Antwort

2

Ihr Problem ist, dass alles zeitbasiert ist, Sie erhalten nicht jedes Mal einen Callback, wenn sich die Leinwand um ein Pixel bewegt, Sie erhalten jedes Mal einen Callback, wenn ein Frame gerendert wird - und das System versucht es nicht einmal Rendern Sie die Bilder mit einer konstanten Rate.

Das Endergebnis ist, was Sie sehen, manchmal können Sie einen Rückruf nach einem 1/2-Pixel-Bewegung erhalten, weil alles glatt ging, das nächste Mal sind es zwei Pixel bewegen, weil der GC mitten im Frame und die Zeit danach trat dass es sich um eine 4-Pixel-Bewegung handelt, weil Word, das im Hintergrund läuft, einige CPU-Zyklen gestohlen hat, um den Spruch-Chekcer auszuführen.

So funktionieren diese Dinge, Sie können entweder damit umgehen und eine höhere Toleranz für die Kollisionserkennung festlegen, oder Sie können Ihre Simulationen außerhalb des Bildschirms auf einer "virtuellen Zeitachse" ausführen, in der Sie Objekte in beliebigem Tempo vorwärts bewegen können ohne die Realitäten von Bildschirmanimationen zu berücksichtigen.

Ich schrieb Software, die Simulation und Kollisionserkennung für echte Flugzeuge macht - und ich kann Ihnen sagen, dass es eine Menge harter Arbeit, jedes für Animationen gebaute Framework für das Verschieben von Dingen auf dem Bildschirm nicht für all die Arbeit, die Sie haben, optimiert wurde für qualitativ hochwertige Simulationen und trotzig nicht für eine genaue Kollisionserkennung.

0

Sie sollten in das Ereignis CompositionTarget.Rendering einhaken.

Wenn Sie sich in dieses Ereignis einklinken, wird es jedes Mal ausgelöst, wenn ein Frame gerendert wird, und Sie können Ihre Sprites entsprechend der verstrichenen Zeit seit dem letzten Ereignisanruf verschieben. Sobald Ihre Sprites nicht mehr bewegt werden, müssen Sie sich von dem Ereignis lösen, da WPF Frames so schnell wie möglich rendert, solange Ereignisse in das Ereignis eingebunden sind.

Für weitere Informationen über das Ereignis und wie es zu verwenden ist, versuchen Sie diesen blog Eintrag, der in Details geht und Code hat, den Sie herunterladen können, um zu untersuchen.