Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Temnota a světlo v GML

Dnes si ukážeme jak udělat ve hře temnotu a samozřejmě tu bude i světlo. Světlo v GM a GM:S začátečníci často řeší tak, že udělají černý sprite s dírou centrovanou na hráče. Inu, pro začátek to není špatné. Ovšem potom se dostáváme k problému "Co když tu bude jiný zdroj světla?", což toto řešení zcela rozbijí. Na druhou stranu pokročilý to řeší DLL knihovnami nebo vlastními Shadery, což má nevýhodu v tom, že to nemusí korektně zpracovat na všech platformách.

Dnes vás naučím jak vytvořit temnotu a světlo použitím vestavěných funkcí, což pracuje správně na všech platformách a podporuje více zdrojů světla.

Pro toto řešení budete potřebovat jen dva objekty a místnost.

oLightController

Vytvoříme si první objekt a pojmenujeme ho "oLightContro­ller".

Create

Vložíme do něj CREATE event a do nej napíšeme jediný řádek.

global.light = surface_create(view_wview,view_hview);

V tomto jediném řádku vytvoříme globální proměnnou s názvem light (ang. světlo), do této proměnné uložíme právě vytvořený surface s rozměry aktivního pohledu.

Pozn.: Globální proměnné mají výhodu, že nejsou obsaženy v žádném objektu, ale v samotné hře. Tudíž jdou volat nebo modifikovat odkudkoliv a existují i když objekt, který ji vytvořil, již neexistuje.

Step

Dále následuje STEP event. Do něj dáme tento kód.

surface_set_target(global.light);
draw_set_color(c_white);
draw_rectangle(0,0,view_wview,view_hview,false);
surface_reset_target();

Funkce surface_set_target(id) nastaví jako cíl vykreslování surface uložený v proměnné. Normálně nebo spíše bez definice se používá surface obsažený v okně programu. draw_set_color(col) nastaví na následující vykreslování určitou barvu, pamatujte, že z důvodu použitého blend módu (to až v draw eventu) bude světlejší barva dělat tmavší temnotu. Takže když chcete naprostou temnotu, použijte bílou barvu. Když chcete tmu napůl průhlednou, použijte šedou. Pokud tmu nechcete (například při den-noc cyklu), použijete černou. S funkcí draw_rectangle(x1,y1,x2,y2,outline) nakreslíte přes monitor tmu a nakonec funkce surface_reset_target() nastaví cíl vykreslování zpět na surface okna, ke které normálně nemáme přístup. I přes to, že máme surface plný tmy, zatím jej nevykreslujeme na monitor. To uděláme v DRAW eventu.

Draw

Vytvoříme si DRAW event a dáme do něj tento kód.

draw_set_blend_mode(bm_subtract);
draw_surface(global.light,view_xview,view_yview);
draw_set_blend_mode(bm_normal);

Funkce draw_set_blend_mode(bm_subtract) nastaví blend mód na subtract, což je hojně používané na efekty světla a tmy. Funkce draw_surface(id,x,y) vykreslí surface na monitor na zadaných souřadnicích, v našem případě to je levý horní roh aktivního pohledu. Jelikož surface má rozměry aktivního pohledu, tak pokryje celý pohled. Nakonec nastavíme blend mód zpět na normální.

oLightSource

Jako zdroj světla poslouží jiný objekt, nyní si vytvoříme nový objekt a pojmenujeme ho oLightSource.

Tento objekt bude mít jen jeden event a to END STEP event.

Step

Použitím End Step eventu zajistíme, aby se vykreslilo vše ostatní a až potom světlo. Kdybychom kód dali do STEP eventu, mohli bychom mít v budoucnu problém s depthem (např. světlo by se mohlo vykreslovat pod některými objekty). Takže si END STEP event vytvoříme a vložíme do něj tento kód.

size = 128;
draw_set_blend_mode(bm_subtract);
surface_set_target(global.light);
draw_ellipse_color(x-(size/2)-view_xview,y-(size/2)-view_yview,x+(size/2)-view_xview,y+(size/2)-view_yview,c_white,c_black,false);
surface_reset_target();
draw_set_blend_mode(bm_normal);

Pozn.: Tento kousek kódu je přizpůsoben tomu, aby jej šlo dát to scriptu, jen místo size, c_white a c_black použijete argumenty.

Proměnná size určuje jak velké naše světlo bude v pixelech. draw_set_blend_mode(bm_mode) nám nastaví blend mód na subtract. surface_set_target(id) nastaví cíl vykreslování na danou surface. Funkce draw_ellipse_color(x1,y1,x2,y2,col1,col2,outline) nám vykreslí světlo. Je použit jednoduchý výpočet, který nastaví velikost vykreslovaného světla podle proměnné size. Jelikož surface se pohybuje s pohledem (viz. olightController objekt), je potřeba od souřadnic elipsy odečíst x/y pohledu (jinými slovy, souřadnice budou relativní k souřadnicím pohledu). Potom tu jsou dvě barvy použité pro vykreslení. Dvě jsou proto, že barva elipsy je přechod, kde první barva bude uprostřed a druhá u kraje.

Tím je vše hotovo. Do místnosti si dejte oLightController a oLightSource. Pokud narazíte na problém, napište ho do komentáře, kde vám rád pomohu.

Temnota a stín v GameMakeru - GameMaker - Efekty

Nakonec jsem vám připravil praktický příklad, v zipu naleznete projekt a spustitelnou aplikaci.

Doufám že jsem vás dnes naučil něco užitečného a nezapomeňte, vědění je od toho, aby se sdílelo.

Pokud se chcete o blend módech dozvědět více, můžete jít na YoYo games blog, první díl zde a druhý zde.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 624x (2.14 MB)

 

Všechny články v sekci
GameMaker - Efekty
Článek pro vás napsal Garrom Orc Shaman
Avatar
Uživatelské hodnocení:
3 hlasů
Autor zabýval pasní her v nástroji GameMaker, poté Unity3D a teď se zabývá GoDot enginem. Dokud tu někde nebude kategorie "GoDot", autor nejspíše psát nebude.
Aktivity