# Lichtupdate in tile-basiertem Spiel



## JavaKiwi (25. Dez 2013)

Heyo! 

Ich möchte die Tiles meines Levels mithilfe von Lichtlevels (Abstufungen) beleuchten.
Jedem Tile wird also ein float zugewiesen, der das Lichtlevel darstellt (zwischen 0 und 1).

Doch wie kann ich für jedes Tile das Lichtlevel errechnen?
Klar, die normalen Luft-Tiles "leuchten" sozusagen mit höchstem Lichtlevel.
Doch wie errechnet sich jetzt zum Beispiel für ein zwei Blöcke tiefer liegendes Tile ein Lichtlevel von 0.8f?
Oder für ein viel tiefer liegendes Tile ein Lichtlevel von 0.0f?

Ich danke euch vielmals für eure Hilfe! Ihr seid eine klasse Community, die mir oft geholfen hat!


----------



## jemandzehage (26. Dez 2013)

Moin,

Wenn ich deinen Text so lese weiß ich weder wie dein Spiel aussieht noch was genau du mit übereinanderliegenden Tiles meinst. Deshalb hier mal zwei Lösungen (je nachdem wie das gemeint war):

1) du meintest Isometrische Tiles und möchtest die in Abhängigkeit von der zeichentiefe beleuchten. Dann gibts du jeder Ebene einfach einen Tiefen wert und rechnest den in einen normierst Weet zwischen 0 und 1 um. Ich vermute dass das nicht die Lösung ist nach der du gesucht hast, also nächster Versuch:

2) Du baust in entfernter Form etwas ähnliches wie minecraft und möchtest, dass an der Oberfläche alles beleuchtet ist, es in Höhlen aber dunkler wird. Und dass du z.B. fakeln aufstellen kannst um einzelne Gebiete zu erhellen. Das Stichwort dazu lautet: "ambient occlusion". Wenn du google ein bisschen befragst, findest du ganz gute Anleitungen wie das geht. (Wie du wahrscheinlich schon vermutet hast ist das Problem gar nicht mal so trivial und erfordert ein Tutorial oder ähnliches). Dazu hat glaube ich sogar Notch mal einen Artikel verfasst. 

Ich hoffe ich könnte helfen. 

Grüße


----------



## JavaKiwi (26. Dez 2013)

Der Begriff "Tile" ist natürlich zu ungenau. Es sind 2D-Tiles, wie bei Terraria.
Ich möchte also, dass in der Erde liegende Tiles dunkler oder schwarz sind. Die Tiles an der Oberfläche sollen hell sein, d.h. von Tageslicht beleuchtet.

Gibt es irgendeine Routine, die das Lichtlevel für alle Tiles berechnen kann, wenn die "leuchtenden" Tiles (z.B. Fackeln) gegeben sind?


----------



## Zettelkasten (26. Dez 2013)

Du wirst wohl nicht um "Licht-Updates" oder ähnliches kommen.
Ein Licht-Update wird dann aufgerufen, wenn sich der Lichtwert eines Tiles ändert, z.B. eine Fackel plaziert wird.
Dann berechnest du das Licht für das Tile neu, z.B. so:
Du checkst alle 4 Lichtlevel von den umliegenden Tiles, nimmst den größten Wert und substrahierst z.B. 
	
	
	
	





```
0.1
```
. Nur wenn das neuberechnete Lichlevel anders ist als das alte, sagst du den umliegenden 4 Tiles, sie sollen ein Licht-Update durchführen.

Ach ja und beim Laden der Welt musst du dann wohl für alles ein Licht-Update durchführen. (oder du speicherst die Licht-Level in der Spieldatei)


----------



## JavaKiwi (29. Dez 2013)

Ich habe dafür einen rekursiven Ansatz gewählt:


```
private void updateLight(int x, int y, float lastLight)
	{
		float newLight;

		if(blocks[x][y] == Tile.EMPTY_BLOCK.getID())
		{
			newLight = lastLight - Tile.getLightBlockingFactor(backgrounds[x][y]) * Level.LIGHT_NUANCE;
		}
		else
		{
			newLight = lastLight - Tile.getLightBlockingFactor(blocks[x][y]) * Level.LIGHT_NUANCE;
		}

		if(newLight <= lights[x][y])
		{
			return;
		}

		lights[x][y] = newLight;

		updateLight(x + 1, y, newLight);
		updateLight(x, y + 1, newLight);
		updateLight(x - 1, y, newLight);
		updateLight(x, y - 1, newLight);
	}
```

Das Problem bei der Geschichte ist, dass das zu einem massiven StackOverflowError führt. 
Für eine Welt in der Größe von 19.200 x 2.560 Tiles (300 x 40 Chunks à 64 x 64 Tiles) ist das rekursiv einfach nicht möglich. 

Irgendwelche Lösungsvorschläge?


----------

