Kostik's Kurs - Die Grundformen2

Einführung

Wenn ich gewöhnlich Wörter hörte wie "Primitives" (=Grundformen), hatte ich keine Ahnung was damit gemeint war. Nun, es ist nicht so schlimm, wie ihr vielleicht denkt. Grundsätzlich sind "Primitives" Grundbausteine (-form) aus denen dann die fertigen 3D-Modelle bestehen und diese zu komplexen Grafiken werden. Um z.B. eine Linie (line) zu malen, werden Pixel benutzt. Die Linien werden dann zum Zeichnen eines Quaders benutzt. Um ein Schiff zu erstellen benutzt man viele von diesen Grundformen, wie Quader, Kugeln, Zylinder, Kegel usw... und diese und all diese Grundformen bestehen wiederum aus Dreiecken (triangle), auch Polygone genannt.

Benutze also diese Grundformen (primitives) als Bausteine und es wird klappen.

Blitz3D Bausteine (Grundformen, "Primitives")

Es gibt einige primäre Grundbausteine um eine Figur mit Blitz3D zu erstellen: Quader (cube), Kugeln (sphere), Kegel (cone) und Zylinder (cylinder). Sie werden alle fast auf die gleiche Weise benutzt, du musst dich also nur darum sorgen, welchen Baustein, wo und wie du ihn in die Szene einbaust.

Ich persönlich ziehe es vor ein Modellingprogramm (siehe Milkshape3D) zur Erstellung solcher komplexer Objekte zu benutzen und sie dann einfach in Blitz3D zu laden, als das alles direkt mit Blitz3D zu coden (das macht fast keiner, Es wird immer ein 3D-Modeller benutzt. Ich persönlich empfehle euch Milkshape3D, siehe dazu unter "Was ist Milkshape3D?" auf meiner Seite www.Blitz3D.istcool.de. Anm. v. Konstantin). Mit so einem Modellingprogramm lässt sich ein "Mesh" (Drahtgitter-Modell) viel einfacher formen, verändern und mit neuen "Teilen" versehen. Zur Erklärung, ein Mesh ist ganz einfach ein Haufen Dreiecke (Polygone), die zu einem Gebilde (Figur, Modell) zusammengefügt werden.

Dennoch, die Grundformen zu kennen und sie benutzen zu können ist immer noch sehr wichtig, weil sie dir helfen werden zu verstehen wie die Blitz3D Welt funktioniert, und es gibt eine große Anzahl von Situationen wo man sie benutzen kann und wo es keine vordefinierten "Meshes" (=Objekte) gibt.

Erstellen und Zeichnen der Grundformen ("Primitives")

Als erstes erstellen wir von jedem Element eins und bringen sie auf den Bildschirm. Hier der Code:

;Als erstes setzen wir die Auflösung.
;Ich benutze 640x480 hier.
GRAPHICS3D 640,480

;Zweitens, genau wie in Blitz2D, benutzen
;wir "Doublebuffering"
SETBUFFER BACKBUFFER()

;Jetzt brauchen wir eine Kamera
camera = CREATECAMERA()

;Und wir stellen die Kameara so ein, dass sie auf dem
;ganzen Bildschirm angezeigt wird
CAMERAVIEWPORT camera,0,0,GRAPHICSWIDTH(),GRAPHICSHEIGHT()

;Einen Zylinder erstellen
GLOBAL cylinder=CREATECYLINDER(6)

;Nach links zum Punkt (-6) von Mittelpunkt aus (=0) bewegen
MOVEENTITY cylinder,-6,0,8

;Quader (Box) erstellen
GLOBAL box=CREATECUBE()

;Nach links zum Punkt (-2) von Mittelpunkt aus (=0) bewegen
MOVEENTITY box,-2,0,8

;Kugel erstellen
GLOBAL sphere=CREATESPHERE(6)

;Nach rechts zum Punkt (2) von Mittelpunkt aus (=0) bewegen
MOVEENTITY sphere,2,0,8

;Kegel erstellen
GLOBAL cone=CREATECONE(6)

;Nach rechts zum Punkt (6) von Mittelpunkt aus (=0) bewegen
MOVEENTITY cone,6,0,8

;Schleife bis die Taste "ESC" gedrückt wird
WHILE NOT KEYHIT(1)

;Die Animationen aktualisieren und
;Kollision abfragen
UPDATEWORLD

;Aktuellen Bildschirm rendern
RENDERWORLD

;Die Seite "flippen"
FLIP

WEND ;Ende der While-Schleife


Wie du siehst, werden alle "Dinge" (Entitys) auf die gleiche Weise erstellt, mit Ausnahme des Quaders (cube). Der Quader Befehl ist anders, weil er er keine geglätteten Ecken (smooth Edges) braucht. Wie du schon von dem letzen Tutorial (Blitz3D - Die ersten Schritte) weist, sind Segmente nichts anderes als Dreiecke. Je mehr Segmente man hat, desto glätter wird das Objekt. Nun, ein Quader ist rechteckig, also werden auch keine geglätteten Ecken gebraucht. Jedoch würden die Kugeln, Kegel und Zylinder ohne diese geglätteten Ecken sehr kantig aussehen, weshalb auch die Segment-Einstellung und -Kontrolle hier auch sehr wichtig ist.

Bewegen der Dinge:

Wir erstellen nun eine Kugel und lassen sie auf dem Bildschirm hüpfen (Es werden keine Physikalischen Berechnungen benutzt, die Kugel wird einfach weit weg bewegt und wieder herangezogen):

;Als erstes setzen wir die Auflösung.
;Ich benutze 640x480 hier.
GRAPHICS3D 640,480

;Zweitens, genau wie in Blitz2D, benutzen
;wir "Doublebuffering"
SETBUFFER BACKBUFFER()

;Jetzt brauchen wir eine Kamera
camera = CREATECAMERA()

;Und wir stellen die Kameara so ein, dass sie auf dem
;ganzen Bildschirm angezeigt wird
CAMERAVIEWPORT camera,0,0,GRAPHICSWIDTH(),GRAPHICSHEIGHT()

;Kugel erstellen
GLOBAL sphere=CREATESPHERE(6)

;Einfach eine kleine Variable die wir dann der Z-Angabe
;des MoveEntity Befehls addieren oder subtrahieren
v=1

;While-Schleife bis "ESC"-Taste gedrückt wird
WHILE NOT KEYHIT(1)

;Wenn die Z-Koordinate der Kugel grösser 50 wird
;fangen wir an die Kugel wieder zu uns zu ziehen
IF ENTITYZ(sphere) > 50 THEN v=-1

;Wenn die Kugel schon ganz auf dem Bildschirm ist
;fangen wir an die Kugel von uns wegzustossen
IF ENTITYZ(sphere) < 1 THEN v=1

;Bewegen der Kugel um den "V" Wert von der
;aktuellen Position
MOVEENTITY sphere,0,0,v

;Die Animationen aktualisieren und
;Kollision abfragen
UPDATEWORLD

;Aktuellen Bildschirm rendern
RENDERWORLD

;Die Seite "flippen"
FLIP

WEND ;Ende der While-Schleife


Eines der Dinge die jetzt erklärt werden müssen, sind die Werte für die Richtungs-Kontrolle. Wie du wahrscheinlich schon gemerkt hast, bewirkt das Ändern der X-Werte eine Bewegung von rechts nach links (oder von links nach rechts) auf dem Bildschirm. Positive Werte bewegen das Objekt (Entity) nach rechts, negative Werte nach links. Null (0) ist der Scheitel (Mitte) der X-Position.

Genauso ist die Mitte des Y-Wertes =0. Ändern der Y-Werte bewegt das Objekt nach oben oder unten. Positive Werte bewegen nach oben und negative Werte nach unten.

Z ist da etwas anders. Setzt man den Z-Wert gleich null, bedeutet das, dass das Objekt wörtlich auf der Kamera "sitzt". Wenn man also den Z-Wert gleich Null (=0) setzt, wird man das Objekt nicht mehr sehen. Ich habe rausgefunden, dass man mindestens den Wert 1 haben muss um das Objekt zu sehen. Um das Objekt weiter weg zu bewegen, muss man einfach positive Werte zum aktuellen Z-Wert addieren. Um es zu sich herzuziehen (und es auch hinter die Kamera zu bewegen) muss man Werte abziehen (eigentlich addiert man negative Werte, so kann man sich das besser vorstellen, denke ich. Anm. v. Konstantin)

Wenn man sich die MoveEntity Zeile anschaut, sieht man, dass der Z-Wert nur (1) oder (-1) wird. Es gibt keine Addition oder Subtraktion. Das hängt von folgendem ab: Blitz3D sagt zu sich: "Okay, von der aktuellen Position aus erhöhe (bewege) ich den Z-Wert um 1 (oder -1)". Also sagen wir nur um wie viele Einheiten und in welche Richtung Blitz3D das Objekt bewegen soll, um die Einzelheiten kümmert sich Blitz3D selbst.

Schließlich gibt es da noch den EntityZ(entity) Befehl. Dieser Befehl gibt ganz einfach den Z-Wert zurück an dem sich gerade ein Objekt (dieses Entity in den Klammern ist eben der Name des Objekts, z.B. in unserem Beispiel die Kamera=camera oder der Quader=box. Anm. von Konstantin) befindet. In unserem Beispiel frage ich also nur ab ob das Objekt weiter als 50 Einheiten weg ist, wenn ja, sage ich dem Programm, dass es die Kugel wieder zurückbewegen soll. Es gibt die gleichen Befehle für X und Y, sie nennt man EntityX und EntityY, logischerweise :-).

Drehen von Objekten

Obwohl das Drehen von Objekten schon im vorigen Tutorial angesprochen wurde, werde ich es hier noch mal genau erklären. Es ist nicht viel anders, aber es gibt da einen wichtigen Unterschied, den man im folgenden sieht:

;Als erstes setzen wir die Auflösung.
;Ich benutze 640x480 hier.
GRAPHICS3D 640,480

;Zweitens, genau wie in Blitz2D, benutzen
;wir "Doublebuffering"
SETBUFFER BACKBUFFER()

;Jetzt brauchen wir eine Kamera
camera = CREATECAMERA()

;Und wir stellen die Kameara so ein, dass sie auf
;dem ganzen Bildschirm angezeigt wird
CAMERAVIEWPORT camera,0,0,GRAPHICSWIDTH(),GRAPHICSHEIGHT()

;Kegel erstellen
GLOBAL cone=CREATECONE(6)

;Einfach eine kleine Variable die wir dann der Z-Angabe
;des MoveEntity Befehls addieren oder subtrahieren
v = 1

;While-Schleife bis "ESC"-Taste gedrückt wird
WHILE NOT KEYHIT(1)

;Wenn di Z-Position des Kegels grösser als 50 wird
;zieht das Programm zu uns her
IF ENTITYZ(cone) > 50 THEN v=-1

;wenn der Kegel direkt auf dem Bildschirm ist
;schiebt das Programm ihn wieder von uns weg
IF ENTITYZ(cone) < 1 THEN v=1

;Den Kegel um "v" Einheiten in die aktuelle
;Richtung bewegen
MOVEENTITY cone,0,0,v

;drehen des Kegels um alle Drei Achsen (x,y,z)
TURNANTITY cone,v,v,v

;Die Animationen aktualisieren und
;Kollision abfragen
UPDATEWORLD

;Aktuellen Bildschirm rendern
RENDERWORLD

;Die Seite "flippen"
FLIP

WEND ;Ende der While-Schleife


Wenn man jetzt das Programm startet, sieht man dass der Kegel nicht einfach gerade vor und zurück läuft, wie die Kugel vorhin. Das kommt davon, dass wir den Kegel gedreht haben. Wenn man den TurnEntity Befehl benutzt, dreht es nicht eifach das Objekt, sonder auch die Richtung wo es sich dann hinbewegt wenn MoveEntity aufgerufen wird. Das ist cool, denn wenn man z.B. ein herumfliegendes Flugzeug hat und diesen dreht, muss man sich nicht um die Berechnung der Flugbahn machen, einfach den TurnEntity Befehl aufrufen und das Flugzeug wird sich automatisch in die richtige Richtung bewegen. (Das macht alles wirklich viel einfacher! Mark hat an alles gedacht! Anm. v. Konstantin).

Ersetze mal ein "v" im TurnEntity Befehl mit einer Null (0) und du wirst selber merken wie der TurnEntity Befehl funktioniert.

Weiter mit Kurs 3



Quelle: www.BlitzBasic.istcool.de