Tworzenie gry platformowej 3D w GM

Klikipedia - klikowa encyklopedia
Skocz do: nawigacji, wyszukiwarki
Autor.jpg
Autorem tego artykułu jest
Jaklub

Artykuł ten porusza kwestie tworzenia gier 3D na przykładzie gry platformowej.
Uwaga! Aby móc zrobić grę opisaną w artykule, musisz posiadać zarejestrowanego Game Makera 6.1

Przygotowanie

Najpierw trzeba dodać 3 sprity do naszej gry - pierwszy ma przedstawiać okrąg w rozmiarze 32x32 pikseli, drugi kwadrat w rozmiarze 128x128 pikseli, a trzeci - okrąg w rozmiarze 64x64. Origin spritów z kołami musi znajdować się w ich środku.

Jeśli już zrobiłeś powyższe sprity użytkowniku, pora zabrać się za dźwięki. Pierwszy ma być dźwiękiem skakania, najlepiej sympatycznym "boing". Drugi ma być odgłosem skończenia levelu, trzeci - zebrania monety, a czwarty - muzyczką.

Robimy backgroundy. Backgroundy w 3D obsługuje się zwykle jako tekstury. Tekstury muszą mieć rozmiary potęga 2 * potęga 2 (np. 64*64). Pierwsza tekstura ma być czerwonym kolorem, najlepiej gradientem. Druga musi być żółtym, trzecia ma przedstawiać... marmur (chyba). Jeśli nie masz skąd wziąć tej tekstury, zajrzyj do bibliotek GM-a. W katalogu z twoim GM-em znajdziesz folder Backgrounds. W nim jest plik gray2, który należy wziąć do naszej gry, ale potem powiększyć tą teksturę z rozmiaru 100*100 na 128*128 pikseli. Czwarta tekstura ma być niebem, a piąta zielonym gradientem.

Obiekty

Kończymy z teksturami, a zaczynamy z najtrudniejszym: obiektami. Robimy więc pierwszy obiekt i nazywamy go kamera. W evencie Room Start musi znajdować się skrypt:

d3d_start(); 
sound_loop(muzyczka); 

d3d_start to komenda startująca 3D, a sound_loop to znany wam skrypt do odtwarzania dźwięków i zapętlania ich. W miejscu muzyczka powinna znajdować się nazwa dźwięku z muzyczką w waszej grze.

W evencie Room End:

d3d_end(); 

Doskonale wiesz, że to skrypt skończenia 3D.

W evencie draw - skrypt:

d3d_set_projection(bohater.x,bohater.y+256,bohater.z+256,bohater.x,bohater.y,bohater.z,0,0,1) 

Powyżej jest skrypt ustalenia pozycji kamery.

W evencie draw - jeszcze jeden skrypt:

ttt=background_get_texture(niebo) 
draw_set_color(c_white) 
d3d_draw_ellipsoid(-640,-640,-640,room_width+640,room_height+640,800,ttt,11,11,24) 

Tu jest skrypt rysowania nieba.

Robimy nowy obiekt: ziemia. Nadajemy mu sprite kwadratu.

W evencie draw - skrypt:

ttt=background_get_texture(marmur) 
draw_set_color(c_white) 
d3d_draw_block(x,y,z-10,x+sprite_width,y+sprite_height,z,ttt,1,1) 

Tak, to skrypt rysowania marmurowego klocka.

Tworzymy kolejny obiekt: bohater. Dajemy mu sprite koła w rozmiarze 32*32. W evencie create - skrypt:

Kod: 
z=0 
zspeed=0 

(zspeed to szybkość spadania, a z chyba już nie trzeba tłumaczyć?)

W evencie step - skrypt:

zspeed+=1 
if zspeed>12 then zspeed=12 
z-=zspeed 
if z<-128 then room_restart() 

Pierwsze trzy linijki obsługują grawitację, ostatnia śmierć w przepaści.

W evencie collision with ziemia - skrypt:

if zother.z-6 
{ 
z=other.z 
zspeed=0 
if keyboard_check(vk_space) 
{ 
sound_play(sound0) 
z+=12 
zspeed=-12 
} 
} 
if zother.z-13 
{ 
x=xprevious 
y=yprevious 
} 
if zother.z-26 
{ 
z+=3 
zspeed=3 
} 

Kolizja z ziemią + skok.

W evencie keyboard right - skrypt:

direction-=10 

W evencie keyboard left - skrypt:

direction+=10 

Obydwa skrypty to obracanie się bohatera.

W evencie keyboard up - skrypt:

speed=4 

Bohater może iść do przodu.

W evencie keyboard down - skrypt:

speed=-2 

Bohater może iść do tyłu.

W eventach keyrelease up i keyrelease down - ten sam skrypt:

speed=0 

Czyli zatrzymanie się po puszczeniu strzałki w górę albo w dół.

Event draw - skrypt:

ttt=background_get_texture(herotekstura) 
draw_set_color(c_white) 
d3d_transform_set_identity() 
d3d_transform_add_rotation_z(direction) 
d3d_transform_add_rotation_y(zspeed) 
d3d_transform_add_translation(x,y,z) 
d3d_draw_block(-16,-8,0,16,8,8,ttt,1,1) 
d3d_transform_set_identity() 

Tu się ukazuje prawdziwe oblicze bohatera... jest klockiem. Tu trzeba było użyć skryptów transformacji. Aby działały poprawnie trzeba było ustawić origin sprita z kołem w jego środku.

Tworzymy nowy obiekt i nazywamy go moneta. Dajemy mu sprite koła w rozmiarze 32*32. W evencie step piszemy skrypt:

direction+=5 

Dzięki temu skryptowi, moneta będzie ciągle zmieniać variable direction.

Event draw - skrypt:

ttt=background_get_texture(kasa) 
draw_set_color(c_white) 
d3d_transform_set_identity() 
d3d_transform_add_rotation_z(direction) 
d3d_transform_add_translation(x,y,z) 
d3d_draw_ellipsoid(-8,-2,0,8,2,16,ttt,1,1,24) 
d3d_transform_set_identity() 

Rysujemy dzięki temu skryptowi złotą, ciągle się obracającą monetę.

Event collision with bohater - skrypt:

if other.zz-16 
{ 
sound_play(zebranie) 
score+=10 
instance_destroy() 
} 

Czyli monetę można zebrać.

Robimy ostatni już obiekt - koniec. Dajemy mu sprite koła w rozmiarze 64*64.

Skrypt draw:

ttt=background_get_texture(roomend) 
draw_set_color(c_white) 
d3d_draw_ellipsoid(x-32,y-32,z,x+32,y+32,z+64,ttt,1,1,24) 

Czyli rysowanie dużej kuli.

Skrypt collision with bohater:

if other.zz-32 
{ 
sound_play(sound1) 
sleep(1000) 
game_end() 
} 

Czyli koniec levelu.

Zakończenie

Uff. Robimy room. Jako pierwszy musimy wstawić objekt kamera. Potem można designować room. Aby zmienić wysokość ziemi, końca levelu i monety, klikamy na niego prawym klawiszem myszy trzymając control i wybieramy Creation Code. Tam wpisujemy skrypt: z=wymyśl sobie wysokość

W Game Options trzeba kliknąć zakładkę Errors i zaznaczyć opcję "Treat uninitialized variables as 0".

informacje na temat funkcji, użytych w artykule: d3d_start(), sound_loop(), d3d_end(), d3d_set_projection, draw_set_color(), d3d_draw_ellipsoid(), d3d_draw_block(), room_restart(), keyboard_check(), sound_play(), d3d_transform_set_identity(), d3d_transform_add_rotation_z(), d3d_transform_add_rotation_y(), d3d_transform_add_translation(), background_get_texture(), instance_destroy(), sound_play(), sleep(), game_end()