Precise Shadowcasting demo
by Ondřej Žára
HTML
<script src="https://raw.github.com/ondras/rot.js/master/rot.js"></script>
Click to toggle cells, move to show FOV. Topology: <select id="topology">
<option value="4">4</option>
<option value="8" selected="selected">8</option>
</select><br/>
<canvas id="canvas"></canvas><br/>
FOV: <span id="fov"></span>ms, draw: <span id="draw"></span>ms
CSS
#canvas { border: 1px solid black; cursor: crosshair; }
JavaScript
var CELL = [12, 12];
var SIZE = [40, 30];
var COLOR_WALL = [40, 40, 40];
var COLOR_FLOOR = [180, 180, 180];
var COLOR_LIGHT = [255, 255, 0];
var CTX = document.querySelector("#canvas").getContext("2d");
CTX.canvas.width = CELL[0]*SIZE[0];
CTX.canvas.height = CELL[1]*SIZE[1];
CTX.fillStyle = "black";
var walls = {};
var lights = {};
var lightPassesCallback = function(x, y) {
var key = x+","+y;
return (!(key in walls));
}
var toggle = function(x, y) {
var key = x+","+y;
if (walls[key]) {
delete walls[key];
} else {
walls[key] = 1;
}
}
var redraw = function() {
var t1 = Date.now();
CTX.clearRect(0, 0, CTX.canvas.width, CTX.canvas.height);
for (var x=0;x<SIZE[0];x++) {
for (var y=0;y<SIZE[1];y++) {
var key = x+","+y;
var light = lights[key];
var base = (walls[key] ? COLOR_WALL : COLOR_FLOOR);
var c = [];
for (var i=0;i<3;i++) {
var factor = 0.5;
if (light) { factor += COLOR_LIGHT[i]*light/255; }
c[i] = Math.min(255, Math.round(base[i]*factor));
}
CTX.fillStyle = "rgb("+c.join(",")+")";
CTX.fillRect(x*CELL[0], y*CELL[1], CELL[0], CELL[1]);
}
}
var t2 = Date.now();
document.querySelector("#draw").innerHTML = t2-t1;
}
var updateVisibility = function(x, y) {
lights = {};
var topology = parseInt(document.querySelector("#topology").value);
var fov = new ROT.FOV.PreciseShadowcasting(lightPassesCallback, {topology:topology});
var t1 = Date.now();
fov.compute(x, y, 15, function(x, y, r, vis) {
lights[x+","+y] = vis*(1-(r+1)/15);
});
var t2 = Date.now();
document.querySelector("#fov").innerHTML = t2-t1;
redraw();
}
var getCoords = function(e) {
var x = e.clientX - CTX.canvas.offsetLeft - CTX.canvas.clientLeft;
var y = e.clientY - CTX.canvas.offsetTop - CTX.canvas.clientTop
return...