muso96 wrote:Currently would appreciate any feedback, criticisms and such. I will be going through and adding comments describing what is going on now so if nothing makes sense, (which I assume it won't), I'll have that version up soon.
I'm new to programming in general and especially lua and love, so any improvements would be appreciated.
I'll include my test file which I used as a proof of concept of generating shadows. This /should/ help understanding.
Looking at _DynLightV2.love I have some suggestions regarding the code.
I think the shadows code could be generalized using the following algorithm (pseudocode):
Code: Select all
-- light source (point) in world coordinates
local wox, woy = 0, 0
-- cast distance
local cast = 500
local si, ei = 1, #polygon
-- get the last vertex (A) of the polygon
local ls = polygon[ei]
-- (optional) if the vertex is in local coords, transform to world coords
local wax, way = get_world_point(enemy.x, enemy.y, ls.x, ls.y)
-- cast a line from vertex A (wax, way) away from the source (wox, woy)
local wpax, wpay = extend(wox, woy, wax, way, cast)
-- for each edge in the polygon
for i = si, ei do
-- get the "next" vertex (B)
local le = vertices[i]
-- (optional) transform vertex B to world coords
local wbx, wby = get_world_point(enemy.x, enemy.y, le.x, le.y)
-- cast a line from vertex B (wax, way) away from the source (wox, woy)
local wpbx, wpby = extend(wox, woy, wbx, wby, cast)
-- (optional) don't cast front shadows
local dx, dy = wox - wbx, woy - wby
local hx, hy = wbx - wax, wby - way
hx, hy = -hy, hx
local dot = dx*hx + dy*hy
-- don't draw if it's a front shadow
if dot > 0 then
-- draw a polygon:
-- wax, way (vertex A)
-- wpax, wpay (extended vertex A)
-- wpbx, wpby (extended vertex B)
-- wbx, wby (vertex B)
end
-- make vertex B the "last" vertex
wax, way = wbx, wby
wpax, wpay = wpbx, wpby
end
Helper function:
Code: Select all
-- Moves one point (x2, y2) away from another (x, y) by the given distance (dist)
local extend = function(x, y, x2, y2, dist)
local dx, dy = x2 - x, y2 - y
local d = math.sqrt(dx*dx + dy*dy)
d = 1/d*dist
return dx*d + x, dy*d + y
end
-- Transforms local point lx, ly to world coordinates
local get_world_point = function(x, y, lx, ly)
-- translation only (optional: add rotation and scale)
return lx + x, ly + y
end
To use the code above you have to represent the rectangles like so:
Code: Select all
enemy =
{
-- position
x = 0, y = 0,
-- local vertices: top left, top right, bottom right, bottom left
vertices = { { x = 0, y = 0 }, { x = w, y = 0 }, { x = w, y = h }, { x = 0, y = h } }
}
For circle shapes the code becomes even simpler.