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 "oLightController".
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.

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ínkamiStaženo 728x (2.14 MB)