2017-04-20 1 views
0

Ich arbeite mit einem JavaFX-Canvas, das die Bewegung von Shape- und Polyline-Objekten im Laufe der Zeit animiert. Gegenwärtig wird für jeden Rahmen die Position von X und Y für jede Form oder Polylinie in einer Liste nach Bedarf bearbeitet, und das Objekt wird verschoben. Dies ergibt etwa 20-30fpsJavaFX Canvas Effiziente Animationen

Ein früherer Ansatz, den ich versucht habe, löscht einfach die Leinwand in jedem Rahmen und zeichnet jedes Objekt erneut. Keine Listen von Objekten sind gespeichert. Dies ergibt 60fps

Diese zweite Methode scheint eine weit unordentlichere Ansatz noch ergibt sich eine viel bessere Framerate.

Gibt es Best Practices oder empfohlene Methoden zur Animation auf einem JavaFX-Zeichenbereich? Alles sauber und empfohlen, ergibt dennoch eine gute Framerate?

Vielen Dank

+0

Können Sie den Code veröffentlichen? – Oswald

+1

Ich bezweifle, dass Sie die Leinwand in Ihrem ersten Beispiel verwenden. Sie können nichts auf einem JavaFX-Canvas verschieben, indem Sie nur die x/y-Positionen einiger Shapes ändern. Ich schätze, du sprichst hier über den Szenengraphen. Könnten Sie das bitte klären? – mipa

Antwort

2

Ich habe gerade einen Vortrag über diese Themen auf der JavaLand Konferenz. Es ist in der Tat richtig, dass für allgemeine Animationen mit pfadbasierten Formen (wie Polylinie und Polygon) die Verwendung der Canvas derzeit die schnellste Standardoption ist. Dies ist auf einen Fehler in JavaFX zurückzuführen, der solche Animationen über den Szenegraph langsam machen kann. Ich habe dieses Problem gemeldet und eine Fehlerbehebung ist auf dem Weg.

https://bugs.openjdk.java.net/browse/JDK-8178521

In dieser JIRA Frage verweise ich im Vergleich zu Software-Hardware-Rendering, aber es wirkt sich auch gegen Leinwand-Rendering-Szene Diagramm, weil die Leinwand von diesem Fehler betroffen zu sein scheint nicht.

+0

Beachten Sie, dass die Kommentare unter dem Fehlerbericht eine mögliche Problemumgehung vorschlagen: Setzen Sie die Systemeigenschaft 'prism.cacheshapes' auf' false'. Sie können dies über die Befehlszeile mit dem VM-Argument '-DPrism.cacheshapes = false' tun. Wenn Sie das programmatisch machen wollen, müssen Sie dies anscheinend tun * bevor * die 'Application'-Klasse geladen wird (ich weiß nicht warum), was bedeutet, dass Sie eine separate Hauptklasse mit' System.setProperty ("prism.cacheshapes") benötigen "," false ");' und dann 'Application.launch (MyApplicationSubclass.class);'. –

+1

Ich bezweifle, dass dies eine gute Idee ist, es sei denn, Sie tun nichts anderes als animierende Formen. Normalerweise ist es sinnvoll, Formen zu cachen. – mipa

Verwandte Themen