So, durch diesen Thread ist mir aufgefallen, wie einfach es ist ein Beleuchtungssystem zu erstellen das ähnlich gute Resultate liefert wie GodGear's aus dem offiziellen Forum.
Zunächst benötigen wir zwei Grafiken, zum einen den Fußboden und zum anderen ein Licht, zum Beispiel so:
und 
Das Licht wird als Sprite hinzugefügt und das origin sollte 128,128 (center) sein, damit das Licht später auch genau dort erscheint wohin man es platziert hat. Der Boden wird als Background hinzugefügt und auch gleich als Hintergrund für den Raum eingestellt. (Ich arbeite hier mal mit einem Raum in der Größe 640x480).
Jetzt fügen wir ein neues Objekt hinzu, das das Licht darstellt, wir nennen es einfach "obj_spot". Der Visible-Haken wird rausgenommen. Wir geben ihm KEINEN sprite, schreiben aber in das Create-event:
Und jetzt zur Erklärung der Code-Zeilen:
sprite_index = spr_light; Hier wird dem objekt der Licht-sprite zugewiesen. Es wird bewusst erst hier gemacht, denn wenn man schon im Objekt das Licht-sprite auswählt ist beim platzieren im Raumeditor schnell der Bildschrim voll.
image_blend = c_white;# Hier wird dem objetk die standart-licht-farbe gegeben. Durch andere Farben kann man zum Beispiel blaues, gelbes, rotes etc Licht erschaffen.
image_alpha = 0.75; Die Lichtstärke (0-1), damit das Licht nicht total hell Leuchtet ist es auf 0.75, je kleiner desto schwächer.
Jetzt verteilen wir ein paar der neuen Licht-objekte im Raum, so zum Beispiel:

Beim starten des Spiels stellen wir fest, das nichts außerd em Hintergrund gezeichnet wird. Deshalb brauchen wir nun ein anderes Objekt, welches die Lichter zeichnet, wir nennen es "obj_light_controller". Es hat ebenfalls KEINEN sprite, aber eine Depth von 1, damit es Anzeigen welche meistens eine Depth von 0 haben nicht überdeckt. Das Objekt wird irgendwo im Raum platziert.
Jetz beginnen wir mit den Scripts, und erstellen schonmal das erste! Es heißt "light_init" und setzt das Beleuchtungssystem in Gang. Reingeschrieben wird folgender Code:
Erklärung:
a_color = make_color_rgb(255-color_get_red(argument0),255-color_get_green(argument0),255-color_get_blue(argument0)); Das Skript wird mit einem Parameter aufgerufen, nämlich der Umgebungs-Helligkeit. Da wir aber später die Lichter negativ zeichnen müssen, wird die Farbe ebenfalls umgedreht.
surface = surface_create(640,480); Hier wird eine Oberfläche erstellt mit der Größe des zu sehenden bereichs (hier 640x480).
Von nun an haben wir also nicht nur die ganz normale Zeichen-fläche die auf dem Bildschrim gezeigt wird sondern noch eine zweite in der selben größe, das kann man sich nun so vorstellen:
normale Zeichenfläche + neue Surface (Oberfläche)
+ 
Das komische Muster rechts kommt davon, dass wir noch nichts auf die Oberfläche gezeichnet haben, und deshalb nur überreste aus dem Grafik-Speicher zu sehen sind.
In das Create-event des Light-Controllers setzen wir nun folgenden Code
Damit wird zu Beginn die Licht-engine aufgerufen und die Umgebungshelle auf ein dunkles grau gesetzt.
Jetzt kommt das Zweite und somit auch schon das schwerste der 3 Skripts. Es heist "light_refresh", und beinhaltet folgenden Code
Erklärung:
surface_set_target(surface); Das Zeichnen wird auf die Oberfläche umgestellt. d.h. von nun an wird bei Zeichenbefehlen die Surface an stelle des normalen Bildes bemalt.
draw_clear(a_color); Die Surface wird komplett mit der (invertierten) Umgebungsfarbe übermalt.
draw_set_blend_mode(bm_subtract); Der Blend-mode wird auf Subtrahieren umgestellt, damit die Lichter ebenfalls invertiert auf die Surface gezeichnet werden
with (obj_spot)
{
draw_sprite_ext(sprite_index,image_index,x,y,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
} Alle Lichter werden auf der Surface eingezeichnet
draw_set_blend_mode(bm_normal); Blend Mode wird wieder normal gesetzt.
surface_reset_target(); Auch wird jetzt nichtmehr auf die Oberfläche gezeichnet.
Im Step-event des Light-Controller wird eingetragen, dass es das script "light_refresh" aufruft. Wenn wir jetzt starten hat sich aber nichts geändert, es wird immernoch nur der Hintergrund gezeichnet. Woran liegts? Wir haben bisher nur alles auf eine Oberfläche gezeichnet, Verwendung fand diese aber noch nicht. Zur Verdeutlichung, wir haben:
normale Zeichenfläche + Surface mit invertierten Lichtern drauf
+ 
Jetzt kommen wir zu unserem letzten Skript. Es heißt "light_draw" und beeinhaltet folgenden Code:
Hier wird die Surface invertiert über das Bild gezeichnet. Jetzt muss nur noch im draw_event des light_controllers
eingetragen werden und voilá, fertig sind wir. So müsste es dann aussehen:

Natürlich ist hier noch nicht so viel möglich, aber ich hab es bewusst einfach gehalten damit leichter das System dahinter verstanden wird. Es zu erweitern ist ziemlich einfach, hier ein paar Stichpunkte was man machen sollte/könnte bevor man es verwendet:
- Views unterstützen
- Parents benutzen, da es sonst bei mehreren licht-objekten umständlich wird
- Lichter die weit außerhalb der View sind deaktivieren
- light_refresh schon im Create-event benutzen, da sonst im ersten Bild hässliche Fehler sein könnten da die surface noch nicht überzeichnet wurde
- etc
PS: Farbige, bewegte Lichter usw ist alles Möglich!
Zunächst benötigen wir zwei Grafiken, zum einen den Fußboden und zum anderen ein Licht, zum Beispiel so:


Das Licht wird als Sprite hinzugefügt und das origin sollte 128,128 (center) sein, damit das Licht später auch genau dort erscheint wohin man es platziert hat. Der Boden wird als Background hinzugefügt und auch gleich als Hintergrund für den Raum eingestellt. (Ich arbeite hier mal mit einem Raum in der Größe 640x480).
Jetzt fügen wir ein neues Objekt hinzu, das das Licht darstellt, wir nennen es einfach "obj_spot". Der Visible-Haken wird rausgenommen. Wir geben ihm KEINEN sprite, schreiben aber in das Create-event:
Und jetzt zur Erklärung der Code-Zeilen:
sprite_index = spr_light; Hier wird dem objekt der Licht-sprite zugewiesen. Es wird bewusst erst hier gemacht, denn wenn man schon im Objekt das Licht-sprite auswählt ist beim platzieren im Raumeditor schnell der Bildschrim voll.
image_blend = c_white;# Hier wird dem objetk die standart-licht-farbe gegeben. Durch andere Farben kann man zum Beispiel blaues, gelbes, rotes etc Licht erschaffen.
image_alpha = 0.75; Die Lichtstärke (0-1), damit das Licht nicht total hell Leuchtet ist es auf 0.75, je kleiner desto schwächer.
Jetzt verteilen wir ein paar der neuen Licht-objekte im Raum, so zum Beispiel:

Beim starten des Spiels stellen wir fest, das nichts außerd em Hintergrund gezeichnet wird. Deshalb brauchen wir nun ein anderes Objekt, welches die Lichter zeichnet, wir nennen es "obj_light_controller". Es hat ebenfalls KEINEN sprite, aber eine Depth von 1, damit es Anzeigen welche meistens eine Depth von 0 haben nicht überdeckt. Das Objekt wird irgendwo im Raum platziert.
Jetz beginnen wir mit den Scripts, und erstellen schonmal das erste! Es heißt "light_init" und setzt das Beleuchtungssystem in Gang. Reingeschrieben wird folgender Code:
Erklärung:
a_color = make_color_rgb(255-color_get_red(argument0),255-color_get_green(argument0),255-color_get_blue(argument0)); Das Skript wird mit einem Parameter aufgerufen, nämlich der Umgebungs-Helligkeit. Da wir aber später die Lichter negativ zeichnen müssen, wird die Farbe ebenfalls umgedreht.
surface = surface_create(640,480); Hier wird eine Oberfläche erstellt mit der Größe des zu sehenden bereichs (hier 640x480).
Von nun an haben wir also nicht nur die ganz normale Zeichen-fläche die auf dem Bildschrim gezeigt wird sondern noch eine zweite in der selben größe, das kann man sich nun so vorstellen:
normale Zeichenfläche + neue Surface (Oberfläche)


Das komische Muster rechts kommt davon, dass wir noch nichts auf die Oberfläche gezeichnet haben, und deshalb nur überreste aus dem Grafik-Speicher zu sehen sind.
In das Create-event des Light-Controllers setzen wir nun folgenden Code
Damit wird zu Beginn die Licht-engine aufgerufen und die Umgebungshelle auf ein dunkles grau gesetzt.
Jetzt kommt das Zweite und somit auch schon das schwerste der 3 Skripts. Es heist "light_refresh", und beinhaltet folgenden Code
Erklärung:
surface_set_target(surface); Das Zeichnen wird auf die Oberfläche umgestellt. d.h. von nun an wird bei Zeichenbefehlen die Surface an stelle des normalen Bildes bemalt.
draw_clear(a_color); Die Surface wird komplett mit der (invertierten) Umgebungsfarbe übermalt.
draw_set_blend_mode(bm_subtract); Der Blend-mode wird auf Subtrahieren umgestellt, damit die Lichter ebenfalls invertiert auf die Surface gezeichnet werden
with (obj_spot)
{
draw_sprite_ext(sprite_index,image_index,x,y,image_xscale,image_yscale,image_angle,image_blend,image_alpha);
} Alle Lichter werden auf der Surface eingezeichnet
draw_set_blend_mode(bm_normal); Blend Mode wird wieder normal gesetzt.
surface_reset_target(); Auch wird jetzt nichtmehr auf die Oberfläche gezeichnet.
Im Step-event des Light-Controller wird eingetragen, dass es das script "light_refresh" aufruft. Wenn wir jetzt starten hat sich aber nichts geändert, es wird immernoch nur der Hintergrund gezeichnet. Woran liegts? Wir haben bisher nur alles auf eine Oberfläche gezeichnet, Verwendung fand diese aber noch nicht. Zur Verdeutlichung, wir haben:
normale Zeichenfläche + Surface mit invertierten Lichtern drauf


Jetzt kommen wir zu unserem letzten Skript. Es heißt "light_draw" und beeinhaltet folgenden Code:
Hier wird die Surface invertiert über das Bild gezeichnet. Jetzt muss nur noch im draw_event des light_controllers
eingetragen werden und voilá, fertig sind wir. So müsste es dann aussehen:

Natürlich ist hier noch nicht so viel möglich, aber ich hab es bewusst einfach gehalten damit leichter das System dahinter verstanden wird. Es zu erweitern ist ziemlich einfach, hier ein paar Stichpunkte was man machen sollte/könnte bevor man es verwendet:
- Views unterstützen
- Parents benutzen, da es sonst bei mehreren licht-objekten umständlich wird
- Lichter die weit außerhalb der View sind deaktivieren
- light_refresh schon im Create-event benutzen, da sonst im ersten Bild hässliche Fehler sein könnten da die surface noch nicht überzeichnet wurde
- etc
PS: Farbige, bewegte Lichter usw ist alles Möglich!