Rozważ siatkę 2d płytek i przybliżoną kulę współrzędnych - wyśrodkowaną na odtwarzaczu - która reprezentuje linię wzroku. Celem jest zablokowanie linii wzroku poza przeszkodami (np. Ścianami).
Względnie proste jest ustalenie, czy widoczna jest pojedyncza komórka w polu widzenia: rzuć promień z gracza na komórkę docelową, używając Bresenhama - jeśli jedna z nakładających się komórek między graczem a celem jest przeszkodą, komórka docelowa nie jest widoczny.
Teraz moją pierwszą myślą było iterowanie przez wszystkie komórki siatki w linii wzroku - ale wydaje mi się to nieskuteczne. Na przykład, jeśli gracz stoi obok ściany, a stwierdzisz, że komórka poza ścianą nie jest widoczna, możesz określić wszystkie komórki na promieniu, po czym nie będą widoczne.
Zastanawiałem się również, czy nie rzucić promienia na każdą komórkę na obwodzie sfery wzroku i iterować każdą komórkę wzdłuż każdego promienia - ale wtedy przetwarzałbym niektóre komórki więcej niż raz.
Czy istnieje bardziej skuteczny sposób to zrobić?
Podczas gdy iteracja ~ 50 komórek na turę jest względnie lekką kalkulacją, idę na szybkość - celem jest móc przejechać kilka tur na sekundę podczas auto-gry. Im bardziej wydajne mogę to zrobić, tym lepiej.
źródło
Odpowiedzi:
Możesz spróbować rzucić „łuki cienia”, aby objąć jednocześnie większe obszary. Chociaż rzeczywiste szczegóły są nieco zaangażowane, Eric Lippert ma bardzo szczegółowe wyjaśnienie (z demo Silverlight na żywo) na http://blogs.msdn.com/b/ericlippert/archive/2011/12/12/shadowcasting-in -c-part-one.aspx .
źródło
Wdrożyłem algorytm zaproponowany przez Jimmy'ego.
Film z kodem w akcji tutaj: https://youtu.be/lIlPfwlcbHo
źródło