Sprite-Animationen

Sprite-Engine

Die Qt Quick Sprite-Engine ist ein stochastischer Zustandsautomat, der mit der Fähigkeit kombiniert ist, Bilder mit mehreren Frames einer Animation zu zerhacken.

Zustandsmaschine

Eine Hauptfunktion der Sprite-Engine ist ihr interner Zustandsautomat. Dieser ist nicht identisch mit den Zuständen und Übergängen in Qt Quick und ähnelt eher einem herkömmlichen Zustandsautomaten. Sprites können gewichtete Übergänge zu anderen Sprites oder zurück zu sich selbst haben. Wenn eine Sprite-Animation beendet ist, wählt die Sprite-Engine das nächste Sprite zufällig aus, basierend auf den gewichteten Übergängen, die für das gerade beendete Sprite verfügbar sind.

Sie können das aktuell spielende Sprite auf zwei Arten beeinflussen. Sie können es willkürlich zwingen, sofort mit der Wiedergabe eines beliebigen Sprites zu beginnen, oder Sie können ihm sagen, dass es allmählich zu einem bestimmten Sprite übergehen soll. Wenn Sie es anweisen, schrittweise überzugehen, wird es das Ziel-Sprite erreichen, indem es gültige Zustandsübergänge durchläuft und dabei die geringste Anzahl von dazwischenliegenden Sprites verwendet (aber relative Gewichtungen ignoriert). Auf diese Weise können Sie leicht eine Übergangsanimation zwischen zwei verschiedenen Sprites einfügen.

Betrachten Sie als Beispiel das obige Diagramm, das die Sprites für eine hypothetische 2D-Plattformspielfigur darstellt. Zu Beginn zeigt die Figur den stehenden Zustand an. Von diesem Zustand aus geht sie, sofern keine externen Eingaben erfolgen, entweder in die Warteanimation, die Gehanimation oder erneut in die Stehanimation über. Da die Gewichte für diese Übergänge jeweils eins, null und drei sind, besteht eine Chance von eins zu vier, dass er die Warteanimation spielt, wenn die Stehanimation beendet ist, und eine Chance von drei zu vier, dass er die Stehanimation erneut spielt. Dies ermöglicht eine Figur, die während des Wartens ein leicht animiertes und variables Verhalten zeigt.

Da es einen gewichtslosen Übergang zur Laufanimation gibt, wird die Stehanimation normalerweise nicht dorthin übergehen. Wenn du aber als Zielanimation die Geh-Animation einstellst, wird die Geh-Animation abgespielt, wenn sie die Steh-Animation beendet hat. Befand sie sich vorher in der Warteanimation, würde sie diese beenden, dann die Stehanimation und dann die Gehanimation abspielen. Die Geh-Animation wird dann so lange abgespielt, bis die Ziel-Animation nicht mehr gesetzt ist; dann wird nach Beendigung der Geh-Animation zur Steh-Animation gewechselt.

Wenn Sie dann den Zielzustand auf die Sprunganimation setzen, wird die Gehanimation beendet, bevor die Sprunganimation abgespielt wird. Da die Sprunganimation nicht in andere Zustände übergeht, wird die Sprunganimation so lange abgespielt, bis der Zustand gewechselt wird. In diesem Beispiel könnten Sie den Zustand auf "Gehen" zurücksetzen und die Zielanimation auf "Gehen" oder auf "Nichts" ändern (was dazu führen würde, dass nach der Geh-Animation die Steh-Animation abgespielt würde). Beachten Sie, dass Sie durch das erzwungene Setzen der Animation sofort mit dem Abspielen der Animation beginnen können.

Eingabeformat

Die Dateiformate, die von der Sprite-Engine akzeptiert werden, sind die gleichen wie die Dateiformate, die von anderen QML-Typen akzeptiert werden, z. B. Image. Um das Bild animieren zu können, benötigt die Sprite-Engine jedoch eine Bilddatei, die alle Bilder der Animation enthält. Sie sollten in einer zusammenhängenden Zeile angeordnet sein, die vom rechten Rand der Datei bis zu einer unteren Zeile reichen kann, die am linken Rand der Datei beginnt (und direkt unter der vorherigen Zeile platziert ist).

Nehmen wir als Beispiel das obige Bild. Betrachten Sie zunächst nur die schwarzen Zahlen, und nehmen Sie an, dass die Quadrate 40x40 Pixel groß sind. Normalerweise wird das Bild von der linken oberen Ecke aus gelesen. Wenn Sie die Bildgröße mit 40x40 Pixeln und eine Bildanzahl von 8 angeben, werden die Bilder in der Reihenfolge ihrer Nummerierung eingelesen. Das Bild oben links wäre das erste Bild, das Bild oben rechts wäre das fünfte Bild, und dann würde es in die nächste Zeile springen (an der Pixelposition 0,40 in der Datei), um das sechste Bild zu lesen. Das Lesen würde nach dem Bild mit der Nummer 8 aufhören, und wenn sich in dem Quadrat unter dem vierten Bild Bilddaten befänden, würden diese nicht in die Animation aufgenommen werden.

Es ist möglich, Animationen von einem beliebigen Offset aus zu laden, aber sie werden immer noch dem gleichen Muster folgen. Betrachten wir nun die roten Zahlen. Wenn wir festlegen, dass die Animation an der Pixelposition 120,0 beginnt, mit einer Bildanzahl von 5 und der gleichen Bildgröße wie zuvor, dann werden die Bilder so geladen, wie sie in Rot nummeriert sind. Die ersten 120x40 des Bildes werden nicht verwendet, da das Programm mit dem Lesen von 40x40 Blöcken an der Position 120,0 beginnt. Wenn das Ende der Datei bei 160,0 erreicht ist, beginnt das Programm mit dem Lesen der nächsten Zeile bei 0,40.

Die blauen Zahlen zeigen die Bildnummern, wenn Sie versuchen würden, zwei Bilder dieser Größe zu laden, beginnend bei 40,40. Beachten Sie, dass es möglich ist, mehrere Sprites aus einer Bilddatei zu laden. Die roten, blauen und schwarzen Zahlen können alle als separate Animationen in dieselbe Sprite-Engine geladen werden. Der folgende Code lädt die Animationen wie im Bild angegeben. Er legt auch fest, dass die Animationen mit 20 Bildern pro Sekunde abgespielt werden sollen.

Sprite {
    name: "black"
    source: "image.png"
    frameCount: 8
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}
Sprite {
    name: "red"
    source: "image.png"
    frameX: 120
    frameCount: 5
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}
Sprite {
    name: "blue"
    source: "image.png"
    frameX: 40
    frameX: 40
    frameCount: 2
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}

Die Frames innerhalb einer Animation müssen die gleiche Größe haben. Bei mehreren Animationen innerhalb derselben Datei ist dies jedoch nicht der Fall. Bei Sprites ohne Angabe von frameCount wird davon ausgegangen, dass sie die gesamte Datei einnehmen, und Sie müssen die Framegröße angeben. Bei Sprites ohne Angabe einer Frame-Größe wird davon ausgegangen, dass sie quadratisch sind und die gesamte Datei ohne Umbruch einnehmen, und Sie müssen eine Frame-Anzahl angeben.

Die Sprite-Engine kopiert und zerschneidet die Bilder intern, um sie in ein leichter lesbares internes Format einzupassen, was zu einigen Einschränkungen des Grafikspeichers führt. Da alle Sprites für eine einzelne Engine in derselben Textur sein müssen, kann der Versuch, viele verschiedene Animationen zu laden, auf eingebetteten Geräten an die Grenzen des Texturspeichers stoßen. In diesen Fällen wird eine Warnung auf der Konsole ausgegeben, die die maximale Texturgröße angibt.

Es gibt mehrere Werkzeuge, die dabei helfen, eine Reihe von Bildern in Sprite Sheets zu verwandeln. Hier sind einige Beispiele:

QML-Typen unter Verwendung der Sprite-Engine

Sprites für die Sprite-Engine können mit dem Typ Sprite definiert werden. Dieser Typ enthält die Eingabeparameter sowie die Länge der Animation und gewichtete Übergänge zu anderen Animationen. Es handelt sich um eine reine Datenklasse, die nichts rendern kann.

SpriteSequence ist ein Typ, der eine Sprite-Engine verwendet, um die in ihm definierten Sprites zu zeichnen. Es ist eine einzelne und eigenständige Sprite-Engine und interagiert nicht mit anderen Sprite-Engines. Sprite Typen können von Sprite-Engine-verwendenden Typen gemeinsam genutzt werden, aber dies geschieht nicht automatisch. Wenn Sie also ein Sprite in einem SpriteSequence definiert haben, müssen Sie es in der Sprites-Eigenschaft eines anderen SpriteSequence neu definieren (oder auf denselben Sprite -Typ verweisen), um zu dieser Animation zu wechseln.

Zusätzlich kann ImageParticle Sprite Typen verwenden, um Sprites für jedes Partikel zu definieren. Dies ist wiederum eine einzelne Sprite-Engine pro Typ. Dies funktioniert ähnlich wie SpriteSequence, aber es hat auch die parametrisierte Variabilität, die der ImageParticle Typ bietet.

AnimatedSprite-Typ

Für Anwendungsfälle, bei denen kein Übergang zwischen Animationen erforderlich ist, bietet sich der Typ AnimatedSprite an. Dieser Typ zeigt Sprite-Animationen mit demselben Eingabeformat an, aber nur eine nach der anderen. Er bietet auch eine feinere manuelle Steuerung, da es keine Sprite-Engine gibt, die das Timing und die Übergänge hinter den Kulissen verwaltet.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.