Jak wdrożyć oświetlenie zokludowane w grze 2D opartej na blokach?

11

Chcę mieć oświetlenie 2D, które mogą być blokowane przez obiekty w grze. Moja gra ma widok z góry, a wszystkie obiekty w grze są opisane prostokątami.

Powiedzmy, że mam świat 10x10 i umieszczam światło na 1x1 i ściany wokół tego światła. Chcę widzieć źródło światła na 1x1, ale nigdzie indziej, ponieważ jest zablokowane przez ściany.

Słyszałem o rzucaniu promieni świetlnych, ale jak to naprawdę działa?

LiquidFeline
źródło
1
Chciałbym zobaczyć odpowiedzi na to pytanie niezależnie od języka.
Dashto,
2
@Dashto: Potrzebujesz działającego kodu w języku, którego używasz? To jest złe miejsce, o które można prosić ...
Kromster,
Czego próbowałeś? Kiedy mówisz „gdziekolwiek indziej nie ma źródła światła”, co masz na myśli? Właśnie podświetliłem ci 1,1 bloku i to wszystko. Może nie dostaję twojego pytania, czy mógłbyś zamieścić ilustrację?
Laurent Couvidou,
1
@Krom Stern: Właściwie pytam o dokładne przeciwieństwo - konceptualną odpowiedź, która nie zależy od języka. Dwa wątki połączone jako duplikaty nie mówią zbyt wiele o pojęciach. W rzeczywistości na większość podobnych pytań na tej stronie znajdują się odpowiedzi „Użyj tej biblioteki!” co jest mniej pomocne dla kogoś, kto chce zrozumieć, jak to działa.
Dashto
@Dashto: To ważna informacja, należy ją dodać do pytania;)
Kromster

Odpowiedzi:

13

Amit Patel napisał bardzo fajny artykuł na temat odlewania promieniami 2D.

Polega to na rzucaniu promieniami na każdy z wierzchołków w zasięgu źródła światła, aby zbudować lekką siatkę.

wprowadź opis zdjęcia tutaj

Wszystkie wizualne przykłady są interaktywne w poście i bardzo łatwe do zrozumienia.

Nie musisz też ograniczać się do pudełka, którego obwód może mieć dowolny kształt.

MichaelHouse
źródło
1

Powinieneś użyć algorytmu raycasting , co oznacza, że ​​powinieneś być w stanie obliczyć przecięcie promienia (pół linii) z dowolnym obiektem w scenie (linie, kwadraty, koła, trójkąty ....) i wybrać najbliższe przecięcie. Rzucasz promień we wszystkich kierunkach, a następnie „przyciągasz światło” tylko do najbliższego obiektu.

Oto jak może to wyglądać .

Ivan Kuckir
źródło
Właśnie zapytałem, jak użyłbym odlewania promieniami. Wiem o tym.
LiquidFeline
0

Jeśli wiesz, co to jest rzutowanie promieniami, wszystko, co musisz naprawdę zrobić, to na stałe go zakodować. Nie jest to zbyt skomplikowane, o ile masz współrzędne dla każdego wierzchołka.

Najpierw utwórz obiekt emitujący światło. Umieść swoje światło na współrzędnych x, y.

#include <math.h>
int i = 0;
if ( sqrt( abs( light.x - vertex.x )^2 + abs( light.y - vertex.y )^2 ) <= light.radius)
{
    lightOccludingVertices[i] = vertex;
    i++;
}

//If two or more vertices are both a member of an individual wall,
//illuminate the triangular area between the light, the furthest 
//vertex on the x-axis, and the furthest vertex on the y-axis

Nie gwarantuje się, że zadziała w przypadku wielokąta wklęsłego, ale powinno działać dobrze w przypadku dowolnych wielokątów wypukłych.

Działa to, jeśli obiekty okluzji (ściany, postać, latający purpurowy zjadacz ludzi) zostaną namalowane na ekranie po zastosowaniu oświetlenia. W przeciwnym razie połowa ściany będzie wydawać się znacznie jaśniejsza niż druga połowa. Jeśli światło punktowe jest w równej odległości od dwóch par wierzchołków tej samej ściany (dokładnie o połowę wysokości wysokości ściany), zastosuj trójkąt do dwóch najbliższych wierzchołków, a nie dwóch dalej.

Powinienem również wspomnieć, że ta metoda wymaga dynamicznie tworzonego punktu wierzchołka, w którym krawędź promienia światła styka się z powierzchnią obiektu zamykającego.Tworzy to co najmniej 3 wierzchołki dla każdego obiektu zasłaniającego i pozwoli ścianom, które wystają poza promień światła (lub poza ekranem), również blokować każde światło.

Więcej informacji o wielokątach wklęsłych i wypukłych

igrad
źródło