# Tile based Ligting from a ds_grid

No replies to this topic

### #1 RocketLauncher3G

RocketLauncher3G

Int. Game Programmer

• GMC Member
• 627 posts

Posted 27 March 2012 - 06:51 AM

Hello fellow users of Game Maker,

I built a system which fills a grid with random walls. Walls are currently 0 (so what isn't in the grid, is also a wall) and walk able terrain is 1. This generates random caves, which is exactly what I want. However the light-engine is working me troubles. Currently I'm looping through all the cells in the view, check if there's a wall between the current cell and the player. This is done using the following code:
```var x0, y0, x1, y1, dx, dy, err, sx, sy, e2;
x0 = argument[0];
y0 = argument[1];
x1 = argument[2];
y1 = argument[3];

dx = abs(x1-x0);
dy = abs(y1-y0);

if (x0 < x1) { sx = 1; } else { sx = -1; }
if (y0 < y1) { sy = 1; } else { sy = -1; }
err = dx-dy;

while(x0 != x1 && y0 != y1) {
if (ds_grid_get(grid, x0, y0) == 0) {
return 1;
}
e2 = 2*err;
if (e2 > -dy) {
err = err-dy;
x0 = x0 + sx;
}
if (e2 < dx) {
err = err+dx;
y0 = y0+sy;
}
}
return 0;```

I'm returning 1's and 0's, because these are used in the calculation of the alpha value. This algorithm is based on the (Wiki: ) Bresenhams line algorithm. To me it seems that this code is running fairly fast.

HOWEVER, the code of the Light object is as follows:
```/*
* st = start time
* cntr = counter
* gridS = size of the grid (16px I believe)
* view size = 1280 * 720;
* hrt_time_now() = is a function from the hrt extension, which is able to get the current time more precisely
*/
st = hrt_time_now();
cntr = 0;
for (i=floor((view_xview[0])/gridS)-1; i<floor((view_xview[0]+view_wview[0]+1)/gridS)+1; i+=1) {
for (j = floor((view_yview[0])/gridS)-1; j < floor((view_yview[0]+view_hview[0])); j+=1) {
dist = floor(sqrt(sqr(i-floor(obj_player.x/gridS)) + sqr(j - floor(obj_player.y/gridS))));
if (dist > 10) {
draw_set_alpha(1);
} else {
draw_set_alpha(ds_grid_collision_line(i, j, floor(obj_player.x/gridS), floor(obj_player.y/gridS))*(dist/10))
}
draw_set_color(c_black);
draw_rectangle(i*gridS, j*gridS, (i+1)*gridS, (j+1)*gridS, false);
cntr += 1;
}
}
dt = (hrt_time_now() - st) / hrt_get_resolution();
draw_set_alpha(1);

draw_set_color(c_white);
draw_text(view_xview[0] + 5, view_yview[0] + 5, dt);```

So yeah, the walking and everything is nicely worked out, but the lighting isn't, which is one of the most important features of this game, as you'd be able to see through walls, which shouldn't be the case.

Yet when I run the game, the Frames per Second are rather low, being lower than 1 frame per second (the dt sits nicely 0.46 seconds). What would be a more efficient method of light, which will also be able to support FoV? I could make a ds_grid which stores the light, for each static light I'd run a flood-fill, which uses a counter, setting that value in the grid and the alpha value based on the light. This way you'd get a rather nice looking light.

I suppose that it is rather slow to go through 82*47 = 3854 cells each frame. How would i do something like this which also supports dynamic light (the player) and FoV, without being a mess on the fps?

If you have any questions about my question, I hope to be able to answer them.

Edit:
I tested something, what If I'd raise the gridS (tried 128), would it still raise the performance? Apparently it didn't and it was still way to low to be playable...

Edit 2:
I tested another thing, what If I'd only try to draw the grid? (in another program) Receiving only the alpha from the grid? This was done with 20*15=300 blocks, and it was steady at 30 fps...
What if I'd raise the gridS another time? Even with 1200 blocks, the FPS is 193 (currently raised the room_speed to 9999 )

Edited by RocketLauncher3G, 27 March 2012 - 07:10 AM.

• 0

#### 0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users