9. díl - Pohyb v GML část 3.

Ostatní jazyky GameMaker Základy Pohyb v GML část 3.

V minulých dílech jsme řešili, jak zařídit, aby se objekty pohybovaly přesně tam, kam chceme buď rovně nebo po předem definované dráze. To je sice hezké, ale často se při tvorbě her stává, že předem nevíme, kam nebo kudy se mají objekty pohybovat. Jsou to typicky případy, kdy je pohyb určen polohou jiných objektů, jejichž výskyt ovlivňuje hráč nebo náhoda. Např. ve hře Pac-Man příšerky nemají pevnou dráhu, ale podle určitých pravidel si teprve hledají v bludišti. Nebo pokud chceme vytvořit simulátor kulečníku, bude pohyb ovlivňován úderem hráče a nemůžeme ho tedy předem nijak nastavit.

Vektory

V případě, že je pohyb definován jako součet více vlivů, je výhodné použít jednoduché vestavěné vektorové sčítání. Ti, co znají jen základy matematiky možná neví, co to takový vektor je. Takže stručně shrnu, co možná nejednodušeji: obecně jde o dvojici čísel spojených jedním významem, tady konkrétně směr a rychlost. Jak se číslem určí rychlost si není těžké představit. Vyšší číslo - vyšší rychlost. U směru je to složitější. Představme si kružnici okolo objektu. Rozdělíme ji na dílky tak, že začneme zprava nulou. Čtvrt otáčky bude mít 90 dílků (stupňů). Celá otáčka bude mít 360 dílků a 720 budou dvě otáčky dokola. Směr tedy v Game Makeru určuje číslo od nuly do 359 tak, jak znázorňuje tato kružnice:

Direction v GameMakeru

V Game Makeru je vektor pohybu napevno spojen s objektem. Jeden objekt – jeden vektor. Každý objekt má své vestavěné parametry speed a direction, které dohromady určují vektor pohybu. Pokud použijete nějakou pohybovou funkci nebo ikonu, ve skutečnosti měníte tento vektor.

Hm, a co s tím?

V první řadě lze vektor pohybu pevně určit. Buď změnou jednotlivých vlastností nebo použitím funkce motion_set(dir,s­peed).

Tento kód:

//nahoru
direction=90;
speed=1;

/*              je totéž jako:                                        */
//nahoru
motion_set(90,1);

/*              a výsledek je stejný jako např.:             */
vspeed=-1;  //přímá změna další vestavěné proměnné - vertical speed

Zapamatujte si, že direction+=180 způsobí obrácení směru pohybu ať už byl původně kamkoli.

Zatím to vypadá celkem jednoduše, i když se části vektoru (směr, rychlost) mění samostatně. Jakou má tedy výhodu jejich spojení? Zkuste si představit, co se stane, když budeme sčítat dva směry. Když sečteme např. pohyb vzhůru (90) rychlostí 1 s pohybem doleva (180) o stejné rychlosti, dostaneme 270, což je pohyb dolů o rychlosti 2. To ale vůbec neodpovídá fyzikální realitě. Tak se to dělat nedá. Proto má Game Maker funkci, která to udělá za nás: motion_add(dir,spe­ed). Např:

motion_add(90,1); //přičte ke stávajícímu pohybu ještě pohyb vzhůru.

Jednoduché, fyzikálně korektní a bez matematických vzorců.

Vyzkoušejte si ukázku Vectors - působení více vektorů najednou

Tažením levé myši ze středu objektů určíte vektory a po stisku SPACE se objekt začne pohybovat podle součtu těchto vektorů. Rychlost odpovídá délce vektoru. Vektory se započítají do pohybu jen jednou a to bezprostředně po stisku SPACE. Nový stisk SPACE zastaví pohyb a umožní nové nastavení. Pravou myší smažete vektory pro daný objekt.

Kdy vektory použít?

Na začátku tvorby hry si dobře rozmyslete, jestli budete pohyb řešit pomocí vektorů a proč. Uvědomte si, že pokud měníte souřadnice x a y přímo, nebudou vestavěné funkce vědět, že se objekt vůbec pohybuje a změna pomocí motion_add nebude dělat co má. Dále je prakticky nemožné zajistit věrohodnou srážku více objektů, když s jejich vektory pohybu zároveň právě manipulujete např. díky klávesnicové události. Naopak jsou vektory perfektní pro ozvláštnění pohybu nepřátel nebo překážek.

Pohyb vymezený překážkami (2D bludiště) a pronásledování jiného objektu

Tady je třeba pochopit, že hledání cesty v bludišti je matematicky složitá věc a že úkoly na první pohled snadné pro člověka se počítači vysvětlí jen velmi těžko. Cesta ven z bludiště nemusí vůbec existovat nebo jich naopak může existovat víc. Game Maker má funkce, které usnadňují základní práci s hledáním cesty mezi překážkami.

Motion Planning – plánování pohybu

Nutností je, aby objekty měly svůj sprite, který musí obsahovat rozumně nastavenou masku (části obrázku, kde maska není, jsou ignorovány – nelze na ně kliknout, nelze zjistit náraz do jiného objektu a neberou se v potaz pro hledání cesty). Tvorbu správné masky pro sprite si můžete vyzkoušet na přiložené ukázce Maska pro Sprite. Volba precise se snaží udělat masku automaticky podle alfa kanálu – průhlednosti. Ovlivnit se to dá pomocí alpha tolerance posuvníku. Často je ale výhodnější nastavit masku ručně některým z běžných tvarů kruh, obdélník, atd. nebo prostě plný celý sprite. Volba separate collision mask umožní mít různé masky pro každý snímek animovaného sprite.

Masky spritů v GameMakeru

Objekty sloužící jako překážky by měly mít zapnutou vlastnost solid, která slouží právě k tomu účelu. Jako solid může být nastaven i vlastní cestu hledající objekt – má smysl, když se potřebuje vyhýbat také instancím sebe sama.

Rovnou k cíli

Když máme vše připraveno (objekt, překážky, sprite s maskou), můžeme přímo použít některou z následujících funkcí a objekt se přímo začne pohybovat (dejte je do eventu Step):

mp_linear_step(x,y,stepsize,checkall)
mp_linear_step_object(x,y,stepsize,obj)
mp_potential_step(x,y,stepsize,checkall)
mp_potential_step_object(x,y,stepsize,obj)

(fungují podobně jako ikona Step Avoiding – udělají kousek pohybu v daném směru a vyhnou se překážkám)

Vždy určujete souřadnice cíle x a y, stepsize udává velikost posunu během jednoho průběhu funkce (tedy většinou 1x za událost Step) a checkall lze mít true pro porovnání se všemi objekty (pomalé) nebo false pro porovnání pouze s těmi, které mají nastaveno Solid. Varianta obsahující obj porovnává jako překážku jen jediný typ objektu. Celý systém se ještě řídí nastavením:

mp_potential_settings(maxrot,rotstep,ahead,onspot)

To ovšem můžete volně ignorovat, protože základní hodnoty bývají většinou v pořádku. Objekt vždy zkusí přímou cestu a pak se zkouší pootočit po rotstep krocích až po maxrot nebo do nalezení cesty. Ahead říká, jak daleko se objekt kouká před sebe, jestli tam není překážka. Malý ahead jezdí kolem překážek velice těsně. Onspot (true/false) určuje jestli se objekt smí točit i na místě nebo se musí točit vždy jen s pohybem vpřed (cca jako auto).

K cíli chceme mířit křivkou (vyžaduje GM Pro)

Následující skupina funkcí pracuje stejně jako ty předchozí, jen jejím výsledkem není přímo pohyb, ale cesta – path. Tuto cestu musíme mít prázdnou předem vytvořenu v resources (create path).

mp_linear_path(path,xg,yg,stepsize,checkall)
mp_linear_path_object(path,xg,yg,stepsize,obj)
mp_potential_path(path,xg,yg,stepsize,factor,checkall)
mp_potential_path_object(path,xg,yg,stepsize,factor,obj)

Aby se objekt začal skutečně pohybovat, musí se vytvořená cesta k pohybu použít pomocí:

path_start(path,speed,endaction,absolute);

(musí být použita stejná cesta jako ve funkcích pro motion planning)

V přiložené ukázce Labyrint Motion Planning

je jako cíl použit pohybující se objekt. Vykreslují se přitom pohybové cesty tak, jak jsou postupně vypočítávány a to i v případě, že se nepovedlo najít cestu přímo k cíli. Všimněte si, že pokud je objekt follower pomalejší v pohybu než objekt runner, sebelépe nalezená cesta mu nepomůže. Rychlost měníte tlačítky po straně. Princip přepínače (radio button) má mnoho použití, takže si ho prohlédněte a jistě budete schopni používat ho i ve svých programech.

Síť překážek – zcela odlišný způsob

Nejpokročilejší systém průchodu bludištěm jaký GM nabízí, je mp_grid. Pomocí funkce mp_grid_create se založí síť čtverců neboli buněk – cells. Čím bude počet buněk vyšší, tím přesnější bude i výpočet (ale i pomalejší). Funkce mp_grid_add_in­stances umí označit části sítě jako neprůchozí tím, že síť porovná s polohou instancí objektů. Výhodou je, že překážky lze připravit do sítě před začátkem jakéhokoli pohybu. Samotné použití se dělá pomocí funkce:

mp_grid_path(id,path,xstart,ystart,xgoal,ygoal,allowdiag)

Významný rozdíl oproti funkcím z předchozí sady je ten, že se neřeší sprite objektu a průchod se počítá jako jednopixelová cesta z bodu xstart, ystart do xgoal, ygoal. Výsledek se opět promítne do obsahu cesty path. Parametr allowdiag povoluje nebo zakazuje pohyb šikmo v síti.

Ukázka sítě

V přiložené ukázce je dobře vidět jak to funguje, když stisknete Shift – zobrazí se mapa s oblastmi možného průchodu. (vykreslování mapy je pomalé a je určeno je pro testování) Klikáním můžete pokládat do bludiště objekty food, ke kterým se hlavní objekt bude snažit najít cestu. Jako cíl se bere vždy nejbližší (vzdušnou čarou) a je tedy logické, že se někdy stane, že dva nebo více jsou stejně daleko. V ukázce je to řešeno obchvatem – interval zjišťování nových vzdáleností je náhodný. Můžete zkusit předělat ukázku na zjišťování vzdáleností podle délky cesty a ověření dělat až tehdy, když hlavní objekt najde původní cíl.

Pokud ovládnete všechny funkce zmíněné v tomto článku, můžete se stát mistry bludišť.


 

Stáhnout

Staženo 162x (4.8 MB)
Aplikace je včetně zdrojových kódů v jazyce GameMaker

 

  Aktivity (1)

Článek pro vás napsal TomBen
Avatar
-

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Předchozí článek
Pohyb v GML část 2.
Miniatura
Všechny články v sekci
GameMaker - základy a ikonky
Miniatura
Následující článek
Pohyb v GML část 4.

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!