vedi0boy
vedi0boy

Reputation: 1040

Making a circle in an array (Tile based game light map)

I am making a tiled based game in java and I want to make a light map.

I am having some issues. I have the lightmap array that has lights placed on it that affect the array. Lights emit in a circle shape. It seems ok so far but its not exactly what I wanted.

Here is my code so far:

for(float i = 0; i < strength + 1; i++){
    for(double u = 0.0f; u < 360; u += 0.5){
        double angle = u * Math.PI / 180;
        int x2 = (int)(x + i * Math.cos(angle));
        int y2 = (int)(y + i * Math.sin(angle));
        if(map[y2][x2] > 1 - 1 / i)
            map[y2][x2] = 1 - 1 / i;
    }
}

Result:

Result

As you can see in the result, it seems as though the light is expanding too much on the bottom left side (red x's). How do I fix this?

Background info:

Strength:
The radius of how far the light reaches. This also determines how bright the light will be at each tile of the array.

The Array "map" is a 2D float array. The engine I am using uses float values for the alpha channel. The range is 0 (completely transparent) to 1 (completely opaque).

Solution (Thanks to Gene):

for(int x2 = -strength; x2 <= strength; x2++){
    for (int y2 = -strength; y2 <= strength; y2++) {
        double r = Math.sqrt(x2 * x2 + y2 * y2);
        double inv_rad = r <= strength + 1 ? 1 / r : 0;
        if(map[y + y2][x + x2] > 1 - (float) inv_rad)
            map[y + y2][x + x2] = 1 - (float) inv_rad;
    }
}

Upvotes: 1

Views: 462

Answers (2)

Ian Evenhuis
Ian Evenhuis

Reputation: 9

when i try to add this to my project i only get o.o back the values i entered where 500, 500,50

private float map[][] = new float[1000][1000];

 public void test(int x, int y, float strength){
    public void addLight(int x,int y,int strength ){
    for(int x2 = -strength; x2 <= strength; x2++){
        for (int y2 = -strength; y2 <= strength; y2++) {
            double r = Math.sqrt(x2 * x2 + y2 * y2);
            double inv_rad = r <= strength + 1 ? 1 / r : 0;
            if(map[y + y2][x + x2] > 1 - (float) inv_rad)
                map[y + y2][x + x2] = 1 - (float) inv_rad;
            System.out.println(map[y + y2][x + x2]);
        }
    }
}

Upvotes: 0

Gene
Gene

Reputation: 46960

Your algorithm suffers from integer truncation of the map indicies. Try it the other away around. Compute the distance from each pixel in a square surrounding the center to the center. From this distance calculate what the intensity ought to be. It will be something like this:

for (x = -R; x <= R; x++)
  for (y = -R; y <= R; y++) {
    double r = Math.sqrt(x * x + y * y);
    double inv_rad = r <= R ? 1 / r : 0; // truncate outside radius R
    map[yc + y][xc + x] = 1 - inv_rad;
  }

Here xc and yc are the integer center coordinates. R is the half-size of the box around the center.

Upvotes: 3

Related Questions