Parallaxe
- Tiefeneindruck bewegter Objekte |
Wie
ein scrollender Hintergrund realisiert wird,
ist beim Hintergrund-Scrolling
beschrieben, und bei Transparente
Farben ist
erklärt, wie man eine Szene
in DirectDraw zusammenstellen kann.
|
Die Simulation
der Überlappung von Objekten ist aber leider
nur das halbe Bild. Andere Effekte kommen noch ins
Spiel, die besonders deutlich werden, wenn die Szene
in Bewegung gesetzt wird.
|
Wenn
wir uns bewegen, scheinen sich nahegelegene Objekte
in die entgegengesetzte Richtung zu bewegen. Dieses
Phänomen wird als relative Bewegung bezeichnet.
Nicht die Objekte bewegen sich, sondern wir. Wenn
wir aber Objekte betrachten, die weiter weg sind,
passiert etwas Interessantes - diese scheinen sich
nicht so schnell zu bewegen. Betrachten Sie das folgende
Abbildung, die die gleiche Szene aus verschiedenen
Blickwinkeln zeigt.
|
|
Beachten
Sie, dass sich der Baum deutlich weiter bewegt hat
als das Haus im Hintergrund. Dieser Effekt wird als
Parallaxe bezeichnet und ist der Schlüssel
zu unserer Wahrnehmung von Tiefe in einer bewegten
Szene.
|
Um dies
in einem Programm einsetzen zu können, wird für
jede Ebene ein Fließkommawert verwendet, der
mit der Bewegung der Szene multipliziert wird. Höhere
Werte werden für die Ebenen näher am Betrachter
verwendet, wodurch diese sich schneller bewegen, als
die Objekte im Hintergrund.
|
Das Parallaxe-Beispiel basiert auf dem Beispiel aus
dem Hintergrund-Scrolling. Wieder ist es
eine Stadtszene, nun jedoch in mehrere Ebenen für
einen 3D-Effekt aufgeteilt. Zusätzlich gibt es
noch ein Taxi, das sich unabhängig von der Position
des Betrachtes durch die Szene bewegt.
|
Das Beispiel benutzt ein Array für die Ebenen mit
folgender Struktur.
|
|
|
'Struktur für Ebenen definieren
Type strcLAYER
surf As DirectDrawSurface7
blit_flags As Long
start_x As Long
start_y As Long
interval As Long
parallax As Double
lwidth As Long
lheight As Long
End Type
Public Layers(3) As strcLAYER |
|
|
surf - Enthält die Oberfläche mit
dem Bild für diese Ebene.
blit_flags - Enthält die Bits für
BltFast() einschließlich der Flags für
die Farbmaskierung, falls erforderlich.
start_x
- Definiert die linke Startposition des Bildes auf
dieser Ebene. Bilder werden alle interval Pixel
nach rechts wiederholt.
start_y
- Bestimmt die Y-Koordinate für alle Kopien des
Bildes.
interval
- Definiert den Abstand auf der X-Achse zwischen den
Kopien dieses Bildes.
parallax
- Definiert den Parallaxfaktor für diese Ebene.
Dies ist ein Multiplikator für die Scrollrate,
die über die Tastatur eingestellt wird.
lwidth
- Definiert die Oberflächenbreite des Quellbildes.
lheight
- Definiert die Oberflächenhöhe des Quellbildes.
|
Dieses
Array wird beim Laden der Bilder zum Programmstart
gefüllt und beim Durchlauf der Ebenen in der
Darstellungsschleife verwendet. Die
Ebenen bekommen unterschiedlich Parallaxe-Werte, so
bewegt sich der Hintergrund langsamer und der Vordergrund
schneller.
|
Wie
Sie Bitmaps in DirectDraw laden können,
wird bei Bitmaps laden und anzeigen
ausführlich beschrieben, wobei das
Beispiel auch die Farbmaskierung aus Transparente
Farben
verwendet.
|
Nun
kommt aber endlich die 3D-Magie! Das Tastaturereignis
legt die Scrollingposition in x_pos (siehe Code-Beispiel) fest, die Position der einzelnen Ebenen
wird jedoch über deren Parallaxefaktor bestimmt.
|
Zur
Bestimmung der Position einer Ebene wird die normale
Scrollingposition mit dem Parallaxefaktor der Ebene
multipliziert (siehe Code-Beispiel). Als nächstes
wird die Position der ersten Instanz des Objekts in
der Ebene bestimmt und alle Kopien durchlaufen, bis
alle gefunden wurden, die innerhalb des sichtbaren
Bereichs liegen. Wie unter Bitmaps zu-
und ausschneiden, Animation
gezeigt, wird das Objekt
ggf. geclippt.
|
|
|
'Schleife über die Ebenen
For i = 0 To NUM_LAYERS
'Parallaxe-Position der Ebene berechnen
screen_pos = x_pos * Layers(i).parallax
'Position des ersten Objekts setzen
obj_pos = Layers(i).start_x
'Schleife bis zum Rand des Bildes
Do While (obj_pos < (screen_pos + 640))
'Ist das Objekt auf dem Schirm?
If (obj_pos + Layers(i).lwidth) >= screen_pos Then
'Ja, Abstand zum linken Rand des Bildes berechnen
screen_x = obj_pos - screen_pos
'Objekt clippen wenn notwendig
srcrect.Left = 0
srcrect.Top = 0
srcrect.Right = Layers(i).lwidth
srcrect.Bottom = Layers(i).lheight
If screen_x < 0 Then
srcrect.Left = srcrect.Left - screen_x
screen_x = 0
ElseIf (screen_x + srcrect.Right) > 640 Then
srcrect.Right = 640 - screen_x
End If
'Objekt auf den Bildschirm zeichnen
BackBuffer.BltFast screen_x, Layers(i).start_y, _
Layers(i).surf, srcrect, _
Layers(i).blit_flags
End If
'Erhöhen zur nächsten Objektposition
obj_pos = obj_pos + Layers(i).interval
Loop
Next i
|
|
|
Zum Schluss wird noch das Taxi gezeichnet, und kommt deshalb erst jetzt, weil es das naheste Objekt
in der Szene ist. Einen abschließenden Rahmen
bildet noch eine Benutzeroberfläche, die über
die Szene gezeichnet wird.
|
|
|
'Bildposition für Taxiparallaxe berechnen
screen_pos = x_pos * 3
'Ist das Taxi auf dem Bilschirm?
If (taxi_pos + Taxi_Width) > screen_pos And _
taxi_pos < (screen_pos + 640) Then
'Ja, berechne den Abstand zum linken Bildschirmrand
screen_x = taxi_pos - screen_pos
'Objekt clippen, wenn notwendig
srcrect.Left = 0
srcrect.Top = 0
srcrect.Right = Taxi_Width
srcrect.Bottom = Taxi_Height
If screen_x < 0 Then
srcrect.Left = srcrect.Left - screen_x
screen_x = 0
ElseIf (screen_x + srcrect.Right) > 640 Then
srcrect.Right = 640 - screen_x
End If
'Taxi auf den Bildschirm zeichnen
BackBuffer.BltFast screen_x, 220, _
bmpTaxi, srcrect, _
DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
End If
'Taxiposition verringern, aber innerhalb eines
'Bereiches damit wir es oft sehen
taxi_pos = taxi_pos - 3.5
If taxi_pos < (screen_pos - 5000) Then
taxi_pos = screen_pos + 5000
End If
'Benutzeroberfläche zeichnen
With srcrect
.Top = 0: .Left = 0:
.Right = 640: .Bottom = 480
End With
BackBuffer.BltFast 0, 0, bmpInterface, _
srcrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
|
|
|
Dies schließt die Darstellung der Szene ab.
Diese Technik, auch als Seiten-Scrolling (Side Scrolling)
bekannt, ergibt einen guten 3D-Eindruck ohne die Kosten
der Erstellung und Darstellung einer 3D-Welt. Ein
Beispiel für Parallaxe können Sie hier downloaden,
und den ausführlichen Code finden Sie in unserer Tipp-Rubrik.
|
|
|
Download
tip0182.zip
(459 kB) |
|
Downloads
bisher: [ 2903
] |
|
|