|
Earthball |
Top Previous Next |
|
Falls Ihnen der Name des Artikel bekannt vorkommt, dann liegen Sie richtig: der Code, den ich hier vorstelle, ist eine Umsetzung des Lite-C “Earthball” Beispiels, das bei neueren Engineversionen enthalten ist. Ich habe übrigens die earthball.c Datei ebenfalls im Codearchiv plaziert.
Starten wir zunächst die Demo; öffnen Sie das test.wmp Level und starten Sie es mit earthball.wdl als Skript; Sie sehen einen großen Raum, der die Erdkugel enthält. Laufen Sie darauf zu und drücken Sie dann die Leertaste – falls Sie A6 Commercial oder A6 Pro verwenden, sehen Sie, wie der Ball springt, als würde eine unsichtbare Kraft auf ihn wirken. Und genau das ist der Fall! Bewegen Sie die Kamera nach Belieben, auch Wände stellen kein Hindernis dar, deshalb können Sie diese Kraft überall anwenden. Sie müssen dem Ball nicht einmal nahe sein!
Das sieht nach einem guten Anfang für ein Basketballspiel aus; schauen wir uns den gesamten Code an:
Es ist nicht viel und sieht auch nicht kompliziert aus. Betrachten wir die Teile einzeln.
Zunächst definieren wir einen Entity Zeiger für den Ball (eBall), einen Sound, zwei globale Variablen und zwei Funktionsprototypen. Die main() Funktion beinhaltet den meisten Code: sie aktiviert die Stencil Buffer Schatten, setzt die Lautstärke für Geräusche auf 100, lädt unser Level, wartet bis das erledigt ist und erstellt dann die Ball Entity.
Diese eBall Entity wird mit Hilfe des Earth.mdl Models kreiert und zwar an der Position (0,0,100) und erhält keine Action, da der letzte Parameter gleich “null” ist. Die folgenden Codezeilen verwandeln das Model in eine Physikentity.
- phent_settype (eBall, ph_rigid, ph_sphere) sagt dem Ball, dass er eine Physikentity mit festem Körper ist (es sind auch Wasseroberflächen möglich) und seine Hülle für die Kollisionserkennung hat die Form einer Kugel. Es ist nämlich so, dass die Form des Models nicht automatisch festlegt, wie es sich als Physikentity verhält. Wenn ich earth.mdl durch einen Würfel ersetze, dann würde diese trotzdem rollen wie eine Kugel, weil phent_settype das Verhalten so festlegt.
- phent_setmass (eBall, 1, ph_sphere) definiert die Masse der Kugel auf 1 Kilogramm.
- phent_setfriction (eBall, 90) setzt den Reibungskoeffizienten auf 90. Es sind Werte zwischen 0 (Eisfläche ohne Reibung) und 100 (wie Gummi) möglich.
- phent_setelasticity (eBall, 75, 100) setzt den Bounce-Faktor des Balles auf 75 und die Minimalgeschwindigkeit auf 100. Was es mit dieser Minimalgeschwindigkeit auf sich hat? Wenn die Geschwindigkeit des Balles unter diesen Wert sinkt, dann wird die Elastizität auf 0 gesetzt, wodurch viele kleine Bewegungen vermiden werden, wenn der Ball liegenbleiben sollte.
- phent_setdamping (eBall, 30, 5) setzt den Dämpfungsfaktor auf 30 und die Dämpfung der Winkelgeschwindigkeit auf 5. Dabei handelt es sich um eine einfache und effektive Methode, um Luftwiderstand und Reibung zu simulieren, da sich der Ball sonst immer weiter drehen würde.
- phent_addvelcentral (eBall, vector(2,2,0)) gibt dem Ball eine kleine Geschwindigkeit zu Anfang. Ohne Schwerkraft und Dämpfung würde der Ball sich in die Ecke des Levels bewegen.
- ph_setgravity (vector(0,0,-500)) definiert die globale Schwerkraft für den Ball. Für gewöhnlich sollten hier 0en bei x un y und ein negativer Wert in z-Richtung stehen, wodurch Objekte nach unten fallen. Sie können die –500 auch durch 500 ersetzen und schauen, was geschieht.
Dies sind schon alle Zeilen, die den Ball korrekt einstellen. Die nächsten Zeilen aktivieren den Schatten und unterdrücken mögliche Schattenwürfe auf das Objekt selbst. Wir legen die Funktion Kick() (dazu später mehr) auf die Leertaste, definieren die Funktion Plop() als Eventfunktion für den Ball und lassen dann Reibungsevents für den Ball zu (sie entsprechen Kollisionsevents bei Entities, die keine Physik-Entities sind).
Sehen wir uns den zweiten Teil der main() Funktion an.
Dies ist der Code für die Kamera; der Vektor vForce wird aus den key_force-Werten für die Pfeiltasten und der Mausbewegung gewonnen wird und erlaubt uns das Drehen der Kamera. Vec_accelerate berechnet die korrekte Distanz (in Quants) für eine gegebene Geschwindigkeit und Beschleunigung, mit einem Reibungsfaktor von 0,8; das Resultat wird zu camera.pan addiert, was die Rotation bewirkt.
Mit den WASD-Tasten bewegen wir die Kamera im Level. Mit “Pos1” und “Ende” bewegen wir die Kamera hoch und runter; ändern Sie iSpeed, wenn Sie eine andere Bewegungsgeschwindigkeit wünschen. Der Code für die Kamerabewegung ist dem für die Drehung sehr ähnlich, der einzige beachtenswerte Unterschied ist die vec_rotate Anweisung, die dafür sorgt, dass sich die Kamera in Blickrichtung bewegt.
Plop() ist die Eventfunktion des Balles; sie sorgt dafür, dass ein Geräusch erklingt, wenn der Ball an etwas stößt. Die Funktion Kick() läuft, wenn die Leertaste gedrückt wird: es wird ein Vektor der Länge 150 in x-Richtung erstellt, der dann entöang der Kamera orientiert wird. Die dritte Komponente wird auf 75 gesetzt und die resultierende Kraft wirkt dann auf den Ball, wodurch er von der Kamera fortspringt, wenn die Leertaste gedrückt wird. Für ein anders Sprungverhalten, könnten Sie auch vSpeed.x z.B. auf 30 und vSpeed.z auf 100 setzen. Die letzte Codezeile ruft Plop() auf, wodurch das Geräusch auch ertönt, wenn die Leertaste gedrückt wird.
Ich hoffe, dass Sie etwas neugierig auf die Physikengine geworden sind. Lesen Sie das Handbuch für die anderen verfügbaren Funktionen und vor allem- experimentieren Sie!
|