# How to add lighting to a 2D Tile-based game in JavaFX?

I'm making a 2D roguelike tile-based game with Java and JavaFX. I'm currently working on adding lighting and darkness to the dungeon, but whenever I try running it, it takes a very long time to load, and it eventually gives an out of memory error.

Here is Lighting.java:

package sample;

import static sample.World.worlds;

public class Lighting {
public static void calculateLighting(int wn, int skyLighting) {
Block[][][] world = worlds[wn];
for (int z = 0; z < worlds[Player.cw][0][0].length; z++) {
for (int y = 0; y < worlds[Player.cw][0].length; y++) {
for (int x = 0; x < worlds[Player.cw].length; x++) {
Block b = world[x][y][z];
b.light = skyLighting;
if (b.embID == 1) { //test if a block has a torch attached to it
for (int distance = 0; distance <= 15; distance++) {
for (int x1 = x - distance; x1 < x + distance; x1++) {
for (int y1 = y - distance; y1 < y + distance; y1++) {
for (int z1 = 0; z1 < worlds[Player.cw][0][0].length; z1++) {
try {
world[x1][y1][z1].light += 1;
} catch (ArrayIndexOutOfBoundsException ignored) {

}
}
}
}
}
}
}
}
}
for (int z = 0; z < worlds[Player.cw][0][0].length; z++) {
for (int y = 0; y < worlds[Player.cw][0].length; y++) {
for (int x = 0; x < worlds[Player.cw].length; x++) {
Block b = world[x][y][z];
if (b.light > 15) {
b.light = 15;

//If your number X falls between A and B, and you would like Y to fall between C and D, you can apply the following linear transform:
//Y = (X-A)/(B-A) * (D-C) + C
//https://stackoverflow.com/questions/345187/math-mapping-numbers
//(worlds[Player.cw][x][y][z].light-0)/(15-0) * (1-0.5) + 0.5
if (b.sprite != null) {
b.sprite = ImgManip.darken(b.sprite, (worlds[Player.cw][x][y][z].light) / (15d) * (1 - 0.5) + 0.5);
}
}
}
}
}
}
}

What this is doing is that it first finds torches in the world, and then increases the brightness of each block around it, depending on how far away the torch is. Then, it takes each block's sprite and makes it darker with the darken() method. This is what is causing it to take so long. When I just comment that out, it performs just fine, but the lighting isn't there.

Here is the darken() method:

public static Image darken(Image image, double amount) {
WritableImage writableImage =
new WritableImage(
(int)image.getWidth(),
(int)image.getHeight());
PixelWriter pixelWriter = writableImage.getPixelWriter();

for(int y=0; y<image.getHeight(); y++){
for(int x=0; x<image.getWidth(); x++){

color = color.deriveColor(0,-amount/2d,-amount,0);

pixelWriter.setColor(x, y, color);
}
}
return writableImage;
}
$$`$$