[WIP] Shadows

Show off your games, demos and other (playable) creations.
Post Reply
muso96
Prole
Posts: 4
Joined: Mon Sep 08, 2014 1:10 am

[WIP] Shadows

Post by muso96 »

Small game I started for my major software project in year 12. 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.

Title is more placeholder than actual name.

Current bugs/needs improvement
- Shadows are jittery, especially noticeable when enemies are larger, not evident in test.
- Enemies aren't removed once off screen (I couldn't figure out how to implement this)
Attachments
Shadows.love
Correct Game
(207.62 KiB) Downloaded 211 times
_DynLightV2.love
Test File
(4.97 KiB) Downloaded 189 times
Last edited by muso96 on Mon Sep 08, 2014 8:02 am, edited 4 times in total.
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: [WIP] Shadows

Post by rmcode »

Can't move far before getting this:

Code: Select all

Error:
main.lua:39: Need at least three vertices to draw a polygon.
muso96
Prole
Posts: 4
Joined: Mon Sep 08, 2014 1:10 am

Re: [WIP] Shadows

Post by muso96 »

rmcode wrote:Can't move far before getting this:

Code: Select all

Error:
main.lua:39: Need at least three vertices to draw a polygon.
Edit: I accidentally uploaded the wrong file, many apologies. New one up now :)
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: [WIP] Shadows

Post by rmcode »

Ah it looks like a game now too :D Runs really smooth and the shadows look fine.

Not sure if it's a bug or a joke, but on the hardest difficulty there is no light.
muso96
Prole
Posts: 4
Joined: Mon Sep 08, 2014 1:10 am

Re: [WIP] Shadows

Post by muso96 »

rmcode wrote:Ah it looks like a game now too :D Runs really smooth and the shadows look fine.
They look fine only because they're so small, I'll up the size so its more obvious what I meant.
rmcode wrote:Not sure if it's a bug or a joke, but on the hardest difficulty there is no light.
Its intended that way as a joke. It's still possible to see all the cubes if you look hard enough, which is the only reason I left it in.
Attachments
Shadows.love
Bigger Enemies
(207.62 KiB) Downloaded 135 times
User avatar
ivan
Party member
Posts: 1918
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: [WIP] Shadows

Post by ivan »

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.
muso96
Prole
Posts: 4
Joined: Mon Sep 08, 2014 1:10 am

Re: [WIP] Shadows

Post by muso96 »

I'll look more deeply into that code at a later time, but thank you so much. I'd like to continue working with lighting in different ways, so in future I may refer to your method. The biggest issue I have with my method currently is the excessive lists for each enemy. I knew going in that there were simpler ways, but this being my first stab at a game, I'm quite happy just to see that it works. Now that I'm finished I can see that even the list itself has a lot of redundancy, but I'm sure you've noticed by now that efficiency wasn't my aim, as I had roughly 4 days to have something which worked.

I see you referencing the front shadow a bit in the pseudocode. As the _DynLightV2 was simply proof of concept for myself, I was lazy and just drew the polygon from the light source. I did this to save me the trouble of figuring out which vertexes I needed to draw from. So the shadow between the light source and the cube isn't intentional, and you can see its omission in the final version.
User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: [WIP] Shadows

Post by Zilarrezko »

with some magic I determined that when staying on the bottom right, you will definitely survive forever.

Here's a video
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: [WIP] Shadows

Post by rmcode »

One small thing that would make it feel more like a "complete" game would be saving and loading of the highscore.

This is a quick example from one of my games:

Code: Select all

local Handler = {};

-- ------------------------------------------------
-- Public Functions
-- ------------------------------------------------

function Handler.save(profile)
    local file = love.filesystem.newFile('player.sav', 'w');

    file:write('return {\n');
    for key, value in pairs(profile) do
        file:write(string.format('    %s = %s,\n', key, tostring(value)));
    end
    file:write('};');
end

function Handler.load()
    local file = love.filesystem.load('player.sav');

    if file then
        return file();
    end
end

function Handler.delete()
    return love.filesystem.remove('player.sav');
end

return Handler;
Pass in a table and it writes it to a file. Use load to get the same table back.
Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot] and 9 guests