Das Datenmodell in meinem Programm hat eine Anzahl von diskreten Zuständen, aber ich möchte den Übergang zwischen diesen Zuständen animieren. Während der Animation wird das, was der Benutzer auf dem Bildschirm sieht, von den zugrunde liegenden Daten getrennt. Sobald die Animation abgeschlossen ist, stimmen sie wieder überein.
Nehmen wir zum Beispiel an, wir haben ein einfaches Spiel, in dem Snuffles, der Hase, auf einem 2D-Gitter herumhüpft. Das Snuffle-Modell enthält ganzzahlige x / y-Koordinaten. Wenn der Spieler Snuffles sagt, nach Norden zu springen, wird seine y-Koordinate sofort um Eins verringert. Auf dem Bildschirm sollte Snuffles jedoch immer noch an seinem alten Ort sein. Dann fährt Snuffles Bild für Bild fort, um zu seiner neuen Position zu springen, bis er an der Position angezeigt wird, die sein Modell angibt.
Wenn wir also Snuffles zeichnen, können wir einfach seine Koordinaten in seinem Modell nachschlagen. Aber wenn er hüpft, ist diese Koordinate falsch.
Wenn sich immer nur eine Sache auf dem Bildschirm bewegt, kann ich einfach damit durchkommen, den gesamten Spielzustand einzufrieren und dem Benutzer nicht zu erlauben, etwas zu tun, bis Snuffles mit dem Springen fertig ist. Aber was, wenn es mehr als einen Hasen auf dem Bildschirm gibt?
Es wird schlimmer, wenn Elemente interagieren, zusammenführen oder teilen. Wenn Snuffles magisch mit einem Hut verschmilzt, um eine Kartoffel zu werden, an welchem Punkt löscht das Datenmodell den Hasen und den Hut und fügt die Kartoffel hinzu? Wenn dies sofort geschieht, verliert die Ansicht sofort den Zugriff auf Informationen über Snuffles und die Kartoffel, die sie noch benötigt, um die Animation der magischen Fusion zu zeichnen.
Ich bin bei der Implementierung von animierten GUIs, insbesondere von Spielen, mehrfach auf dieses Problem gestoßen und habe keine befriedigende Lösung gefunden.
Unbefriedigende sind:
Nehmen Sie die Änderungen sofort vor, setzen Sie dann jedoch alle weiteren Änderungen im Modell aus, bis die Animation aufgelöst wurde. Lässt Dinge nicht mehr reagieren und funktioniert nicht, wenn sich mehr als eine Sache bewegen kann oder Dinge auf komplexe Weise interagieren.
Verschmelzen Sie das Modell und die Ansicht - Snuffles erhält Fließkomma-Koordinaten und wahrscheinlich eine z-Koordinate, um anzuzeigen, wie weit er sich befindet. Die Regeln des Modells werden dadurch massiv komplexer, da das Modell keine prägnanten Aussagen mehr machen kann wie "man kann nicht nach Norden springen, wenn es eine Mauer bei (x, y - 1)" gibt. Jede Änderung an den Regeln dauert viel länger und die Entwicklung verlangsamt sich zu einem Crawling.
Behalten Sie, was zu einem Duplikat der Daten in der Ansicht führt. SnufflesModel hat ganzzahlige Koordinaten, SnufflesSprite jedoch Gleitkomma-Koordinaten. Am Ende duplizieren Sie einige der Modellregeln in der Ansicht und müssen sie synchron halten. Verbringen Sie viel Zeit mit dem Debuggen, um sicherzustellen, dass SnufflesModel und SnufflesSprite unter seltenen Umständen nicht synchronisiert werden.
Meine beste Wette ist momentan Option 3, aber sie kommt mir kaum so elegant vor. Gedanken?
Sie benötigen ein stärkeres Modell, um die Zeitkomponente von Änderungen zu berücksichtigen:
Jedes Sprite muss eine Warteschlange von Animationsaktionen verwalten, die es ausführen soll. Das Hinzufügen von Animationen zur Warteschlange sollte eine zeitlose Aktion (Spielzeit) sein. In der Warteschlange befindliche Animationen werden Frame für Frame ausgeführt, wenn sie ein Häkchen von der Animationsuhr erhalten. Mit der Warteschlangenfunktion können Sie das Modell vom Grafiksubsystem und den Animationen trennen.
Jede Animation in der Warteschlange enthält eine Modellaktion, die ausgeführt wird, wenn die Animation abgeschlossen ist. Einige Sprachen machen das einfacher, z. mit anonymen Funktionen in C # oder JavaScript. In anderen Sprachen können Sie stattdessen einen Rückruf verwenden. Mit der Modellaktion können Sie festlegen, wie sich das Modell nach Abschluss der Animation ändern soll.
Sprites können Koordinaten mit hoher Auflösung (z. B. Fließkomma) tragen, während das Modell bei ganzzahligen Einsen bleibt. Sprites müssen jedoch nichts über die Spielregeln wissen - die Aktionen in der Warteschlange für Animationen - Abschlussmodelle gehen damit um.
Modelleinheiten sollten in der Lage sein, Übergangszustände zu berücksichtigen: Erscheinen, Verschwinden und Verschieben. Auf diese Weise können Sie die Regeln für Objekte im Übergang nicht überprüfen.
Um die Quest von Snuffle zu implementieren, könntest du dann:
Benutzer hat gefragt, Snuffle nach Norden zu bewegen? - (1) Überprüfe, ob die Regeln den Zug erlauben, (2) reihe eine Bewegungsanimation auf das Sprite des Snuffle, gekoppelt mit einer Landung Modellaktion. Setze das Modell des Hasen in einen Übergangszustand.
Snuffes Landung Modellaktion bringt das Modell des Hasen zurück in einen normalen Zustand und überprüft den Landeplatz und die Regeln. Nach einem Hut suchend, stellt er eine Kartoffelanimationsanimation (die "Verschmelzung") und zwei Verschwindenanimationen für das Häschen und den Hut ein.
Die Modellaktionen für die verschwundenen Animationen löschen den Hasen und Hut, wenn sie fertig sind.
Tags und Links model-view-controller animation data-structures graphics