Bewährte Methoden für Sprite-Animationen

18

Ich möchte einen besseren Überblick darüber bekommen, wie Menschen in der realen Welt mit ihren Animationen umgehen.

Laden Sie 1 großes Bild und zeichnen Sie dann verschiedene Rechtecke basierend auf dem Animationsrahmen?

Laden Sie X-Bilddateien in ein Array und zeichnen Sie das Element im Array basierend auf dem Animationsrahmen?

Wie gehen Sie mit unterschiedlich langen Animationen für verschiedene Sprites um?

Nehmen wir an, ein Charakter braucht zu Fuß 4 - 8 Frames und die Wellen am Strand nur 2 - 3 Frames. Wie würden Sie mit dieser Situation umgehen? Siehe unten

Dim Waves(1) as Sprite
Dim Char(5) as Sprite

Sub Animate()
     Frame += 1
     Draw Char(Frame)
     Draw Waves(Frame)
     If Frame = 5 Then Frame = 0
End Sub

Offensichtlich würde Waves einen Fehler machen, der außerhalb der Grenzen liegt.

Oder macht sich Ihr Sprite Sorgen um seine eigene Animation und kümmert sich überhaupt nicht um den Frame? Hat jedes Sprite eine eigene Animationsschleife?

jblaske
quelle

Antworten:

23

Ich habe es in der Vergangenheit so gemacht, dass die Animationsdaten von der Animationswiedergabe getrennt wurden . Ein Animationkann dann im Grunde genommen ein Array von Framesund ein paar Eigenschaften werden, die beschreiben, wie sich die Animation verhalten soll (wenn sie sich schleift usw.).

Normalerweise lade ich ein Bild und zeichne Teile davon.

Jede FrameAnimation ist im Wesentlichen ein Rechteck und eine Zeitdauer. Dies ermöglicht, dass einige Frames länger angezeigt werden als andere, was Sie vielleicht möchten oder auch nicht. Wenn Sie möchten, dass alle Frames in Ihrer Animation für dieselbe Zeit angezeigt werden, speichern Sie sie in Ihrem AnimationObjekt.

Alles, was zum Abspielen einer Animation benötigt wird, hat eine eigene, auf AnimationPlayerdie verwiesen werden kann Animation. Das Player-Objekt kümmert sich um das Abspielen der Animation und stellt das "aktuelle Bild" zur Verfügung.

Der Vorteil für mich war, dass ich eine einzelne Instanz von Animationso vielen Objekten haben konnte, die gleichzeitig auf verschiedene Rollen zeigen und diese spielen konnten. Es war auch einfach, Animationen zu ändern, indem man einfach auf AnimationPlayerein anderes AnimationObjekt zeigte und die Wiedergabe zurücksetzte.

Bearbeiten : Hier ist eine recht einfache JavaScript-Implementierung des oben beschriebenen Systems . Ich habe es in ein paar Minuten als Demonstration zusammengeschmissen . "Echter" Code hätte mehr Funktionen. Sie benötigen jedoch einen modernen Browser, der sowohl Canvas- als auch Daten-URIs unterstützt.

Zack der Mensch
quelle
1
Was er sagte. Außerdem ist es häufig praktisch, für jedes Bild in einer Animation einen x / y-Versatz festzulegen, damit Sie die Sprite-Bilder eng in ihre Begrenzungsrahmen packen und sie dann in einer Animation an der gewünschten Stelle platzieren können. Sie können damit auch einige grundlegende Dinge tun, z. B. Wackeln, indem Sie nur ein einzelnes Bild verwenden.
Munificent
Ja, dem stimme ich voll und ganz zu. In der Tat ermöglicht das von mir verwendete Animationssystem dies. Es macht es viel einfacher, die Position eines Rahmens zu ändern, ohne die Bilddaten zu bearbeiten.
Zack The Human
Nettes Arbeitsbeispiel, WOW Daumen hoch. Würde es empfehlen.
DFectuoso
Eine wichtige Einschränkung der Art der Animation besteht darin, dass die Figur nicht aus einem anderen Blickwinkel betrachtet werden kann - vom Betrachter weggehen, auf den Betrachter zugehen usw. Oder irre ich mich?
Majid Fouladpour
@MajidFouladpour Ich glaube nicht, dass diese Art von Einschränkung bei dieser Technik besteht. Sie haben einfach verschiedene AnimationData-Objekte für jeden "Betrachtungswinkel".
Zack The Human
1

Ich hätte eine Animation, wie viele Frames es hat. Wo und wie diese gespeichert werden, ist mit Ausnahme von Leistungsproblemen (wie Sie sie möglicherweise in derselben Textur haben möchten) relativ irrelevant. Ich würde nie 1 zum Bildzähler hinzufügen, ich würde deltaTime * animSpeed ​​hinzufügen und diesen Wert bei der Anzeige in eine Ganzzahl umwandeln. Auf diese Weise können Sie die Animationen verlangsamen oder beschleunigen und sind unabhängig von der Framerate.

Ein Sprite hätte also eine Animation, die sich selbst aktualisiert.

Kaj
quelle
0

Warum nicht einfach die Anzahl der Frames für jedes Ihrer Objekte speichern lassen? Persönlich gebe ich die Anzahl der Frames in der Animation an meine Objekte in ihren Konstruktoren weiter, dann habe ich eine Standardfunktion Animate (), die die Anzahl der Frames in der Animation berücksichtigt.

SD021
quelle
0

Das hängt von der Implementierung ab. In meiner Engine mache ich Animationen in Direct3D und DirectDraw.

In DirectDraw erstelle ich ein großes Bild. Es wird sowieso alles im Systemspeicher gespeichert, was schließlich zu einem eindimensionalen Datenblock führt.

Vorteile:

  • Leicht zwischen den Bildern zu bewegen. Ändern Sie den Startzeiger, addieren Sie die Teilung (die Gesamtbildbreite) jedes Jahr und Sie sind golden.

Nachteile:

  • Sie können nicht nur einen Frame auf den Bildschirm kopieren, sondern müssen dies manuell tun.

  • Riesiger Speicherblock. Das Herumtollen von Bildern wird mit einer Strafe geahndet.

In Direct3D verwende ich separate Texturen. Dies liegt daran, dass ich keine Ahnung von den Texturbeschränkungen eines Geräts habe und daher nicht weiß, ob es auch Texturen unterstützt, die die Größe des gesamten Bildes haben.

Vorteile:

  • Sie können einen Rahmen direkt auf den Bildschirm kopieren, da es sich um separate Objekte handelt.

Nachteile:

  • Fehlende Speicherausrichtung.
knight666
quelle
0

In meinen Spielen habe ich meiner Sprite-Basisklasse das Wissen vermittelt, wie man sich selbst zeichnet, und alle animierten Elemente erben dieses Wissen: Anzahl und Dauer der Animationsrahmen, Position auf dem Bildschirm usw. Die Hauptspielschleife durchläuft nur alle der Sprites und bittet jeden, sich selbst zu zeichnen, wie es passt. Scheint recht gut zu funktionieren und ist etwas modularer zu booten: Wenn Sie ein neues Sprite mit einer anderen Animationsschleife hinzufügen (oder noch komplexer: mehrere Animationszustände), müssen Sie Ihr Animate nicht zurückschreiben und neu schreiben () Routine zur Berücksichtigung der zusätzlichen Komplexität:

Dim Waves as Sprite
Dim Char as Sprite

Sub Animate()
     Char.update()
     Waves.update()
End Sub

Bei jedem Aufruf der update () -Methode eines Sprites wird festgelegt, ob dasselbe Bild wie beim letzten Mal neu gezeichnet, zum nächsten Bild in der aktuellen Animation gewechselt oder zu einer neuen Animation gewechselt werden soll.

Dies hat den zusätzlichen Vorteil, dass es viel einfacher ist, die Framerate anzupassen, um unterschiedlichen Takt- / Plattform-Rendergeschwindigkeiten Rechnung zu tragen, da die einzige Änderung darin besteht, wie oft Sie Animate () aufrufen.

Rylee Corradini
quelle