Licht und Schatten in 2D? Ich bekomms nicht hin.
Übersicht

![]() |
M0rgensternBetreff: Licht und Schatten in 2D? Ich bekomms nicht hin. |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey Leute.
Ich hab mir die letzten Tage mal überlegt, wie man Lichter auf einer 2D Tilemap umsetzen könnte. Bin bisher leider noch nicht zu einem anständigen Ergebnis gekommen. Folgende Ansätze hatte ich: 1) Mit Lightblend ein halbtransparenten Kreis über entsprechende Stellen zu zeichnen -> Sah bescheuert aus. 2) Einfach prüfen, welche Tiles in dem Einzugsbereich des Lichts sind und diese heller machen -> Gab kantige Kreise. 3) Direkt auf die Pixmap zugreifen und die Entfernung von Pixeln zu Lichtquelle prüfen. -> Erscheint mir immernoch als beste Lösung. Aber: Ich bekomm das nicht hin. So wie ich es mache, ist meine ganze Tilemap grau. Ich hab hier mal den Code, aber wie gesagt, graue Tilemap: BlitzMax: [AUSKLAPPEN] Function CalcLight() Ich hab mir gedacht, ich verrechne die Position des Pixels auf dem Bild mit der Position des zugehörigen Tiles auf der Map um die Pixelposition auf der Map zu bekommen, aber irgendwas mach ich falsch. Vor allem: Warum wird das grau? Gibt es da einen allgemein besseren Ansatz? (Ich will später halt Wände mit eingeziehen. Lichter müssen nicht mal dynamisch sein. Momentan ist es geplant das vorrendern zu lassen). Lg, M0rgenstern |
||
![]() |
ChaosCoder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also das mit dem grau kommt wahrscheinlich daher:
Code: [AUSKLAPPEN] r = r + (250 - r)
Egal wie groß r,g und b sind, für jedes kommt 250 raus.
g = g + (250 - g) b = b + (250 - b) Warum jetzt die ganze Tilemap gefüllt wird? Keine Ahnung, entweder deine Pythagoras-Funktion liefert falsche Werte oder deine Light.irange ist zu groß?! Mach einfach mal Debug ausgaben, wo du mit derselben Zeile prüfst, ob deine Mausposition im Radius liegt, also sowas: Code: [AUSKLAPPEN] If Pythagoras(Light.ixPos, Light.iyPos, MouseX(), MouseY()) <= Light.irange Then DrawText "Drin!",10,10
Liebe Grüße |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Rechne RGB in HSV um, Stelle die Helligkeit ein, und rechne in RGB zurück. Bin sicher die passenden Funktionen im Codearchiv gesehen zu haben. | ||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Meine Pyhtagoras Funktion funktioniert.
Das hab ich anderswo schon genutzt. Ich glaube, dass ich das so nicht berechnen kann: BlitzMax: [AUSKLAPPEN] maskx + ix * iTILESIZE, masky + iy * iTILESIZE Oder? Ich möchte damit die Position eines Pixels auf dem Bildschirm haben, abhängig von den Tiles. Oder stimmt das? @ Xeres: Guck ich gleich mal nach, vielen Dank. Lg, M0rgenstern |
||
![]() |
ChaosCoder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also meiner Meinung nach ist die Zeile richtig.
Was steht denn da in den Variablen so drin? Also in: iTILESIZE,iMapwidth,iMapheight,Light.irange,pTileMask.width, etc.? BTW: Da steht "For Local iy:Int = 0 Until iMapwidth". |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also:
ITILESIZE = 32 imapwidth = 30 <- Breite der Tilemap imapheight = 30 <- Höhe der Tilemap Light.ilightrange = rand(150,200) <- Reichweiter der Lichtquelle in Pixel. pTileMask.width bzw height stehen die Daten der Pixmap zu dem Tile an einer besitmmten Stelle in der Map. Oh, vielen Dank. Seh ich jetzt erst^^ Lg, M0rgenstern ARG!!! Ich glaube, ich hab das Problem gefunden: Wenn ich die Pixmap des Bildes verändere, dann wird sie für das komplette Bild übernommen. Dauerhaft. Und da die komplette Map aus diesem Bild besteht, ändert sich die komplette Map. Kann man das nicht irgendwie umgehen? Lg, M0rgenstern |
||
![]() |
ChaosCoder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du musst für jede Zelle ein eigenes Bild speichern.
Im Moment machst du das mit einem Bild und frames, das wird aber nicht klappen. Jede Zelle sollte ein TImage zeigen. Am Anfang zeigen alle auf das gleiche Bild, doch wenn du dann die Funktion aufrufst um die Schatten zu berechnen, kopierst du den relevanten Frame der Originalbildes mittels TPixmap.copy() und veränderst diesen Inhalt. So wird es klappen. Viel Spaß noch! |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das heißt ich brauche für jedes Tile ein eigenes Bild?
Wie soll das denn bitte gehen? Also, wie soll ich einem Tile ein Bild zuordnen, und vor allem: Wie soll das speichertechnisch gelöst werden? BTW: Ich hab keine Funktion gefunden um die Farbwerte umzurechnen. Lg, M0rgenstern |
||
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
BlitzMax: [AUSKLAPPEN] Type TColorSpaceHSV Beispiel: BlitzMax: [AUSKLAPPEN] SuperStrict Hatte ich noch auf Lager, musste nur kurz aufbereitet werden. Ich hatte im Codearchiv nur den HSL Teil veröffentlicht: https://www.blitzforum.de/foru...hlight=hsl Vielleicht kannst du damit ja auch was anfangen. |
||
Blessed is the mind too small for doubt |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
RGB zu HSV von Markus2, von Nilium... such dir was passendes aus.
Was das speichern angeht; Das kommt wohl darauf an, was du vor hast und wie groß die Tilemaps sind. Du könntest ja nur den Lichtbereich in ein Bild zeichnen und dieses mit Light- oder shadeblend über die Tilemap rendern lassen. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Erst mal danke an DaysShadow für den Code. Wollte grade anfangen mir sone Funktion selbst zu schriben (wikipedia ser dank^^).
und auch danke an Xeres für die Links^^ Zitat: Du könntest ja nur den Lichtbereich in ein Bild zeichnen und dieses mit Light- oder shadeblend über die Tilemap rendern lassen.
Wie genau meinst du das? Das hab ich schon versucht, also einfach einen hellen Kreis mit lightblend an einer STelle über die Map zu legen, aber das sieht sch.... aus. Außerdem könnte ich so keine Wände mit einbeziehen. Es geht halt drum, dass ich das ganze auf Basis der Mapdaten berechnen möchte. Also Wände sollen das Licht nicht durchlassen. Welche Tiles das sind weiß ich. Wenn ich aber nur einzelne Tiles übeprüfe, dann wird das licht "eckig" (also wenn ich alle Tiles im Lichtradius beleuchte mit color 255,255,255). Das ganze müsste ich also auf die einzelnen Pixel der Tiles umrechnen und prüfen welcher Pixel noch im einzugsbereich liegt. Dafür müsste ich dann aber jedem Tile ein Bild zuordnen um eben dieses mit Writepixel zu bearbeiten. Oder hab ich da was falsch verstanden? Wahrscheinlich geh ich das ganze wieder viel zu kompliziert an. Lg, M0rgenstern |
||
![]() |
ComNik |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also ich kenne deinen weissen Kreis nicht, aber dein Kreis Bild muss so aussehen:
![]() Nicht einfach weiss, sondern ein Farbverlauf von weiss nach Schwarz an den Rändern. Den zeichnest du. Bei mir sah es damals mit ganz normalem Alphablend ganz gut aus, leider kannte ich da Lightblend noch nicht, wenn ich den Code wiederfinde probier ichs aus... Schatten sind ein wenig komplizierter, du musst alle Kanten des Schatten Werfenden Objektes durchgehen, dir immer die vorherige merken, und dann vergleichen ob sie in gegensätzliche Richtungen zeigen bzw einen Winkel Unterschied von > 180 haben. Das lässt sich leicht mit ein bisschen Vektorgeometrie ausrechnen (Senkrechte zur Kante bilden, Skalaprodukt(senkrechte Kante, vorherige Kante) > 90). Wenn ja dann kannst du den Punkt zwischen den Beiden als einen Eckpunkt des Schattens speichern. Wenn du alles durch bist, hast du alle Kantenpunkte des Schattens. Für jeden Kantenpunkt rechnest du jetzt den Entfernungsvektor Punkt - Lichtquelle aus und verlängerst den um einen beliebigen Wert (zum Beispiel die Länge des Distanzvektors, oder einfach Global Sonnenstand:Float oder wasweisich...). Nun musst du (Werbung: z.B mit Avas Gfx Engine ![]() Um den Rechenaufwand zu verkleinern könntest du Kantenpunkte vor der Mainloop berechnen und speichern. Das wäre die grundlegende Vorgehensweise meiner Meinung nach. Weiche Schattenkanten und Selbstbeleuchtung musst du da noch einbauen. Bei vielen Teiles würde es btw Sinn machen nur die Kantenpunkte der Kanten-Tiles zu berechnen... lg ComNik |
||
WIP: Vorx.Engine |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
M0rgenstern hat Folgendes geschrieben: Das hab ich schon versucht, also einfach einen hellen Kreis mit lightblend an einer STelle über die Map zu legen, aber das sieht sch.... aus. Du erstellst ein Bild in der größe, in den der Lichtschein sichtbar sein soll, in das zeichnest du die Pixel anstatt auf die Tiles und zeichnest es, wenn es fertig, ist drüber.
|
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm.
Also, das heißt, einfach so ein Bild wie das was ComNik gezeigt hat und in das soll ich dann die Pixel der Tiles reinschreiben, und das Bild dann an entsprechender Stelle malen? Also, auf das Bild mit Writepixel zeichnen? Das heißt, ich muss die Pixelinformationen des Bildes mit denen der Tiles addieren? Sorry, aber ich hab mit dem Pixelwirrwar manchmal meine Probleme^^... @ComNik: Vielen Dank, aber so gut kenn ich mich dann doch in Vektorrechnung nicht aus. Lg, M0rgenstern |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du erstellst ein neues, leeres Bild in einer passenden größe, um den kompletten Lichtschein ein zu fangen. In dieses Bild zeichnest du die Pixel heller, die beschienen werden, dann hast du in etwa ComNiks bild, nur mit Beachtung der Wände / Schattenwurf.
Aber: Hab's selber noch nicht gemacht, keine Ahnung wie das schlussendlich aussieht. Mach erst ein Test auf freier Fläche, wenn's gut aussieht kümmer' dich um die Beachtung von Wänden! |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Achsooooo...
Ja gut. Jetzt weiß ich was du meinst. Werd ich soäter mal testen. Hört sich ganz gut an. Vielen Dank. Lg, M0rgenstern |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group