You are on page 1of 27

J2ME.

Tworzenie gier
Autor: Janusz Grzyb
ISBN: 978-83-246-1263-5

Stwrz wasn gr do telefonu komrkowego


Poznaj technologi J2ME
Zaprojektuj interfejs uytkownika dla gry
Zaimplementuj mechanizmy wywietlania grafiki 3D

Wspczesne telefony komrkowe przestay by urzdzeniami wykorzystywanymi


wycznie do prowadzenia rozmw i wysyania wiadomoci SMS. Mona je dzi
stosowa do wielu innych celw peni rol notatnikw, dyktafonw, aparatw
fotograficznych, odtwarzaczy plikw MP3 i przenonych konsoli do gier. Jednak
najwiksze moliwoci telefony komrkowe uzyskay dziki zaimplementowaniu w nich
jzyka Java. Mobilna Java pozwala nie tylko na tworzenie dodatkowych narzdzi, ale
take gier zarwno prostych platformwek, jak i skomplikowanych gier
wykorzystujcych zoone algorytmy wywietlania grafiki trjwymiarowej.
Ksika J2ME. Tworzenie gier to podrcznik, dziki ktremu opanujesz technologi
J2ME i wykorzystasz j do napisania wasnej gry do telefonu komrkowego. Czytajc
j, poznasz podstawy mobilnej Javy, zainstalujesz narzdzia niezbdne do pracy
i dowiesz si, jak zbudowana jest aplikacja przeznaczona do wykorzystania w tym
urzdzeniu. Zaprojektujesz interfejs uytkownika i zastosujesz podstawowe metody
generowania grafiki 2D. Poznasz take bibliotek Java Mobile 3D i wykorzystasz j
do stworzenia prawdziwej gry z trjwymiarow grafik, uwzgldniajc tekstury
obiektw, owietlenie i cieniowanie. Dowiesz si rwnie, jak budowa gry dla wielu
graczy czcych si ze sob poprzez interfejs Bluetooth.

Wydawnictwo Helion
ul. Kociuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl

Instalacja i konfiguracja narzdzi Wireless Toolkit, Ant i Antenna


Tworzenie interfejsu uytkownika
Rysowanie podstawowych obiektw graficznych
Algorytm ledzenia promieni wiata
Reprezentacja obiektw 3D w Java Mobile 3D
Modelowanie owietlenia i cieniowania
Animowanie obiektw
Przygotowanie sceny gry w programie Blender
Komunikacja poprzez interfejs Bluetooth
Tworzenie gry typu multiplayer

Nie szukaj w sieci gier do swojej komrki napisz wasn!

Spis treci
Wstp .............................................................................................. 7
Rozdzia 1. Podstawy ....................................................................................... 11
Konfiguracja .................................................................................................................... 12
Profil ................................................................................................................................ 12
Najpopularniejsze pakiety opcjonalne ............................................................................. 13
Hello World ..................................................................................................................... 15
Wireless Toolkit .............................................................................................................. 17
Instalacja pakietu ....................................................................................................... 17
KToolbar ................................................................................................................... 19
Narzdzia specjalne ................................................................................................... 22
Ant ................................................................................................................................... 25
Instalacja .................................................................................................................... 26
Praca z Antem ........................................................................................................... 27
Tworzenie wersji dystrybucyjnej aplikacji ............................................................... 30
Antenna ............................................................................................................................ 32
Instalacja .................................................................................................................... 32
Nowa wersja skryptu wykorzystujemy Antenn .................................................. 33
WTKPREPROCESS i kompilacja warunkowa w Javie ........................................... 35
Podsumowanie ................................................................................................................. 37
Pytania kontrolne ............................................................................................................. 38
Zadania ............................................................................................................................ 38

Rozdzia 2. Interfejs uytkownika ..................................................................... 39


Podstawy interfejsu graficznego midletw ...................................................................... 39
Hierarchia klas interfejsu uytkownika ..................................................................... 41
Komendy ................................................................................................................... 42
Dodajemy wicej ekranw ........................................................................................ 45
Pozostae ekrany interfejsu wysokopoziomowego .......................................................... 48
Lista wyboru .............................................................................................................. 48
Alert ........................................................................................................................... 50
Klasy Form i Item kontrolki zoone .......................................................................... 52
Interfejs niskopoziomowy ............................................................................................... 55
Klasa Canvas i Graphics ........................................................................................... 56
Rysowanie na paszczynie ekranu ........................................................................... 58
Obsuga zdarze ........................................................................................................ 68

J2ME. Tworzenie gier


Podsumowanie ................................................................................................................. 74
Pytania kontrolne ............................................................................................................. 74
Zadania ............................................................................................................................ 75

Rozdzia 3. Gry 3D w 2D Wolfenstein ........................................................... 77


Raycasting ....................................................................................................................... 77
Algorytm DDA ledzenia promienia ......................................................................... 81
Implementacja wersja uproszczona ............................................................................ 84
Klasa Raycaster ......................................................................................................... 84
Klasa Player ............................................................................................................... 89
Klasa midletu ............................................................................................................. 90
Jeszcze jeden problem ............................................................................................... 92
Metoda dokadna ............................................................................................................. 93
Obliczamy wsprzdne wektora promienia ............................................................. 93
Algorytm DDA w metodzie dokadnych podziaw ................................................. 94
Poprawiona implementacja metody Render .............................................................. 95
Podsumowanie ................................................................................................................. 97
Pytania kontrolne ............................................................................................................. 98
Zadania ............................................................................................................................ 98

Rozdzia 4. Wprowadzenie do Java Mobile 3D ................................................... 99


Reprezentacja obiektw 3D ........................................................................................... 100
Ukady wsprzdnych .................................................................................................. 101
Ukad globalny, ukady lokalne i pozycjonowanie kamery .......................................... 102
Transformacje w przestrzeni trjwymiarowej ............................................................... 102
Macierze w Java Mobile 3D .................................................................................... 103
Zastosowanie macierzy w praktyce ......................................................................... 104
Orientacja trjktw ...................................................................................................... 105
Orientacja trjktw ................................................................................................ 105
Bufory wierzchokw .................................................................................................... 106
Bufory indeksw ............................................................................................................ 107
Pierwszy przykad w trybie immediate ......................................................................... 108
Inicjalizacja ............................................................................................................. 110
Rendering ................................................................................................................ 112
Animacja kamery .................................................................................................... 114
Dodajemy owietlenie ................................................................................................... 115
Model Phonga ......................................................................................................... 115
Model owietlenia w Java Mobile 3D ..................................................................... 115
Dodajemy rda wiata do sceny .......................................................................... 116
Materiay ................................................................................................................. 116
Dodajemy wektory normalne do bufora wierzchokw .......................................... 117
Kod przykadu z dodanymi rdami wiata .......................................................... 118
Teksturujemy walec ....................................................................................................... 120
Teksturowanie w Java Mobile 3D ........................................................................... 121
Zaawansowany przykad grafiki w trybie immediate ................................................ 125
Metoda map wysokoci ....................................................................................... 126
Klasa Terrain ....................................................................................................... 127
Tworzenie bufora wierzchokw ............................................................................. 132
Generujemy wsprzdne mapowania tekstur ......................................................... 133
Tworzymy bufor indeksw Triangle Strip ......................................................... 133
Efekt mgy ............................................................................................................... 136
Podsumowanie ............................................................................................................... 137
Pytania kontrolne ........................................................................................................... 137
Zadania .......................................................................................................................... 138

Spis treci

Rozdzia 5. Tryb Retained Java Mobile 3D ....................................................... 139


Graf sceny ...................................................................................................................... 140
Hierarchia klas grafu sceny ..................................................................................... 142
Animacja ........................................................................................................................ 146
Klatki kluczowe ....................................................................................................... 146
Wiemy animacj z waciwociami obiektu ........................................................ 147
Czas i kontrola animacji .......................................................................................... 148
Wywietlanie plikw M3G ............................................................................................ 151
Przygotowanie sceny ............................................................................................... 151
Eksport sceny do formatu M3G .............................................................................. 157
Wywietlanie sceny na urzdzeniu mobilnym ........................................................ 159
Wywietlanie animowanej sceny ............................................................................ 160
Efekty specjalne ............................................................................................................. 162
Billboarding rysujemy drzewa ........................................................................... 162
Animacja tworzymy efekt eksplozji ................................................................... 165
Kolizje strzelamy do celu ................................................................................... 170
Podsumowanie ............................................................................................................... 173
Pytania kontrolne ........................................................................................................... 173
Zadania .......................................................................................................................... 174

Rozdzia 6. Gry sieciowe poprzez cza Bluetooth ............................................ 175


Charakterystyka sieci w technologii Bluetooth ............................................................. 176
Aplikacje klient-serwer w technologii Bluetooth .......................................................... 177
Rola serwera w grze sieciowej ................................................................................ 177
Rola klienta w grze sieciowej .................................................................................. 178
Typowy scenariusz gry sieciowej .................................................................................. 178
Najwaniejsze pojcia Java Bluetooth .......................................................................... 181
Identyfikator usugi ................................................................................................. 181
Kod klasy urzdzenia .............................................................................................. 181
Dostpno (wykrywalno) urzdzenia Bluetooth ................................................ 182
GCF Generic Connection Framework ................................................................ 182
Rejestracja usugi .................................................................................................... 183
Implementacja ............................................................................................................... 184
Ekran wyboru roli aplikacji ..................................................................................... 185
Ekran wyszukiwania potencjalnych graczy ............................................................ 185
Ekran wyboru uczestnikw gry ............................................................................... 189
Ekran klienta oczekujcego na start gry .................................................................. 192
Klasa BluetoothConnection ..................................................................................... 195
Logika gry ............................................................................................................... 197
Podsumowanie ............................................................................................................... 201
Pytania kontrolne ........................................................................................................... 202
Zadania .......................................................................................................................... 202

Rozdzia 7. Gra 3D Multiplayer ....................................................................... 203


Scenariusz gry Cosmic Speedway ............................................................................. 203
Sztuczna inteligencja przeciwnikw ............................................................................. 204
Wycigi i gracze komputerowi ................................................................................ 204
Tor i reprezentacja trasy .......................................................................................... 207
Sterowanie i logika gracza ............................................................................................. 212
Klasa gwna gry Game ........................................................................................... 216
Inicjalizacja ............................................................................................................. 216
Krokowanie logiki gry ............................................................................................ 216
Maszyna stanw ...................................................................................................... 217

J2ME. Tworzenie gier


Klasa MyCanvas ............................................................................................................ 223
Klasa Player ................................................................................................................... 224
Dodajemy opcj Multiplayer ..................................................................................... 225
Okno wyboru trybu gry ........................................................................................... 226
Inicjalizacja ............................................................................................................. 227
Gracz sieciowy ........................................................................................................ 229
Modyfikacja klasy MyCanvas ................................................................................. 230
Podsumowanie ............................................................................................................... 233
Pytania kontrolne ........................................................................................................... 233
Zadania .......................................................................................................................... 234

Dodatek A Odpowiedzi do pyta kontrolnych .................................................. 235


Dodatek B Odpowiedzi i wskazwki do zada ................................................. 243
Skorowidz .................................................................................... 259

Rozdzia 3.

Gry 3D w 2D
Wolfenstein
Jeszcze kilka lat temu, grajc na swojej Nokii 3310 w kultowego ju wa, za fantazj
uznabym, gdyby kto powiedzia mi wtedy, e za kilka lat na telefonach komrkowych
krlowa bd gry 3D. A jednak! Najnowsze telefony komrkowe maj ju tak due
moce obliczeniowe, e wiat gier 3D stan przed nimi otworem. Co wicej, niektre
urzdzenia mobilne maj ju wbudowane sprztowe akceleratory grafiki 3D. Najnowsze telefony komrkowe udostpniaj programistom interfejs Java Mobile 3D, uatwiajcy w zasadniczym stopniu proces tworzenia aplikacji korzystajcych z grafiki trjwymiarowej.
Czy mona jednak stworzy gr 3D na popularnych (czytaj: taszych) modelach telefonw? Okazuje si, e przy zastosowaniu pewnych trikw mona osign efekt trjwymiarowoci na telefonach o niskich mocach obliczeniowych nieposiadajcych dedykowanych ku temu API czy te sprztowej akceleracji. Z pomoc przychodzi nam metoda
raycastingu, znana z takich gier jak m.in. Wolfenstein3D, Doom i wiele innych tytuw
z pocztku lat 90.
W rozdziale tym:
dowiemy si, czym jest metoda raycastingu,
poznamy zasady dziaania algorytmu DDA rzucania promieni,
stworzymy symulacj spaceru po trjwymiarowym labiryncie, takim jak

znany z gier Wolfenstein czy Doom.

Raycasting
wiat gry w metodzie raycastingu reprezentowany jest przez dwuwymiarow siatk, tak
jak ta pokazana na rysunku 3.1. Siatka ta przedstawia rzut z gry labiryntu, po ktrym
poruszaj si bohaterowie gry. W pamici komputera siatka ta moe by reprezentowana

78

J2ME. Tworzenie gier

Rysunek 3.1.
Reprezentacja
wiata gry w metodzie
raycastingu

przez dwuwymiarow tablic bajtw. Kade oczko siatki (element tablicy) okrela, czy
dany sektor (np. o rozmiarze 11 metr) jest pusty, czy stanowi cian labiryntu (a waciwie cztery ciany, gdy sektor ten przylega ciankami do czterech ssiednich
sektorw).
A oto przykad reprezentacji takiego wiata w pamici komputera:
int worldMap[][] = new int[][] {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1},
{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1},
{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1},
{1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1},
{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};

Rozdzia 3. Gry 3D w 2D Wolfenstein

79

Dziki sprytnemu trikowi moemy na paszczynie ekranu wygenerowa trjwymiarowy obraz tego, co widzi gracz umieszczony wewntrz labiryntu.
Dla uproszczenia przyjmijmy, e kt rozwarcia stoka kamery, przez ktr patrzymy,
jest rwny 90 stopni. Z punktu, w ktrym stoimy, prowadzimy 90 promieni (co 1 stopie), tak jak to jest pokazane na rysunku 3.2. (Dla czytelnoci na rysunku pokazano
tylko kilka takich promieni).
Rysunek 3.2.
Promienie rzucane
z punktu, w ktrym
znajduje si
obserwator

Dla kadego z tych promieni szukamy punktu, w ktrym promie po raz pierwszy
uderzy w cian labiryntu. Po znalezieniu kadego takiego punktu obliczamy jego odlego od punktu, w ktrym znajduje si obserwator. Odlego ta okrela, jak wysoko
na ekranie monitora bdzie mie fragment cianki, w ktr uderzy dany promie. Im
dalej nastpia kolizja ze ciank labiryntu, tym mniejszy powinien by pionowy pasek
przedstawiajcy ten fragment cianki na wywietlaczu telefonu. Wygenerowany na ekranie obraz bdzie mia szeroko 90 pikseli (kada kolumna odpowiada jednemu z dziewidziesiciu promieni) i wysoko zalen od przyjtego przez nas wspczynnika
proporcjonalnoci pomidzy wysokoci cianki a odlegoci od punktu kolizji z promieniem. Rysunek 3.3 przedstawia opisany sposb generacji obrazu na przykadzie kilku
promieni z rysunku 3.2.
Rysunek 3.3.

a)

b)

Na rysunku widzimy 4 przykadowe promienie. Pierwszy z nich biegnie pod ktem -45
stopni wzgldem kierunku, w ktrym patrzy gracz. Kolejne trzy promienie puszczane s
pod ktami odpowiednio: -45, -15, 15 i 45 stopni wzgldem obserwatora. Promienie
te uderzaj w ciany labiryntu w czterech rnych punktach. Odlegoci, w jakich uderzyy one w ciany labiryntu, pokazane s na rysunku 3.3a w postaci wykresu supkowego.

80

J2ME. Tworzenie gier

Im dalej nastpio uderzenie, tym wyszy bdzie supek odpowiadajcy promieniowi


wypuszczonemu pod okrelonym ktem. Widzimy, e najwyszy jest supek odpowiadajcy promieniowi wypuszczonemu pod ktem -15 stopni. Pokrywa si to z rzeczywistoci (popatrzmy na rysunek 3.3a); promie wypuszczony pod ktem -15 stopni dotar
do najodleglejszego zauka labiryntu. Supki dla ktw 15 i 45 stopni s najnisze, gdy,
jak widzimy na rysunku 3.3a, promienie te natrafiy na przeszkod najszybciej.
Teoria perspektywy mwi, e obiekty pooone dalej s widziane jako mniejsze ni te,
ktre znajduj si tu przy obserwatorze. Musimy wic odpowiednio przeskalowa nasz
wykres supkowy, a ponadto wyrodkowa paski wzgldem linii horyzontu. Przedstawia
to rysunek 3.3b. Paski najdusze staj si najkrtsze i podobnie najkrtsze s odpowiednio dusze.
Przy odrobinie wyobrani mona dostrzec, e rysunek 3.3b stanowi fragment obrazu,
ktry widzi gracz z rysunku 3.2. Wygenerowalimy dla przykadu tylko 4 promienie.
Popatrzmy, co bdzie si dziao, gdy uyjemy 8, 16, 32, 64, 128 i wszystkich promieni.
Dla uatwienia percepcji uyjemy rnych kolorw dla cianek labiryntu wzdu osi
X i osi Y (rysunek 3.4).

Rysunek 3.4. Widok labiryntu przy 8, 16, 32, 64 i 128 promieniach rzuconych z punktu obserwacji

Rozdzia 3. Gry 3D w 2D Wolfenstein

81

Wszystkie obliczenia odbywaj si w przestrzeni 2D i polegaj gwnie na znalezieniu


punktu przecicia si prostej z pierwsz napotkan ciank labiryntu. Poniewa obliczenia
takie musimy przeprowadzi tylko raz dla kadej kolumny ekranu, to przy ekranie
o szerokoci 90 pikseli musimy obliczenia wykona jedynie 90 razy na klatk animacji sceny.

Algorytm DDA ledzenia promienia


Na podstawie oglnego opisu raycastingu widzimy, e najwaniejszym elementem
metody jest algorytm znajdujcy te sektory mapy, przez ktre przebiegnie promie.
Algorytm, ktry zastosowalimy w naszym przykadzie, rozwizuje problem w sposb
iteracyjny. W kadym kroku iteracji analizowany jest jeden sektor mapy. Obliczenia
rozpoczynaj si w sektorze, w ktrym znajduje si obserwator patrz rysunek 3.5.
Rysunek 3.5.
Szukanie
drugiego sektora,
ktry odwiedzi
rzucany promie

Danymi wejciowymi do oblicze s:


Pozycja obserwatora wzgldem lewego dolnego rogu sektora
Kierunek, w ktrym spoglda obserwator
Kierunek (kt ), pod jakim wyrusza promie z punktu obserwacji

Zadaniem algorytmu jest znalezienie nastpnego w kolei sektora, znajdujcego si na


drodze promienia. Aby to stwierdzi, algorytm bada, przez ktr ciank promie opuszcza biecy sektor.
Rysunek 3.5 pokazuje, w jaki sposb moemy obliczy dwie wielkoci:

82

J2ME. Tworzenie gier


Odlego k punktu, w ktrym promie przetnie pierwszy raz pionow lini

wirtualnej siatki oddzielajcej sektory


Odlego l od punktu, w ktrym promie przetnie po raz pierwszy poziom

lini wspomnianej siatki


Te dwie wartoci pozwalaj nam stwierdzi, czy promie przebije cianki w kierunkach
poziomych (W lub E) czy pionowych (cianki N lub S). Jeli warto k jest mniejsza
od l, wnioskujemy, e promie opuszcza sektor przechodzc przez ciank W lub E.
W przeciwnym razie oznacza to, e nastpnym sektorem odwiedzonym przez promie
bdzie ssiad cianki N lub S.
Aby ucili obliczenia, badana jest jeszcze warto kta , pod ktrym biegnie promie.
Ponisza tabelka przedstawia reguy wnioskowania algorytmu na podstawie wartoci
k, l oraz wartoci kta .
Kierunek cianki, przez ktr promie opuszcza sektor

Regua wnioskowania

K<=l oraz >90 i <270

K<=l oraz <90 i >-90

k>l oraz >0 i <180

k>l oraz >180

Teraz czas na odrobin matematyki. Wartoci k i l wyraaj si wzorami:


k = a/cos()
l = b/sin()

Wartoci a oraz b moemy obliczy z zalenoci:


a = 1Xl
b = 1Yl

Gdzie (xl, yl) to wsprzdne obserwatora w lokalnym ukadzie wsprzdnych sektora


jak znale te wsprzdne, pokaemy w dalszej czci rozdziau.

Kolejne iteracje
Wiemy ju, jak wyznaczy drugi z kolei sektor, ktry przetnie rzucany promie. A jak
znale kolejne sektory, a do momentu, gdy promie natrafi na cian? Spjrzmy na
rysunek 3.6.
Znajc kt, pod jakim wypuszczony zosta promie, moemy obliczy odlegoci od
kolejnych przeci poziomych i pionowych linii wirtualnej siatki:
dk = 1/cos()
dl = 1/sin()

Informacje te wykorzystamy do znalezienia kolejnych sektorw na drodze promienia.

Rozdzia 3. Gry 3D w 2D Wolfenstein

83

Rysunek 3.6.
Szukanie
kolejnych sektorw
odwiedzanych przez
rzucany promie

Na tym etapie znajdujemy si w drugim z kolei sektorze na trasie promienia. Zastanwmy si, jakie informacje posiadamy zaraz po wejciu do tego sektora. Po pierwsze,
wiemy, przez ktr ciank promie do niego wkracza. Po drugie, wiemy, jak drog
przeby promie do momentu przecicia tej cianki.
Gdybymy teraz znali odlego do kolejnego przecicia si promienia z lini pionow
i poziom wirtualnej siatki, moglibymy wyznaczy kolejny sektor na drodze promienia. Skorzystamy tutaj z wyprowadzonych wczeniej wzorw (dk oraz dl). Mamy do
rozwaenia dwa przypadki:
Jeli do sektora promie wbieg przecinajc ciank poziom, to odlego od przecicia cianki pionowej znamy, gdy wyliczylimy j dla poprzedniego sektora. Odlego od nastpnego przecicia z ciank poziom obliczymy, dodajc warto dl do
odlegoci, w jakiej nastpio poprzednie przecicie cianki poziomej. Zmienne decyzyjne l oraz k przyjm nastpujce wartoci:
k=k
l = l+dl

Jeli do sektora promie wbieg przecinajc ciank pionow, to odlego od przecicia cianki poziomej rwnie znamy, gdy wyliczylimy j dla poprzedniego sektora. Odlego od nastpnego przecicia z ciank pionow obliczymy, dodajc warto
dl do odlegoci, w jakiej nastpio poprzednie przecicie cianki pionowej.
k = k+dk
l=l

Dalej postpujemy podobnie jak w przypadku sektora startowego:


na podstawie dwch odlegoci oraz kta wybieramy nastpny sektor na drodze

promienia;
gdy znamy ju kolejny sektor, sprawdzamy, czy jest on pusty. Jeli tak, wwczas

przechodzimy do kolejnej iteracji. W przeciwnym razie rysujemy lini na ekranie,


gdy natrafilimy na przeszkod.

Wsprzdne pooenia obserwatora wzgldem sektora


Kady sektor jest kwadratem o dugoci boku rwnym 1. Znajc wsprzdne (Xg, Yg)
pooenia obserwatora w ukadzie globalnym, moemy obliczy:

84

J2ME. Tworzenie gier


wsprzdne sektora na wirtualnej siatce poprzez odcicie czci uamkowej

wsprzdnych globalnych,
wsprzdne lokalne (Xl, Yl) wzgldem tego sektora poprzez odcicie czci

cakowitej wsprzdnych globalnych.

Rozwamy na przykad wsprzdne globalne obserwatora o wartoci (3.7, 9.55)


rysunek 3.7. Na ich podstawie obliczamy:
wsprzdne sektora na mapie (3, 9)
wsprzdne lokalne (0.7, 0.55)
Rysunek 3.7.
Obliczanie
wsprzdnych
pooenia wzgldem
sektora

Implementacja wersja uproszczona


W podrozdziale tym przytoczona jest uproszczona implementacja metody rzucania
promieni. Sposb generowania obrazu przez metod Render() klasy Raycaster (opisany w poprzednich akapitach) jest stosunkowo atwy do zrozumienia, lecz zawiera
pewne uproszczenia wprowadzone na potrzeby dydaktyczne. Na tym etapie najwaniejsze
jest zrozumienie samej idei raycastingu na szczegy przyjdzie pora pniej.

Klasa Raycaster
Klasa Raycaster zawiera gwn cz naszej aplikacji zajmujcej si rysowaniem labiryntu. Oto jej kod:
package mypackage;
import javax.microedition.lcdui.*;
import java.util.*;
import java.lang.Math.*;
public class Raycaster extends Canvas {

Rozdzia 3. Gry 3D w 2D Wolfenstein


public static final int screenHeight = 200;
public static final int screenWidth = 90;
public static final int screenHalfHeight = 50;
public static final int maxDistance = 40;
private static final int halfViewAngle = 45;
private Player player;
private int worldMap[][] = new int[][] {
{4,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{4,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
{4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2}};
private int arrX[] = new int[] { 1,-1,-1, 1 };
private int arrY[] = new int[] { 1, 1,-1,-1 };
public Raycaster() {
initialize();
}
private void initialize() {
player = new Player(this);
player.setPos(12.0f,12.0f);
}
public void paint(Graphics g)
{
int playerDirection = player.getAngle()%360;
if(playerDirection<0)
playerDirection+=360;
g.fillRect(0,0,screenWidth,screenHeight);
}

Render(g,playerDirection, player.getPosX(), player.getPosY());

private double Cos(double angle) {

85

86

J2ME. Tworzenie gier


return Math.cos(Math.toRadians(angle));
}
private double Sin(double angle) {
return Math.sin(Math.toRadians(angle));
}
public void Render(Graphics g, int playerDirection,
double playerX, double playerY)
{
int x=0;
for(int rayAngle = playerDirection - halfViewAngle ;
rayAngle < playerDirection + halfViewAngle ;
rayAngle++)
{
int ceilPosX = (int)playerX;
int ceilPosY = (int)playerY;
double a = 1.0 - (playerX - ceilPosX);
double b = 1.0 - (playerY - ceilPosY);
double dk = Math.abs(1.0 / Cos(rayAngle));
double dl = Math.abs(1.0 / Sin(rayAngle));
double k = a * dk;
double l = b * dl;
int index = (rayAngle % 360) / 90;
int stepX = arrX[index];
int stepY = arrY[index];
double distance = 0.f;
boolean hit = false;
int leftHit = 1;
while(false == hit) {
if(k>l) {
ceilPosY += stepY;
if(0 != worldMap[ceilPosX][ceilPosY]) {
hit = true;
distance = l;
} else {
l += dl;
}
} else {
ceilPosX += stepX;
if(0 != worldMap[ceilPosX][ceilPosY]) {
hit = true;
distance = k;
leftHit=2;
} else {
k += dk;
}
}
}
g.setColor(160/leftHit,160/leftHit,255/leftHit);

Rozdzia 3. Gry 3D w 2D Wolfenstein

87

distance = maxDistance-distance%maxDistance;

g.drawLine(x,screenHalfHeight - (int)(distance),
x,screenHalfHeight + (int)(distance));
x++;

public void keyPressed(int keyCode) {


int action = getGameAction(keyCode);
switch(action) {
case Canvas.LEFT:
player.RotateLeft();
break;
case Canvas.RIGHT:
player.RotateRight();
break;
case Canvas.UP:
player.MoveForward();
break;
case Canvas.DOWN:
player.MoveBackward();
break;
}
repaint();
serviceRepaints();
}

W klasie Raycaster na samym pocztku definiujemy kilka poytecznych staych wykorzystywanych w algorytmie rzucania promieni:
screenHeight wysoko ekranu wyraona w pikselach,
screenWidth szeroko ekranu wyraona w pikselach,
maxDistance maksymalna odlego, na jak widzi obserwator,
halfViewAngle poowa kta rozwarcia stoka kamer.

W dwuwymiarowej tablicy worldMap definiujemy wygld naszego labiryntu. Wartoci


rne od zera oznaczaj sektory stanowice ciany labiryntu. Zera oznaczaj przestrzenie
otwarte labiryntu.
Tablice arrX i arrY su do celw optymalizacyjnych procedury rozstrzygajcej o tym,
ktr ciank promie opuszcza biecy sektor.

Metoda Render()
Omwiony wczeniej algorytm DDA realizowany jest w metodzie Render(). Parametrami wejciowymi do metody s:
wektor kierunku, w ktrym spoglda gracz (0 360 stopni),
wsprzdne pooenia gracza (wsprzdne globalne),
kontekst graficzny.

88

J2ME. Tworzenie gier

Ptla for obejmujca cay kod wewntrz metody render() zapewnia, e wszystkie obliczenia powtarzane s dla kadego paska ekranu z osobna. W ten sposb realizowane
jest rzucanie promienia dla kadego kta z zakresu stoka widzenia kamery.
W pierwszym kroku znajdujemy wsprzdne sektora, w ktrym znajduje si gracz.
Przypomnijmy, e kady sektor to kwadrat o dugoci boku rwnym 1 metr. Poprzez
rzutowanie wsprzdnych globalnych pooenia gracza do wartoci typu int pozbywamy si ich czci uamkowej. Wartoci te (s to szukane wsprzdne sektora) zapamitujemy w zmiennych ceilPosX oraz ceilPosY.
Nastpnie obliczamy wartoci nastpujcych wspczynnikw: a, b, dk, dl, k, l. Ich znaczenie oraz sposb obliczenia ju omwilimy. Aby obliczy wspczynnik a, od jedynki
odejmujemy warto wsprzdnej lokalnej gracza w sektorze (wzdu osi x ukadu
wsprzdnych patrz rysunek 3.7). Podobnie postpujemy obliczajc wspczynnik b.
Zestaw tych szeciu wspczynnikw posuy dalej do obliczania odlegoci od kolejnych punktw przecicia si promienia z poziomymi i pionowymi liniami wirtualnej siatki
wyznaczajcej sektory.
W zalenoci od wartoci kta, pod jakim biegnie rzucany promie, inicjalizowane s
dwie zmienne decyzyjne:
stepX przyjmuje warto dodatni (promie biegnie w praw stron), dla wartoci

kta z zakresu od -90 do 90 stopni. Dla pozostaych ktw zmienna przyjmuje


warto ujemn promie biegnie w lew stron,
stepY przyjmuje warto dodatni (promie biegnie w gr) dla wartoci kta

z zakresu od 0 do 180 stopni. Dla pozostaych ktw zmienna przyjmuje warto


ujemn promie biegnie w d.
Najwaniejsza cz algorytmu DDA zawarta jest w ptli while. Oto pseudokod ptli while:
Dopki(nie nastpia kolizja ze ciank labiryntu)
{
Jeli(odlego od przecicia z najblisz pionow granic kratki >
Odlegoci od przecicia z najblisz poziom granic kratki)
{
Analizuj kratk powyej lub poniej biecej
Jeli(nowa kratka jest ciana)
{
nastpia kolizja zapamitaj odlego
}
Ustal odlego od punktu kolizji z kolejn poziom granic kratek
}
w przeciwnym wypadku
{
Analizuj kratk po prawej lub lewej stronie biecej
Jeli(nowa kratka jest ciana)
{
nastpia kolizja zapamitaj odlego
}

Rozdzia 3. Gry 3D w 2D Wolfenstein

89

Ustal odlego od punktu kolizji z kolejn pionow granic kratek


}
}

Kod w ptli powtarzany jest a do momentu, gdy stwierdzona zostanie kolizja promienia
ze ciank labiryntu. Gdy stwierdzona zostanie kolizja, w zmiennej distance zapamitywana jest odlego od punktu kolizji. W zmiennej leftHit zapamitywana jest informacja pozwalajca zastosowa proste cieniowanie cianek labiryntu. cianki rwnolege do osi Y ukadu wsprzdnych bd janiejsze od tych rwnolegych do osi X.
Po wykryciu kolizji promienia ze ciank wykonanie ptli While jest przerywane. Nastpnie obliczana jest dugo pionowego paska na ekranie odpowiadajcego promieniowi i obliczonej odlegoci od punktu kolizji. Pasek ten ostatecznie jest rysowany na
ekranie przy uyciu metody drawLine.

Klasa Player
Obiekt tej klasy reprezentuje gracza poruszajcego si po labiryncie. W prawdziwej
grze klasa ta zawieraaby midzy innymi takie informacje, jak: ilo ywotw, zdobyte punkty, ilo energii i wiele innych zalenych od typu gry. W naszym przykadzie
gracz opisany jest najprostszymi parametrami. S to:
pozycja na mapie,
orientacja (kt obrotu),
parametry ruchu prdko poruszania i prdko rotacji.

Klasa Player udostpnia take metody suce do manipulacji tymi parametrami. Metody
moveForward oraz moveBackward pozwalaj porusza si odpowiednio do przodu i w ty.
Metody te wykrywaj te ewentualne przeszkody (takie jak ciany labiryntu), stojce
na drodze gracza, i odpowiednio modyfikuj wektor ruchu. Funkcje rotateRight oraz
rotateLeft pozwalaj graczowi obraca si wok wasnej osi pionowej.
package hello;
public class Player
{
private Raycaster r;
private float posX;
private float posY;
private int angle = 90;
/** Konstrukcja obiektu gracza */
public Player(Raycaster _r) {
r = _r;
}
private int getSpeed() {
return 1;
}

90

J2ME. Tworzenie gier


public void setPos(float x,float y) {
posX = x;
posY = y;
}
public float getPosX()
public float getPosY()

{ return posX; }
{ return posY; }

public int getAngle() { return angle; }


public void setAngle(int _angle) { angle = _angle; }
public void MoveForward()
{
float newPosX = posX + 1.0f *
(float)Math.cos(Math.toRadians((double)angle));
float newPosY = posY + 1.0f *
(float)Math.sin(Math.toRadians((double)angle));
if(r.getMapPoint( (int)newPosX,(int)posY) == 0)
posX = newPosX;
if(r.getMapPoint( (int)posX,(int)newPosY) == 0)
posY = newPosY;
}
public void MoveBackward()
{
float newPosX = posX - 1.0f *
(float)Math.cos(Math.toRadians((double)angle));
float newPosY = posY - 1.0f *
(float)Math.sin(Math.toRadians((double)angle));
if(r.getMapPoint( (int)newPosX,(int)posY) == 0)
posX = newPosX;
if(r.getMapPoint( (int)posX,(int)newPosY) == 0)
posY = newPosY;
}
public void RotateLeft() {
angle-=5;
}

public void RotateRight() {


angle+=5;
}

Klasa midletu
Poniewa nasz przykad nie uywa adnych (!) zasobw (grafik, dwiku itp.), kod klasy
midletu wyglda nastpujco:
package mypackage;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

Rozdzia 3. Gry 3D w 2D Wolfenstein

91

public class Welcome extends MIDlet {


public Welcome() {}
public void startApp() {
Display.getDisplay(this).setCurrent(new Raycaster());
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}

Efekt rybiego oka


Niestety, w naszym przykadzie napotykamy pewien problem. Do obliczenie wysokoci
paska na ekranie uywamy wprost odlegoci od punktu, w ktrym promie uderzy
w ciank. Wynikiem takiego postpowania jest efekt rybiego oka.
Wyobramy sobie sytuacj, jak przedstawia rysunek 3.8. Obserwator znajduje si
dokadnie na wprost dugiej ciany. Pomimo to obraz jest zdeformowany, co wida na
rysunku. Aby efekt ten zniwelowa, powinnimy zrzutowa wektor dugoci na wektor
kierunku, w ktrym patrzy obserwator. Dugo wynikowego wektora powinnimy
zastosowa w rysowaniu paska dla tego promienia.
Rysunek 3.8.
Efekt rybiego oka

Odlego t uzyskamy take, mnoc odlego euklidesow przez kosinus kta pomidzy promieniem a wektorem kierunku obserwatora.
Kta tego nie znamy, ale moemy go atwo obliczy. Na podstawie rysunku 3.9 widzimy, e odejmujc od kta kt , uzyskamy szukany kt pomidzy promieniem a kierunkiem, w ktrym patrzy gracz. Kt to kt pomidzy rzucanym promieniem a osi

92

J2ME. Tworzenie gier

Rysunek 3.9.
Rzutowanie wektora
odlegoci na kierunek
obserwacji

x ukadu wsprzdnych. Kt to kt pomidzy kierunkiem, w ktrym patrzy gracz,


a osi x ukadu. W ten sposb uzyskujemy nastpujcy wzr na odlego punktu kolizji
ze cian labiryntu od paszczyzny ekranu:

projDistance = cos( ) distance

Jeszcze jeden problem


Spjrzmy na rysunek 3.10. Widzimy na nim pk promieni wychodzcych z punktu P.
Na granicznych promieniach (o ktach -45 oraz 45 stopni wzgldem kierunku, w ktrym
patrzymy) rozpilimy paszczyzn ekranu. To na niej wygenerowany zostanie obraz
naszej sceny.

Rysunek 3.10. Bdny oraz poprawny podzia paszczyzny ekranu przez rzucane promienie

Z lekcji matematyki wiemy, e promienie dziel t prost na odcinki o rnej dugoci.


W efekcie obraz, ktry uzyskamy, moe by zdeformowany. Bdy bd widoczne gwnie przy duych zblieniach na krawdziach ekranu. Aby tego unikn, musimy promienie rzuca w taki sposb (pod takimi ktami), aby paszczyzn ekranu (prost na
rysunku) dzieliy na rwnej dugoci odcinki.

Rozdzia 3. Gry 3D w 2D Wolfenstein

93

Metoda dokadna
W dalszej czci tego rozdziau zajmiemy si rozwizaniem problemu prawidowego
podziau rzutni (ekranu) przez rzucane promienie.
W metodzie dokadnej obliczamy wsprzdne wektora kierunku promienia, ktry biegnie
przez okrelony pasek powierzchni ekranu. Zmiana ta pociga za sob modyfikacje oblicze pozostaych wielkoci uywanych przez algorytm uproszczony.

Obliczamy wsprzdne wektora promienia


Na kocu jednostkowego wektora kierunku obserwatora (rysunek 3.11) zaczepiamy dwa
wektory jednostkowe o przeciwnych znakach, prostopade do wektora kierunku. W ten
sposb tworzymy stoek kamery, przez ktr obserwowana bdzie scena.
Rysunek 3.11.
Tworzenie stoka
kamery na podstawie
wektora kierunku
obserwacji

Prost utworzon przez dwa wektory prostopade do kierunku, w ktrym zwrcony jest
gracz, dzielimy na N rwnych odcinkw. Warto N okrela poziom rozdzielczo
ekranu, a tym samym liczb promieni, ktre bdziemy ledzi.
Obliczamy wektor prostopady do wektora kierunku obserwacji. Jego wsprzdne
wyraone s wzorem:
Rysunek 3.12.
Podzia paszczyzny
ekranu oraz
znajdowanie wektora
kierunku rzucanego
promienia

Vperp = [Vy ,Vx ]


W powyszym wzorze Vx i Vy to wsprzdne wektora kierunku, w ktrym patrzy gracz.

94

J2ME. Tworzenie gier

Mnoc ten wektor przez odpowiedni wielko skalarn z zakresu [1,1] uzyskamy
wektor n, jak na powyszym rysunku. Wektor ten wyznacza punkt paszczyzny ekranu,
przez ktry przebiega bdzie rzucany promie. Wektor kierunku promienia obliczamy,
dodajc do siebie wektor n i prostopady do niego wektor kierunku obserwacji v:
r
r r
r (rx , ry ) = v + n

Algorytm DDA w metodzie dokadnych podziaw


Zmienne decyzyjne wyliczamy na podstawie znaku wsprzdnych rx i ry:
stepX przyjmuje warto dodatni (promie biegnie w praw stron), jeli

skadowa rx ma warto dodatni; w przeciwnym przypadku zmienna decyzyjna


stepX przyjmuje warto ujemn promie biegnie w lew stron;
stepY przyjmuje warto dodatni (promie biegnie w gr), jeli skadowa ry
ma warto dodatni; w przeciwnym przypadku zmienna decyzyjna stepY

przyjmuje warto ujemn promie biegnie w d.


Sposb obliczenia wartoci wspczynnikw k, l pokazany jest na rysunku 3.13.
Rysunek 3.13.
Obliczanie
wspczynnikw k,
l w metodzie
dokadnej

Wartoci tych wspczynnikw wyraone s wzorami:


r
r
rx
a
cos = r = K = a
r
K
rx
r
r
r
b
sin = ry = L = b
r
L
ry

Rozdzia 3. Gry 3D w 2D Wolfenstein

95

Modyfikacji ulega take sposb obliczenia rzutu odlegoci na wektor kierunku, w ktrym
spoglda gracz. Kosinus kta potrzebny do znalezienia rzutu moemy obliczy w dwojaki sposb:
Po pierwsze, wyraa si on ilorazem dwch wielkoci: moduu rzutu wektora

odlegoci na kierunek obserwacji oraz moduu wektora odlegoci euklidesowej,


Po drugie, jest on rwny ilorazowi dugoci wektora jednostkowego v i wektora

r wyznaczajcego promie.
Zalenoci te opisa moemy nastpujcym wzorem:
cos( ) =

v
dist
= r
dist
r

Znaczenie poszczeglnych skadowych wzoru pokazane s na rysunku 3.14.


Rysunek 3.14.
Obliczanie rzutu
odlegoci
euklidesowej
w metodzie dokadnej

Przeksztacajc ten wzr, otrzymujemy zaleno wartoci rzutu wektora odlegoci od


kierunku obserwacji:
v
dist
dist = r dist = r
r
r

Poprawiona implementacja metody Render


Ponisza implementacja odzwierciedla wspomniane wczeniej poprawki:
public void Render(Graphics g, int playerDirection,
double playerX, double playerY)
{
double playerDirX = Cos(playerDirection);
double playerDirY = Sin(playerDirection);
double playerPerpDirX = -playerDirY;
double playerPerpDirY = playerDirX;

96

J2ME. Tworzenie gier


double deltaOffset=2.0/screenWidth;
int x=0;
for(double offset
{
int ceilPosX =
int ceilPosY =
double a = 1.0
double b = 1.0

= -1 ; offset < 1 ; offset += deltaOffset)


(int)playerX;
(int)playerY;
- (playerX - ceilPosX);
- (playerY - ceilPosY);

double rx = playerDirX + playerPerpDirX * offset;


double ry = playerDirY + playerPerpDirY * offset;
double stepX,stepY;
stepX = stepY = -1;
if(rx>0) stepX = 1;
if(ry>0) stepY = 1;
double lengthR = Math.sqrt(rx*rx + ry*ry);
double dl = Math.abs(lengthR /ry);
double dk = Math.abs(lengthR /rx);
double k = a * dk;
double l = b * dl;
boolean hit = false;
int leftSideHit = 1;

// nastpia kolizja ze cian?


// czy to ciana pn. czy pd.?

double distance = 0.f;


while(false == hit) {
if(k>l) {
ceilPosY += stepY;
if(0 != worldMap[ceilPosX][ceilPosY]) {
hit = true;
distance = l;
leftSideHit = 1;
} else {
l += dl;
}
} else {
ceilPosX += stepX;
if(0 != worldMap[ceilPosX][ceilPosY]) {
hit = true;
distance = k;
leftSideHit = 2; //2 dodaje cieniowanie
} else {
k += dk;
}
}
}
g.setColor(160/ leftSideHit,160/ leftSideHit,255/ leftSideHit);
distance = distance / lengthR;

Rozdzia 3. Gry 3D w 2D Wolfenstein

97

distance = 30/distance;

g.drawLine(x,screenHalfHeight - (int)distance,
x,screenHalfHeight + (int)distance);
x++;

Najpierw na podstawie kta rotacji obliczamy jednostkowy wektor v orientacji gracza.


Nastpnie na jego podstawie obliczamy wsprzdne wektora prostopadego do wektora
kierunku. Wsprzdne tych wektorw reprezentowane s przez pary zmiennych (playerDirX, playerDirY) i (playerPerpDirX, playerPerpDirY).
Nastpnie obliczamy dugo wektora n, prostopadego do wektora kierunku i odmierzajcego na paszczynie kolejne punkty, przez ktre przechodzi powinny rzucane promienie. Poniewa paszczyzn ekranu rozpostarlimy na dwch jednostkowych wektorach,
dugo wektora n obliczamy, dzielc warto 2 przez szeroko (w pikselach) generowanego obrazu. Zmienna wektora n zapamitana zostaje w zmiennej deltaOffset.
Podobnie jak w pierwszym przykadzie gwna praca wykonywana jest w ptli for. Tutaj,
po obliczeniu wartoci wspczynnikw a oraz b, obliczamy wsprzdne wektora r wyznaczajcego rzucany aktualnie promie.
Wektor r jest wynikiem sumy dwch wektorw:
Wektora kierunku, w ktrym zwrcony jest gracz,
Prostopadego do niego wektora, o dugoci zalenej od piksela ekranu (linii),

dla ktrej jest on rzucany.


W kolejnym kroku znajdujemy warto zmiennych decyzyjnych stepX i stepY. Tym razem
obliczamy je na podstawie wartoci wsprzdnych wektora r.
Ostatnim krokiem przed rozpoczciem ledzenia promienia jest obliczenie wspczynnikw k, l, dk i dl. Sposb, w jaki jest to wykonywane, obrazuje rysunek 3.13.
Dalsza cz kodu (waciwe ledzenie promienia) jest prawie identyczna z t w poprzednim przykadzie i nie bdziemy jej opisywa tutaj ponownie. Jedyna rnica to sposb
obliczenia odlegoci od punktu kolizji. Korzystamy tutaj z rzutu odlegoci euklidesowej na wektor orientacji gracza. Sposb jego obliczenia ju omawialimy, ponadto
zobrazowany jest on take na rysunku 3.14.

Podsumowanie
Technika raycastingu, ktr poznalimy w tym rozdziale, okazaa si krokiem milowym w wiecie gier komputerowych. Jest potwierdzeniem znanej tezy, e geniusz tkwi
w prostocie. Wykorzystujc tak prost funkcjonalno jak rysowanie linii oraz proste
obliczenia na paszczynie, stworzylimy wraenie trjwymiarowoci wiata opisanego
przez dwuwymiarow tablic znakw.

98

J2ME. Tworzenie gier

Technika ta, po raz pierwszy zastosowana przez Johna Carmacka w grze Wolfenstein,
lega u podstaw takich gier jak Doom i przyczynia si do byskawicznego rozwoju
gier 3D. Bez raycastingu gry komputerowe nie byyby w miejscu, w ktrym znalazy
si obecnie. Kady programista gier komputerowych powinien wic zna t technik,
bo to znaczcy fragment historii gier komputerowych.
W rozdziale zaprezentowalimy jedynie podstawy techniki raycastingu. Zachcamy
Czytelnika do dalszego zgbiania tajnikw tej metody. Przez dodanie tekstur, podogi,
sufitu i przeciwnikw moemy tworzy przepikne gry 3D, ktre w dodatku nie bd
wymaga najnowszych technologicznie telefonw.

Pytania kontrolne
1. Czemu generowanie obrazu 3D metod raycastingu zawdzicza tak du

efektywno?
2. Opisz zasad dziaania algorytmu DDA.
3. Wyprowad wzr na odlegoci od pierwszego przecicia promienia

z pionow i poziom granic sektora.


4. Jak oblicza si wsprzdne gracza w sektorze na podstawie pooenia

globalnego?
5. Co to jest i dlaczego powstaje efekt rybiego oka w metodzie raycastingu?

Zadania
1. Zmodyfikuj przykad tak, aby ciany labiryntu mogy mie dowolny kolor.
2. Wprowad kolor podogi oraz dodaj niebo (to) nad labiryntem.
3. W rozdziale 5. omwiona zostaa metoda billboardingu wywietlania paskich

obrazw w trjwymiarowym wiecie. Zastanw si, w jaki sposb metodologia


ta mogaby by wykorzystana do reprezentacji animowanych postaci w wiecie
generowanym metod raycastingu.

You might also like