# Calculating dynamic light and shadows in tile based roguelike games – part 3: let there be Bresenham light

Are you enjoying the series about dynamic light and shadows in tile based roguelike games? In step 1 I explained Bresenham algorithm to connect two points in a tile based environment and in step 2 I showed you how to draw circles in a tile based environment. Now it’s time to put things together and make them work properly: what about if Bresenham circles were the field of view and Bresenham lines were rays cast from player eyes to each point along the circumference of the field of view? And what about if any obstacle hitting the ray would stop it? This is what we would get:
Drag the player (the green tile) along the maze, not to overlap red walls, and see how dynamic light works. There is still some more to do. First, we will avoid light to pass through diagonal tiles, but it’s an improvement we’ll see next time. Here is the source code, still uncommented because it’s not finished yet but you should start to understand where I’m going.
```var game;
var gridWidth = 40;
var gridHeight = 40;
var tileSize = 16;
var wallRatio = 3;
var maze = [];

game = new Phaser.Game(640, 640, Phaser.AUTO, "");
game.state.start("PlayGame");
}

var playGame = function(game){};

playGame.prototype = {
},
create: function(){
for(var i = 0; i < gridHeight; i++){
maze[i] = [];
for(var j = 0; j < gridWidth; j++){
maze[i][j] = 0;
if(game.rnd.between(0, wallRatio) == 0){
maze[i][j] = 1;
var wall = game.add.sprite(i * tileSize, j * tileSize, "tile");
wall.tint = 0xff0000;
}
}
}
var startCol = game.rnd.between(0, gridWidth - 1);
var startRow = game.rnd.between(0, gridHeight - 1);
this.playerPosition = game.add.sprite(startCol * tileSize, startRow * tileSize, "tile");
this.playerPosition.tint = 0x00ff00;
this.playerPosition.alpha = 0.5;
this.playerPosition.inputEnabled = true;
this.playerPosition.input.enableDrag();
this.playerPosition.input.boundsRect = new Phaser.Rectangle(0, 0, game.width, game.height);
this.playerPosition.input.enableSnap(tileSize, tileSize, true, true);

},
update: function(){
this.lineGroup.removeAll(true);
this.drawCircle(this.playerPosition.x / tileSize, this.playerPosition.y / tileSize, sightRadius);
},
drawBresenham: function(x0, y0, x1, y1){
var dx = Math.abs(x1 - x0);
var sx = -1;
if(x0 < x1){
var sx = 1
}
var dy = Math.abs(y1 - y0);
var sy = -1;
if(y0 < y1){
var sy = 1;
}
var err = -dy / 2;
if(dx > dy){
err = dx / 2;
}
do{
if(x0 < 0 || y0 < 0 || x0 >= gridWidth || y0 >= gridHeight || maze[x0][y0] == 1){
break;
}
var tile = game.add.sprite(x0 * tileSize, y0 * tileSize, "tile");
var e2 = err;
if(e2 > -dx){
err -= dy;
x0 += sx;
}
if(e2 < dy){
err += dx;
y0 += sy;
}
} while(x0 != x1 || y0 != y1)
},
var y = 0;
var err = 2 - 2 * radius;
do {
this.drawBresenham(this.playerPosition.x / tileSize, this.playerPosition.y / tileSize, (x0 - x), (y0 + y));
this.drawBresenham(this.playerPosition.x / tileSize, this.playerPosition.y / tileSize, (x0 - y), (y0 - x));
this.drawBresenham(this.playerPosition.x / tileSize, this.playerPosition.y / tileSize, (x0 + x), (y0 - y));
this.drawBresenham(this.playerPosition.x / tileSize, this.playerPosition.y / tileSize, (x0 + y), (y0 + x));
y++;
err += y * 2 + 1;
}
if (radius > x || err > y){
x++;
err += x * 2 + 1;
}
} while (x < 0);
}
}
```
Next time I’ll show you how to remove light passing through diagonal walls. How would you do? Feel free to post your suggestions, meanwhile download the source code.
215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 10000000
// 2 Cars
// 2048
// Avoider
// Ballz
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Breakout
// Bricks
// Columns
// CubesOut
// Dots
// DROP'd
// Dudeski
// Eskiv
// Filler
// Fling
// Globe
// HookPod
// Hundreds
// InkTd
// Iromeku
// Lumines
// Magick
// MagOrMin
// Maze
// Memdot
// Nano War
// Nodes
// o:anquan
// Ononmin
// Pacco
// Phyballs
// Platform
// Poker
// Pool
// Poux
// Pudi
// qomp
// Racing
// Renju
// SameGame
// Security
// Sling
// Slingy
// Sokoban
// Splitter
// Sproing
// Stack
// Stairs
// Stringy
// Sudoku
// Tetris
// Threes
// Toony
// Turn
// TwinSpin
// vvvvvv
// Wordle
// Worms
// Yanga
// Zhed
// zNumbers