The logic is rather simple:
1) in love.draw, set all lights to not visible ( setVisible(false) )
2) for each tile to render, see if that tile contains a light. if it does, update its relative position and make it visible
This does not work at all. As soon as the light has been made invisible, it will never appear again. Dumping the contents of the object, you can clearly see the light SHOULD be appearing. It'll look something like this:
Code: Select all
(*) l |
z => 1
visible => true
red => 1
green => 1
blue => 1
glowStrength => 0
glowSize => 0.1
x => 1013
y => 631
angle => 6.2831853071796
direction => 0
range => 110
smooth => 1
is_on_screen => true
Here's a bit of code that determines if a light is going to be drawn or not:
Code: Select all
if (maps[room][layer][roomx][roomy].fn) then -- tile has a light
if (global.state.screen.light) then
local lsdx = rangeXmax - mx + 1 -- tracking which portion of the map is going to be drawn
local lsdy = rangeYmax - my + 1
if not(lights) then lights = { } end
local id = room .. maps[room][layer][roomx][roomy].uid --creating a unique identifier for the light
if not(lights[id]) then -- need to re-create this light
print("creating light in room " .. room .. " at position " .. lsdx .. " " .. lsdy .. " " .. ((spreadX*64)+offsetX-64) .. " " .. ((spreadY*64)+offsetY-64))
local ld = f_ed_get_light(lightsdata[maps[room][layer][roomx][roomy].fn].fn) -- describe the light
local offset_x, offset_y = 0, 0
if ld[7] then offset_x = offset_x + ld[7] end
if ld[8] then offset_y = offset_y + ld[8] end
lights[id] = light:newLight(((spreadX*64)+offsetX-64) + offset_x, ((spreadY*64)+offsetY-64) + offset_y, ld[1], ld[2], ld[3], ld[4])
if ld[5] then lights[id]:setAngle(ld[5]) end
if ld[6] then lights[id]:setDirection(ld[6]) end
else -- light was already made, update position
--print("updating light " .. id .. " in room " .. room .. " at position " .. lsdx .. " " .. lsdy)
local ld = f_ed_get_light(lightsdata[maps[room][layer][roomx][roomy].fn].fn)
local offset_x, offset_y = 0, 0
if ld[7] then offset_x = offset_x + ld[7] end
if ld[8] then offset_y = offset_y + ld[8] end
lights[id]:setVisible(true)
lights[id]:setPosition(((spreadX*64)+offsetX-64) + offset_x, ((spreadY*64)+offsetY-64) + offset_y)
end
If I simply run that code as-is, the lights work, but as soon as you move, many other lights will start to be be created and will never get cleaned up. I tried many, many, many methods to clean them up, and none short of destroying the light worked. Using this method below causes all the lights to go invisible and never return, no matter how many times you make them visible again afterward:
Code: Select all
if (global.state.screen.light) then
for k,v in pairs(lights) do
if (lights[k]) then
lights[k]:setVisible(false)
end
end
end