workshop 21 |
Top Zurück Weiter |
Workshop 21: Modelle. Animierte Modelle.Wenn Sie vorhaben, ein Game zu erstellen, werden Sie für Ihre Fahrzeuge, Charaktere etc. Modelle verwenden wollen. Sie können Ihre Levels außerdem aber noch ein wenig aufpeppen indem Sie z. B. Modelle an die Wände hängen, so wie ich das mit dem Fackel-Modell gemacht habe:
Um nicht animierte Modelle in Ihrem Game zu verwenden, brauchen Sie nun wahrlich kein Genie zu sein; mit WED's"Add model" laden sie solche Modelle einfach ins Level und schieben sie dann dahin, wo Sie sie haben wollen. Allerdings sieht so ein nicht flackernde Fackel stinklangweilig aus. Wie aber verwenden wir diese so prima aussehenden animierten Modelle? Es gibt zwei Typen von animierten Modellen: 1) Modelle, die Animationsframes verwenden (auch Vertex-Animationen genannt). 2) Modelle, die ein Skelett haben und also über Knochen animiert werden (Bones-Animation). Der erste Modell-Typus wird, genauso wie ein Sprite, mithilfe von Frames animiert. Die Tatsache, dass ein Modell ein 3D-Objekt ist, sollte dabei allerdings nicht übersehen werden. Ich starte jetzt den kostenlosen Modell-Editoren, MED. Werfen wir einen Blick auf ein Modell, welches Animationsframes verwendet: Die Animationen können sowohl als Schleife (für stehen, gehen, laufen usw.) als auch als One-Shot-Animationen (für Springen, Ducken etc.) abgespielt werden. Sie können für Ihre Modelle ruhig viele Frames benutzen, der von animierten Modellen benötigte Video-Speicher hängt nämlich hauptsächlich von der Größe seiner Skin ab; die Anzahl seiner Animationsframes hat, bis Sie einmal bei Hunderten von Animationsframes angekommen sind, dagegen nur wenig Einfluss. Ein normales Modell hat verschiedene Animationen und in MED sehen die Frame-Namen so aus: Ok, MED stellt die verschiedenen Framebereiche nicht verschiedenfarbig dar (ich habe da mit einem Paintprogramm nachgeholfen) aber es ist mir wichtig, klarzumachen, dass jede Animation einen eigenen Namen haben sollte. Wenn Sie für ein Modell zum Beispiel verschiedene Sterbeanimationen ("death") haben, könnten Sie diese in etwa so benennen: - deatha1... deatha30 (die erste "death"-Animation hat 30 Frames) - deathb1... deathb5 (die zweite "death"-Animation hat 5 Frames) - rip1... rip8 (die dritte "death"-Animation hat 8 Frames) Damit versuche ich klarzumachen, dass der Name einer Animation nicht allzu wichtig ist, es aber ein ureigener Namen für jede einzelne Animation sein muss. Wie schreiben wir nun den Code, der diese Animationen anwendet? Starten Sie Lite-C, öffnen Sie workshop21 und starten Sie script21.c: Die Wache links spielt ihre "walk"-Animation ab, die auf der rechten Bildschirmseite hingegen macht gar nichts! Ok, warten wir noch ein paar Sekunden... Aha! Die Wache links führt eine Animationsschleife (walk) durch und die rechte Wache hat eine One-Shot-Animation abgespielt (death)! Untersuchen wir also die Skript-Datei: /////////////////////////////// #includeIch mochte lite-C von Anfang an, denn mit einigen wenigen Code-Zeilen kann man eine Menge erreichen. Werfen Sie einen Blick auf die Aktion, die die gehende Wache animiert: action
walking_guard() Da unsere "walk"-Animation ständig laufen muss, verwenden wir eine while (1)-Schleife. Gehen wir zur nächsten Code-Zeile: ent_animate(my, "walk", walk_percentage, ANM_CYCLE); Diese Anweisung animiert die Entity "my" (die, der diese Aktion zugewiesen ist) und benutzt dazu ihre "walk"-Animationsschleife mit der durch die Variable namens walk_percentage vorgegebenen Geschwindigkeit und spielt die Animation aufgrund des anm_cycle-Parameters in einem Zyklus (einer Schleife) ab. Hier ist die allgemeine Formel der ent_animate-Anweisung: ent_animate(entity_name, animation_name, animation_percentage, animation_mode); - "entity" ist der Name der Entity, die animiert wird. "My" brauchen Sie hier nicht, wenn Sie nicht wollen. Definieren Sie zuerst einen ´pointer´ auf eine Entity und schon können Sie auch ihren Namen verwenden: Beispiel: ENTITY*
kung_fu_master; - "animation_name" bezeichnet den Namen der Animation aus MED (aber ohne die zu den Frames gehörigen Figuren). Denken Sie daran, den Animationsnamen in Anführungszeichen zu setzen, sonst bekommen Sie eine Fehlermeldung. Noch einmal: Sie können in MED irgendeinen beliebigen Namen für die Animation nehmen, aber auch in Ihrer Skriptdatei müssen Sie genau denselben Namen verwenden: Bsp:: ent_animate(my, "smelling", nose_speed, ANM_CYCLE); - "animation_percentage" stellt den Prozentsatz der Animation dar. Es ist eine einfache var, die, wenn Sie das Modell animieren wollen, ihren Wert ändern muss. Wenn animation_percentage 0 ist, stellt das Modell seinen ersten Animationsframe dar und ist animation_percentage = 100, wird das Modell seine letzte Animationsrate zeigen. Unser Wache-Modell hat nur 4 Animationsframes fürs gehen (walk1... walk4) aber die Animation in unserem Demo sieht überhaupt nicht ruckelig aus! Wenn Sie einen Blick auf die Bilder unten werfen, werden Sie feststellen, dass es tatsächlich so aussieht, als hätte die Wache viel mehr Animationsframes! Dieses Feature nennt sich "smooth frame interpolation" und wird von Lite-C gemacht. Die Engine berechnet dabei Zwischen-Animationsframes, setzt sie zwischen die existierenden Frames und sorgt so dafür, dass die Animation, selbst wenn das Modell nur wenige Frames hat, sehr viel weicher aussieht
Die Variable namens "walk_percentage" aus unserem Beispiel erhöht ständig ihren Wert und darum ist unser gehendes Modell animiert. Zum Erhöhen oder Verringern der Animationsgeschwindigkeit spielen Sie, wenn Sie wollen, ein wenig mit der "3". - "animation_mode" sagt der Engine ob sie die Animation in einer Schleife (animation_mode == ANM_CYCLE) oder als One-Shot-Animation ((animation_mode = 0) abspielen soll. Wächst in einer zyklischen Animation der Wert von animation_percentage über 100, wird sie einfach wieder mit dem ersten Frame weitermachen, eine One-Shot-Animation wird dagegen mit dem letzten Frame aufhören. Wenn Sie vorhaben Ihre Modelle mithilfe von Animationsframes zu animieren, ist das alles, was Sie über ent_animate wissen müssen. Zur Vertiefung des Ganzen werfen wir nun aber noch einen Blick auf die Aktion, die dem Modell mit der One-Shot-Sterbeanimation zugewiesen ist: action
dead_guard() Der Sterbe-Kerl wartet 5 Sekunden bevor die Animation startet. Beim Aufruf von wait() mit einem negativen Parameter wartet die Engine wie Sie wissen, die angegebene Anzahl von Sekunden anstelle von Framezyklen. Benutzen etwas in der Art von wait (10);, um kürzere Wartepausen zu haben (in meinem Beispiel 10 Frames). Die ent_animate-Zeile spielt die death-Animation mithilfe der Variablen death_percentage ab. Da animation_mode auf Null gesetzt ist, handelt es sich um eine One-Shot-Animation. Wollen Sie die Animationsgeschwindigkeit erhöhen oder verringern, spielen Sie ein wenig mit der "2" herum. Ich habe für die sterbende Wache eine while (1)-Schleife genommen. Diese Schleife wird weiterlaufen auch wenn das Modell sein letztes "death"-Animationsframe abgespielt hat und macht weiter nichts, als ein wenig CPU-Leistung zu vergeuden. Eine etwas elegantere Version der Aktion sieht so aus: action
dead_guard() Die obige while-Schleife läuft solange death_percentage kleiner als oder gleich groß wie 100 ist und stoppt sobald death_percentage größer als 100 ist (das letzte "death"-frame ist abgespielt) und gestattet der CPU, diese (nun nutzlose) while-Schleife zu vergessen. Haben Sie unsere kleine Hausaufgabe vermisst? Haben Sie tatsächlich? Na dann versuchen Sie doch, eine einfache Aktion für ein mit der "walk"-Animation animiertes Modell zu erstellen, das sich gleichzeitig mithilfe von "c_move" bewegt. Benutzen Sie die Aktion walking_guard als Grundlage (die "walk"-Animation ist darin bereits als Schleife definiert) und fügen Sie dann innerhalb der while(1)-Schleife eine einzige Zeile ein in der "c_move" verwendet wird. Lösung: fügen Sie die Codezeile in die Aktion walking_guard ein: action
walking_guard() |