Roguelike stíny/viditelnost - implementace z návodu (mírná matyka)

Pokud si nevíte s něčím rady ohledně tvorby v Game Makeru - pište sem!
Odpovědět
Kaleta
Příspěvky: 16
Registrován: říjen 23, 2011, 1:53 pm
Facebook: http://facebook.com/

Roguelike stíny/viditelnost - implementace z návodu (mírná matyka)

Příspěvek od Kaleta » prosinec 17, 2016, 7:13 pm

Zdravím všechny, kdo někdy rádi hráli ADOM, Angband, Helherron, Avernum, Eschalon, a milion dalších podobných RPG.

Každý správný roguelike potřebuje odkrývání a zakrývání viditelnosti mapy. A protože mi to pořád nedá, tak jsem se rozhodl vyzkoušet a do GM implementovat tento návod:
http://journal.stuffwithstuff.com/2015/ ... hero-sees/

Mým cílem je schopnost testovat, zdali je nějaké políčko viditelné, nebo není. Což není možné při použití surfaces. Proto jsem se rozhodl pracovat se strukturou ds_grid. Návod je napsaný v jazyce Dart, takže je třeba nějakých úprav.

Princip je tento.
1) vytvořil jsem dvě mřížky - wallgrid a fowgrid. Wallgrid, jak název napovídá, je prostě to, kde je uloženo, kde jsou zdi. Fowgrid je mřížka, kde bude fog of war. Wallgrid se nemění, ale fowgrid se bude měnit dynamicky, právě podle toho toho, co se nachází ve wallgrid. Prakticky řečeno, 0 znamená průhledné, 1 znamená zakryto (jako alpha).

2) Postupoval jsem podle návodu. Vzal jsem skript, který dokáže projít pole na koláčovém výřezu 1/8 obrazovky a odhalit (zprůhlednit) všechna pole. Ten skript jsem potom upravil, aby ho šlo otáčet a zopakovat jej na zbylých 7/8 obrazovky, do nějaké vzdálenosti. Tady to fungovalo.

3) Teď nastalo to těžké. Návod je založen na tom, že při každém procházení výřezu z koláče se vytvoří zvláštní datová struktura, která v obsahuje jakési rozmezí dvou úhlů, které kostka svírá s hráčem na obou svých hranách. Procházení výřezu postupuje od hráče dopředu a při každém řádku se uloží rozmezí všech kostek v řádku. Každý další řádek přidá svoje kostky a testuje, jestli už nejsou zakryté rozmezím předchozích kostek. Pokud ano, tak se taky zakryjí. Chytrý trik je v tom, že autor neukládá konkrétní souřadnici kostky, ale zlomek poměru toho, jak moc je daná kostka daleko od levého okraje výřezu. 0 - na levém okraji, 1 - na pravém okraji, 0.5 - něco mezi tím. Tento zlomek má výhodu, že je vždy stejný, ať už kostka zavazí přímo před hráčem, nebo daleko od něho.

5) K vytvoření stínových linií jsem použil ds_list. Jeden ds_list, kde lichá místa označují začátek zakrytého rozmezí a sudá pole jeho konec, takže list může být dlouhý libovolně. Testuji vždy pro poslední, nově přidanou položku, vůči položkám od začátku, protože postupujeme od hrdiny do dálky.
Pokud poslední rozmezí do žádného předchozího nespadá, tak je pole viditelné, jinak je zakryté.

6) No, ale tady to právě blbne. Náznaky funkčnosti tam jsou, ale taky hodně chaosu. Kostky se často odkrývají a zakrývají dost nesmyslně. Mám podezření, že za to může skript projectTile, kde docházelo k dělení nulou (tak jsem tam dal zarážku). Ale víc mi dělá starosti pasáž, kterou úplně nechápu (ach ta matematika) a nejsem si jist, jestli není nějak špatně, pozdě nebo vůbec transformovaná do jiného úhlu při otáčení toho výřezu (skript transformOctant)

Kód: Vybrat vše

topLeft = cols / (rows + 2);
bottomRight = (cols + 1) / (rows + 1);
Tam, kde jsou plusy, neměly by být pro jiný octant být někde mínusy?

Chápu, že je tu strmá učební křivka, ale jestli to někdo spraví, tak si můžete vybudovat kariéru, protože roguelike RPG se prodává dobře, na Steamu je jich plno :D A v GM tohle notoricky skoro nikdo dělat neumí, ani po všech těch letech. Všude je žádné nebo ultra primitivní odkrývání mapy, nebo naopak ultra promakaný shading, který je ale spíš dekorace. Relativně hnusné ale funkční kostky neumí snad nikdo v komunitě.

Tady je ten výtvor:
https://dl.dropboxusercontent.com/u/374 ... gofwar.gmk
Verze GM 8.0 (nejrychlejší kompilace)

Soubor obsahuje ještě i nějaké další skripty, ale to jsou většinou odpad, nebo předchozí verze. Za zmínku stojí úspěšná implementace Bresenhamova algoritmu, který funguje jako collision_line, jenom hledá uvnitř ds_grid. Teoreticky by to šlo udělat brute force, natvrdo udělat raycasting pro všechna pole v celé místnosti pomocí Bresenhamovy collision_line. Ale pokud bych chtěl přidat víc postav s jejich vlastním viděním, tak by to už nebylo schůdné.
Najdete tam i šikovné skripty, který umožňují převést souřadnice z ds_grid na index políčka v ds_grid, počítáno zleva shora, dolů doprava. A potom jde ten index převést na X nebo Y souřadnici pole. To šetří proměnné, protože jediný skript dokáže vrátit souřadnice XY. (musím se pochválit)
To vše je užitečné pro nepřátele, kteří potřebují jedinou věc, zjistit, jestli je collision_line k hráči volná, příp. jestli je jejich pole odkryté...

Uživatelský avatar
DDL Blue
Živý stín
Příspěvky: 431
Registrován: srpen 6, 2011, 7:21 pm

Re: Roguelike stíny/viditelnost - implementace z návodu (mírná matyka)

Příspěvek od DDL Blue » prosinec 24, 2016, 8:28 pm

Hele z GM už sem trochu vypadl a navíc sem to nepouštěl, protože bych musel přebootovat z linuxu na wokna a na to su moc línej :D

...nicméně nesouhlasím, že by jsi u světel řešených přes surfaces nemohl zjistit, kde je světlo a kde je tma. Existuje funkce pojmenovaní tuším něco jako get_pixel(...); která dovede zjistit barvu pixelu na určitý souřadnici. Jakmile to zavoláš nad tím svým surface s osvětlením, máš vyhráno. Údajně je to celkem pomalý (fakt by mě zajímalo proboha proč), takže to asi není dobrej nápad třeba zjišťovat každej step pro každý políčko na mapě, ale funguje to. Případně by se nad to vykreslování dala postavit nějaká paralelní logika, co by to zajišťovala.
Zkoukněte moji hudební galerii ;). Nebo vyzkoušej můj generátor akordů!
Řikejte mi prostě Blue...

Goblin
Příspěvky: 134
Registrován: červenec 2, 2014, 2:42 pm

Re: Roguelike stíny/viditelnost - implementace z návodu (mírná matyka)

Příspěvek od Goblin » prosinec 29, 2016, 12:24 pm

Tohle jsem zatím dělal jen pomocí objektů. Nad každým políčkem na mapě se vznáší objekt se spritem černého čtverce a zprůhledňuje se podle zorného pole/vzdálenosti od hráče (zdi a zavřené dveře se řeší normálně přes collision_line). Nejspíš je to hodně prasácký způsob, ale neseká se to ani na mém obstarožním netbooku. A to řeším zprůhledňování opravdu v každém stepu (což v tahovém rogueliku není zapotřebí). Jestli chceš funkční hnusné čtverce, tak ti klidně pošlu upravený zdroják.

Kdybych to kutil na programové úrovni, asi bych vynechal ds_grid a pracoval s arrayemi. U těch alespoň vím, že mi za zády nežonglují s pamětí...

Sám dělám v GM:S, takže ten přiložený projekt jsem bohužel nezkoušel...
"Understanding is not required. Only obedience."

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host