Pravidla Ucet
Nepřihlášen

Článek

Menu

First Person Shooter - 3. část
Napsal: Satik64
Přidáno: 25.07. 2010

Další pokračování seriálu o tvorbě FPS pomocí GM3D (z tutoriálu Marka Overmarse). Tentokrát přidáme naší hře střelbu a nepřátele.

Střelba

V dnešním díle do přidáme do naší hry střelbu. Nejdřív vytvoříme jako terč barely, potom příšery.

Přidání barelů

K sestřelení nějakých barelů budeme potřeboval obrázek barelu. Ve skutečnosti potřebujeme dva, jeden, kdy barel ještě stojí, a jeden, když exploduje. Pro tento účel si půjčíme nějaké obrázky z Doomu. Můžete je najít na . Tady jsou oba animované sprity. Také potřebujeme 2 sprity pro znázornění v roomu. K získání správné animace je důležité, aby sprit měl stejný počet podobrázků jako skutečná animace. Vytvoříme objekt barelu a objekt explodujícího barelu. Oběma dáme parent základní zdi, takže přes ně nepůjde chodit. Objekty barelu umístíme na náhodných místech v roomu. Protože má jen dva podobrázky, nastavíme proměnnou image_speed na 0.1 v Create eventu pro pomalejší animaci. V eventu draw vykreslíme správný podobrázek na plochu zdi, jak bylo ukázáno výš. Když je barel zničen (takže v eventu Destroy) vytvoříme objekt explodujícího barelu na stejném místě. Pro tento objekt znovu nastavíme pomalejší rychlost animace. Protože barel nevybouchne okamžitě, nastavíme alarm, takže zvuk exploze se přehraje až po krátké chvilce. Vykreslíme ho stejně jako minule, ale použijeme jeden trik. Pomalu snižíme hodnotu průhlednosti, takže exploze postupně zprůhlední. V Draw eventu přidáme pro toto následující řádek:  
draw_set_alpha(1-0.05*image_index);
 

Nakonec přidáme do eventu Animation End zničení explodujícího barelu.

 

Můžete si jednoduše přidat další extra věci, jako je zranění hráče v blízkosti explodujícího barelu, ale to do tohoto jednoduchého příkladu hry nezahrneme.

 

Zbraň

Pro zbraň opět použijeme animovaný sprite. Tento sprit bude mít obrázky pro pevnou zbraň (podobrázek 0), pro střelbu a nabíjení. Normálně budeme vykreslovat pouze podobrázek 0 (takže nastavíme image_speed na 0), ale při výstřelu musíme nechat přehrát celou animaci. Budeme chtít zbraň vložit na obrazovku hry. K dosažení této nové věci je potřebné:

1) Musíme se ujistit že že objekt zbraně se vykresluje naposled. To zařídíme přiřazením objektu zbraně hloubkou (depth) -100.

2) Nebudeme už používat perspektivní projekci, ale změníme ji na normální orthografickou projekci.

3) A nakonec musíme dočasně vypnout odstranění skrytého povrchu.

 
Kod pro event Draw pro objekt zbraně bude vypadat takto:
{
d3d_set_projection_ortho(0,0,640,480,0);
d3d_set_hidden(false);
draw_sprite_ext(sprite_shotgun,-1,0,224,2,2,0,c_white,1);
d3d_set_hidden(true);
}
 

Všimněte si, že jsme zvětšili měřítko spritu na 2 v obou směrech. Jinak by byl příliš malý. V dalším stepu Draw eventu objektu postavy nastavíme zpět perspektivní projekci, nepotřebujeme ji proto nastavovat tady.

 

Střílení

Máme teď barel ke střelení a zbraň, ale stále jsme nepřidali střílecí mechanismus. Protože je to brokovnice, střely budou velmi rychlé. Takže není vhodné vytvářet objekt střely. Místo toho, když hráč stiskne <space> klávesu, musíme určit objekt který trefil, a pokud je to barel, exploduje.

 

Ze všeho nejdřív zavedeme proměnnou can_shoot v objektu zbraně, která bude určovat kdy hráč může vystřelit střelu. Nastavíme ji na true v Create eventu objektu zbraně. Když hráč stiskne klávesu <space>, ověříme ji. Pokud hráč může střílet nastavíme ji na false, a spustíme animaci zbraně změněním image_index a image_speed na 0. Ve výsledku hráč nemůže střílet neustále.

K určení, co střela trefila, budeme postupovat následovně. Vezmeme malé kroky od aktuální pozice hráče v aktuálním směru. Pro každou pozici ověříme, jestli netrefila objekt. Ověříme pouze objekty s parentem hlavní zdi, který mají všechny důležité objekty. Pokud na pozici je, ověříme zda je to barel. Pokud je, zničíme ho. Pokud trefíme základní zeď, zastavíme smyčku, protože to bude znamenat konec cesty střely. Kod umístěný v Keyboard eventu pro <Space> vypadá takto:

{
var xx, yy, dx, dy, ii;
xx = obj_player.x;
yy = obj_player.y;
dx = 4*cos(obj_player.direction*pi/180);
dy = 4*sin(obj_player.direction*pi/180);

repeat (100)
{
xx += dx;
yy += dy;
ii = instance_position(xx,yy,obj_wall_basic);
if (ii == noone) continue;
if (ii.object_index == obj_barrel)
with (ii) instance_destroy();
break;
}
}
 

(Kod v příkladu pod článkem trochu odlišný v ukládání pozice kamery a požaduje sinus a cosinus v globálních proměnných k urychlení některých výpočtů, ale myšlenka je stejná.)

Přidání protivníků

Je hezké že můžeme střílet na nějaké barely, ale zábava je brzy pryč. Potřebujeme nějaké nepřátele. V tomto tutorialu přidáme právě některé typy příšer, ale když porozumíte jak pracují, je lehké přidat další. Pro příšeru budeme potřebovat dva animované sprity, jeden když žije a jeden když umírá. To vše bude fungovat přesně jako barely, jen s jedním rozdílem. Při konci animace smrti neodstraníme mrtvou příšeru, ale necháme ji povalovat, bude zobrazovat poslední podobrázek animace. K tomuto účelu přidáme do eventu Animation End akci Change sprite, nastavíme správný podobrázek (7) a rychlost na 0.

Aby mohli být zastřeleny, použijeme stejný postup jako pro barel. Ale musíme udělat několik změn. První, nenastavíme příšerám parent základní zdi. To by způsobilo problém při pohybu kolem. Takže vytvoříme nový objekt obj_monster_basic. Ten bude parentem pro všechny příšery (ikdyž máme teď jenom jednu). Druhá změna je, že budeme chtít střílet přes rostliny. (základní objekt rostliny má jako parent základní zeď, protože nechceme aby po nich chodil hráč.) Kod pro střílení je nyní upraven takto:

{
var xx, yy, dx, dy, ii;
xx = obj_player.x;
yy = obj_player.y;
dx = 4*cos(obj_player.direction*pi/180);
dy = -4*sin(obj_player.direction*pi/180);

repeat (50)
{
xx += dx;
yy += dy;
ii = instance_position(xx,yy,obj_wall_basic);
if (ii == noone)
{
ii = instance_position(xx,yy,obj_monster_basic);
if (ii == noone) continue;
with (ii) instance_destroy();
break;
}
if object_is_ancestor(ii.object_index,obj_plant_basic) continue;
if (ii.object_index == obj_barrel)
with (ii) instance_destroy();
break;
}
}
 

Je to z velké části stejné jako původní kod. První ověříme, jestli střela trefila zeď. Pokud ne, ověříme trefení příšery, a pokud ano, zničíme ji. Pokud trefíme zeď, ověříme jestli je instance rostlina, a pokud ano, bude pokračovat (takže střela proletí rostlinou).

 

(Funkce object_is_ancestor(obj1,obj2) vrací pokud je obj2 ancestor objektu obj1.) Nakonec, pokud trefíme barel, exploduje.

 

Poslední věc, kterou uděláme, je nechat příšery útočit na hráče. Tyto příšery nebudou střílet, ale budou jednoduše chodit za hráčem. Když narazí na hráče, odebere se mu trochu zdraví. Mechanismus zdraví je jak asi víte zabudovaný v Game Makeru. V eventu Create objektu hráče nastavíme health na 100. V objektu zbraně, kde je funkce na vykreslení na obrazovku, vykreslíme healthbar, lehce průhledný, jako tento:

draw_set_alpha(0.4);
draw_healthbar(5,460,100,475,health,c_black,c_red,c_lime,0,true,true);
draw_set_alpha(1);
 

A v eventu No More Health jednoduše restartujeme hru (trochu nudné; vymyslete něco lepšího).


K vyvolání útoku příšer na hráče vložíme následující kod do eventu Begin Step objektu příšery:

{
if (point_distance(x,y,obj_player.x,obj_player.y) > 200)
{ speed = 0; exit; }
if (collision_line(x,y,obj_player.x,obj_player.y,obj_wall_basic,false,false))
{ speed = 0; exit; }
if (point_distance(x,y,obj_player.x,obj_player.y) < 12)
{
speed = 0; health -= 2;
if not sound_isplaying(snd_ow) sound_play(snd_ow);
exit;
}
move_towards_point(obj_player.x,obj_player.y,1.4);
}
 

To dělá následující: Pokud je vzdálenost mezi hráčem a příšerou velká, nedělá nic a jednoduše nastaví speed na 0. Pokud příšera nevidí hráče (čára mezi němi koliduje se zdí) opět nedělá nic. Pouze pokud příšera vidí hráče, začne se za ním pohybovat. Pokud je vzdálenost menší jak 12, předpokládejme že narazila na hráče, takže zastaví a začne odčítat zdraví a přehrávat zvuk. Jinak se bude pohybovat za hráčem s danou rychlostí. ( Pamatujte, že první ověření vzdálenosti může být odstraněno, ale funkce pro ověření kolizní linky je celkem náročná, proto je lepší ji provádět jen pokud je příšera blízko.) Pro vyhýbání zdi může mít příšera stejný pohybový mechanismus jaký jsme dali postavě.

 

Teď musíme umístit nějaké příšery do životně důležitých míst našeho světa. Máme připravenou first person střílečku. Hru můžete najít v souboru dole. Samozřejmě, k vytvoření zajímavější hry bychom měli vytvořit východ do dalšího roomu, střežený příšerami, a vytvořit několik dalších roomů. Můžete taky vytvořit několik dalších příšer, a přidat nějaké další objekty do světa, jako balíčky životů. Také můžete dát příšerám zdraví, k zabití bude potřeba několik střel, a můžete přidat možnost najít lepší zbraně a náboje. Je jen na vás jak to rozšíříte.

 
 

Příští díl ukončí tento tutoriál Marka Overmarse. Řekneme si jak do hry přidat další vylepšení (například dveře) nebo jak zlepšit herní výkon.

 
Aktuální editovatelnou hru najdete tady

Ostatní díly seriálu:
[25.07. 2010] - First Person Shooter - 4. část
[25.07. 2010] - First Person Shooter - 2. část
[25.07. 2010] - First Person Shooter - 1. část
Klíčová slova: first person shooter fps 3D GM3D
 

Komentáře:

Napsal: NicharCZ
Přidáno: 26.07. 2010

Mno... Co k tomu říct.. Super!

Trvalý odkaz

Napsal: Quadman
Přidáno: 26.07. 2010

nice work ;-)

Trvalý odkaz

Velkej Chytrák
Copyright (c) 2001-2010