Wie implementiere ich verschlossene Beleuchtung in einem blockbasierten 2D-Spiel?

11

Ich möchte eine 2D-Beleuchtung, die durch Objekte im Spiel blockiert werden kann. Mein Spiel hat eine Ansicht von oben nach unten und alle Spielobjekte werden durch Rechtecke beschrieben.

Nehmen wir an, ich habe eine 10x10-Welt und platziere ein Licht auf 1x1 und Wände rund um dieses Licht. Ich möchte die Lichtquelle 1x1 sehen können, aber nirgendwo anders, weil sie von den Wänden blockiert wird.

Ich habe gehört, dass das Werfen von Lichtstrahlen funktioniert, aber wie funktioniert das wirklich?

LiquidFeline
quelle
1
Ich würde gerne einige sprachunabhängige Antworten auf diese Frage sehen.
Dashto
2
@Dashto: Benötigen Sie einen funktionierenden Code in der von Ihnen verwendeten Sprache? Das ist ein falscher Ort, um danach zu fragen.
Kromster
Was hast du versucht? Was meinst du mit "irgendwo anders, wo es keine Lichtquelle gibt"? Nur Sie 1,1 Block beleuchtet und das war's. Vielleicht verstehe ich Ihre Frage nicht, könnten Sie eine Illustration posten?
Laurent Couvidou
1
@Krom Stern: Ich frage eigentlich nach dem genauen Gegenteil - einer konzeptionellen Antwort, die nicht von der Sprache abhängt. Die beiden als Duplikate verknüpften Threads sprechen nicht viel über die Konzepte. Tatsächlich haben die meisten ähnlichen Fragen auf dieser Site einfach Antworten mit der Aufschrift "Verwenden Sie diese Bibliothek!" Das ist weniger hilfreich für jemanden, der verstehen will, wie es funktioniert.
Dashto
@Dashto: Das ist eine wichtige Information, das solltest du der Frage hinzufügen;)
Kromster

Antworten:

13

Amit Patel hat einen sehr schönen Artikel über 2D-Raycasting geschrieben.

Dies beinhaltet das Werfen von Strahlen auf jeden der Eckpunkte innerhalb des Bereichs der Lichtquelle, um ein Lichtnetz aufzubauen.

Geben Sie hier die Bildbeschreibung ein

Alle visuellen Beispiele sind interaktiv in der Post und sehr leicht zu verstehen.

Sie müssen sich auch nicht auf eine Box beschränken, der Umfang, den Sie verfolgen, kann eine beliebige Form haben.

MichaelHouse
quelle
1

Sie sollten einen Raycasting-Algorithmus verwenden, dh Sie sollten in der Lage sein, den Schnittpunkt des Strahls (halbe Linie) mit einem beliebigen Objekt in Ihrer Szene (Linien, Quadrate, Kreise, Dreiecke ...) zu berechnen und den nächstgelegenen Schnittpunkt auszuwählen. Sie werfen den Strahl in alle Richtungen und "zeichnen das Licht" nur zum nächsten Objekt.

So kann es aussehen .

Ivan Kuckir
quelle
Ich habe nur gefragt, wie ich Ray Casting verwenden würde. Ich weiß darüber Bescheid.
LiquidFeline
0

Wenn Sie wissen, was Ray Casting ist, müssen Sie es nur hart codieren. Es ist nicht übermäßig komplex, solange Sie Koordinaten für jeden Scheitelpunkt haben.

Erstellen Sie zunächst ein lichtausstrahlendes Objekt. Platzieren Sie Ihr Licht bei x, y Koordinaten.

#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

Es ist nicht garantiert, dass dies für ein konkaves Polygon funktioniert, aber es sollte für alle konvexen Polygone gut funktionieren.

Dies funktioniert, wenn Ihre okkludierenden Objekte (Wände, Charakter, fliegender lila Menschenfresser) nach dem Anlegen der Beleuchtung auf den Bildschirm gemalt werden. Andernfalls erscheint die Hälfte einer Wand deutlich heller als die andere Hälfte. Wenn Ihr Punktlicht gleich weit von zwei Scheitelpunktpaaren derselben Wand entfernt ist (genau halb so hoch wie die Höhe Ihrer Wand), wenden Sie das Dreieck auf die beiden nächstgelegenen Scheitelpunkte an und nicht auf die beiden weiter entfernten.

Ich sollte auch erwähnen, dass diese Methode einen dynamisch erzeugten Scheitelpunkt erfordert, an dem die Kante des Lichtradius auf die Oberfläche des okkludierenden Objekts trifft. Dies erzeugt mindestens 3 Eckpunkte für jedes okkludierende Objekt und ermöglicht es Wänden, die sich über den Radius des Lichts (oder außerhalb des Bildschirms) hinaus erstrecken, auch jegliches Licht zu blockieren.

Weitere Informationen zu konkaven und konvexen Polygonen

igrad
quelle