Field of View (FOV) computation
FOV algorithms return a set coordinates, visible from a starting place. Computing these works in the same fashion
as Map generators do: using a user-supplied callback function. This time, however, user has to supply two callbacks:
- Input callback, passed as a constructor argument, which provides visiblity information;
- Output callback, passed as an argument to the
compute
method, which receives FOV data.
Input callback is called by the FOV algorithm to retrieve visibility information for a given coordinate pair. This callback must return true
(light passes)
or false
(light does not pass). Output callback is called with these arguments: x
, y
, r
and visibility
:
the meaning is that "the place at [x,y] is visible with a distance of r". The last argument specifies the amount of visibility (0..1).
Currently there are these FOV algorithms available:
- Precise Shadowcasting
- Recursive Shadowcasting
Precise shadowcasting
Precise shadowcasting FOV computations currently support 360-degree viewsheds and are initiated by calling the compute
method with the following arguments:
x
y
r
– maximum visibility radius
callback
– output callback function
ROT.RNG.setSeed(12345);
var W = 80;
var H = 30;
var display = new ROT.Display({fontSize:12, width:W, height:H});
SHOW(display.getContainer());
/* create a map */
var data = {};
new ROT.Map.Uniform(W, H).create(function(x, y, type) {
data[x+","+y] = type;
display.DEBUG(x, y, type);
});
/* input callback */
function lightPasses(x, y) {
var key = x+","+y;
if (key in data) { return (data[key] == 0); }
return false;
}
var fov = new ROT.FOV.PreciseShadowcasting(lightPasses);
/* output callback */
fov.compute(50, 22, 10, function(x, y, r, visibility) {
var ch = (r ? "" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
Recursive shadowcasting
Recursive shadowcasting FOV computations are initiated by calling one of its three compute
methods. It currently supports viewing an entire 360-degree circle (compute
), as well as half-circles (compute180
) and quadrants (compute90
). While the compute
method behaves the same as with Precise and Discrete shadowcasting, the two partial views require an additional argument noting the direction to look in:
x
y
r
– maximum visibility radius
dir
– direction to face in from ROT.DIRS[8]
callback
– output callback function
ROT.RNG.setSeed(12345);
var W = 80;
var H = 30;
DIR_NORTH = 0;
DIR_WEST = 6;
var display = new ROT.Display({fontSize:12, width:W, height:H});
SHOW(display.getContainer());
/* create a map */
var data = {};
new ROT.Map.Uniform(W, H).create(function(x, y, type) {
data[x+","+y] = type;
display.DEBUG(x, y, type);
});
/* input callback */
function lightPasses(x, y) {
var key = x+","+y;
if (key in data) { return (data[key] == 0); }
return false;
}
var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);
/* output callback for mob with bad vision */
fov.compute90(50, 22, 10, DIR_WEST, function(x, y, r, visibility) {
var ch = (r ? "1" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
/* output callback for second mob with better vision */
fov.compute180(57, 14, 10, DIR_NORTH, function(x, y, r, visibility) {
var ch = (r ? "2" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});
/* output callback for third mob with supernatural vision */
fov.compute(65, 5, 10, function(x, y, r, visibility) {
var ch = (r ? "3" : "@");
var color = (data[x+","+y] ? "#aa0": "#660");
display.draw(x, y, ch, "#fff", color);
});