UNPKG

rot-js

Version:

A roguelike toolkit in JavaScript

84 lines (68 loc) 3.16 kB
<h2>Global lighting</h2> <p>Lighting module is one of the most convoluted parts of <strong>rot.js</strong>: it is a mix of various concepts introduced in simpler components. <code>ROT.Lighting</code> is used to compute how multiple light sources mix and reflect in a cellular map (using a highly simplified radiosity-like algorithm).</p> <p>To compute a lighting, you need the following:</p> <ul> <li>a <code>ROT.FOV</code> instance, which is used to compute the areas lit by light sources;</li> <li>a <code>lightingCallback</code> which notifies you about the resulting light for a given coordinates;</li> <li>a set of lights, defined by their position (x, y) and color.</li> </ul> <p>If you decide to use a <em>two-pass</em> lighting (more light, more realistic light spread, more computation time), you also need:</p> <ul> <li>a <code>reflectivityCallback</code> which is used to return how much individual map cells reflect incoming light. Please note that wall cells should not reflect any light for the purpose of lighting computation.</li> </ul> <p>Finally, the <code>ROT.Lighting</code> function accepts an optional configuration object as its second argument. This object may contain:</p> <ul> <li><code>range</code> &ndash; maximum range for the most powerful light source</li> <li><code>passes</code> &ndash; number of computation passes (1: no reflectivity used, 2: reflectivity used)</li> <li><code>emissionThreshold</code> &ndash; minimal amount of light at a cell to be re-emited (only for passes>1)</li> </ul> <div class="example"> ROT.RNG.setSeed(12345); var mapData = {}; var lightData = {}; var W = 60; var H = 40; /* build a map */ var map = new ROT.Map.Cellular(W, H).randomize(0.5); function createCallback(x, y, value) { mapData[x+","+y] = value; } for (var i=0; i&lt;4; i++) { map.create(createCallback); } /* prepare a FOV algorithm */ function lightPasses(x, y) { return (mapData[x+","+y] == 1); } var fov = new ROT.FOV.PreciseShadowcasting(lightPasses, {topology:4}); /* prepare a lighting algorithm */ function reflectivity(x, y) { return (mapData[x+","+y] == 1 ? 0.3 : 0); } var lighting = new ROT.Lighting(reflectivity, {range:12, passes:2}); lighting.setFOV(fov); lighting.setLight(12, 12, [240, 240, 30]); lighting.setLight(20, 20, [240, 60, 60]); lighting.setLight(45, 25, [200, 200, 200]); function lightingCallback(x, y, color) { lightData[x+","+y] = color; } lighting.compute(lightingCallback); /* draw the resulting mix of mapData and lightData */ var display = new ROT.Display({fontSize:8, width:W, height:H}); SHOW(display.getContainer()); /* all cells are lit by ambient light; some are also lit by light sources */ var ambientLight = [100, 100, 100]; for (var id in mapData) { var parts = id.split(","); var x = parseInt(parts[0]); var y = parseInt(parts[1]); var baseColor = (mapData[id] ? [100, 100, 100] : [50, 50, 50]); var light = ambientLight; if (id in lightData) { /* add light from our computation */ light = ROT.Color.add(light, lightData[id]); } var finalColor = ROT.Color.multiply(baseColor, light); display.draw(x, y, null, null, ROT.Color.toRGB(finalColor)); } </div>