Merge pull request #1 from tanema/master

Updated stuffs
This commit is contained in:
Paul Liverman 2014-11-10 13:00:47 -08:00
commit d81a656812
12 changed files with 284 additions and 232 deletions

View File

@ -10,12 +10,12 @@ only it has been largely refactored and edited to allow for scaling and proper t
## How to use ## How to use
```lua ```lua
local LightWorld = require "lib/light_world" local LightWorld = require "lib" --the path to where light_world is (in this repo "lib")
-- create light world -- create light world
lightWorld = LightWorld({ lightWorld = LightWorld({
drawBackground = drawBackground, --the callback to use for drawing the background drawBackground = drawBackground, --the callback to use for drawing the background
drawForground = drawForground, --the callback to use for drawing the foreground drawForeground = drawForeground, --the callback to use for drawing the foreground
ambient = {55,55,55}, --the general ambient light in the environment ambient = {55,55,55}, --the general ambient light in the environment
}) })

View File

@ -1,5 +1,5 @@
-- Example: Complex Example -- Example: Complex Example
local LightWorld = require "lib/light_world" local LightWorld = require "lib"
function initScene() function initScene()
-- physic world -- physic world
@ -94,7 +94,7 @@ function love.load()
refractionStrength = 16.0, refractionStrength = 16.0,
reflectionVisibility = 0.75, reflectionVisibility = 0.75,
drawBackground = drawBackground, drawBackground = drawBackground,
drawForground = drawForground drawForeground = drawForeground
}) })
mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange) mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange)
@ -131,9 +131,11 @@ end
function love.update(dt) function love.update(dt)
love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")")
mouseLight:setPosition(love.mouse.getX(), love.mouse.getY(), 16.0 + (math.sin(lightDirection) + 1.0) * 64.0)
mx = love.mouse.getX() mx, my = (love.mouse.getX() - offsetX)/scale, (love.mouse.getY() - offsetY)/scale
my = love.mouse.getY()
mouseLight:setPosition(mx, my, 16.0 + (math.sin(lightDirection) + 1.0) * 64.0)
lightDirection = lightDirection + dt lightDirection = lightDirection + dt
colorAberration = math.max(0.0, colorAberration - dt * 10.0) colorAberration = math.max(0.0, colorAberration - dt * 10.0)
@ -357,7 +359,7 @@ function drawBackground(l,t,w,h)
end end
end end
function drawForground(l,t,w,h) function drawForeground(l,t,w,h)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
for i = 1, phyCnt do for i = 1, phyCnt do
if phyLight[i]:getType() == "polygon" then if phyLight[i]:getType() == "polygon" then

View File

@ -1,18 +1,18 @@
-- Example: Normal map Example -- Example: Normal map Example
local LightWorld = require "lib/light_world" local LightWorld = require "lib"
function love.load() function love.load()
x = 0 x = 0
y = 0 y = 0
scale = 1 scale = 1
-- load images -- load images
image = love.graphics.newImage("gfx/crossColor.jpg") image = love.graphics.newImage("gfx/rock.png")
image_normal = love.graphics.newImage("gfx/crossnrm.jpg") image_normal = love.graphics.newImage("gfx/rock_n.png")
-- create light world -- create light world
lightWorld = LightWorld({ lightWorld = LightWorld({
drawBackground = drawBackground, drawBackground = drawBackground,
drawForground = drawForground, drawForeground = drawForeground,
ambient = {55,55,55}, ambient = {55,55,55},
refractionStrength = 32.0, refractionStrength = 32.0,
reflectionVisibility = 0.75, reflectionVisibility = 0.75,
@ -21,6 +21,7 @@ function love.load()
-- create light -- create light
lightMouse = lightWorld:newLight(0, 0, 160, 160, 160, 300) lightMouse = lightWorld:newLight(0, 0, 160, 160, 160, 300)
lightMouse:setGlowStrength(0.3) lightMouse:setGlowStrength(0.3)
--lightMouse.normalInvert = true
-- create shadow bodys -- create shadow bodys
local w, h = love.graphics.getWidth(), love.graphics.getHeight() local w, h = love.graphics.getWidth(), love.graphics.getHeight()
@ -65,7 +66,7 @@ function drawBackground(l,t,w,h)
love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale) love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale)
end end
function drawForground(l,t,w,h) function drawForeground(l,t,w,h)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
local w, h = love.graphics.getWidth(), love.graphics.getHeight() local w, h = love.graphics.getWidth(), love.graphics.getHeight()
love.graphics.draw(image, w/2-(image:getWidth()/2), h/2-(image:getHeight()/2)) love.graphics.draw(image, w/2-(image:getWidth()/2), h/2-(image:getHeight()/2))

View File

@ -1,5 +1,5 @@
-- Example: Short Example -- Example: Short Example
local LightWorld = require "lib/light_world" local LightWorld = require "lib"
function love.load() function love.load()
testShader = 0 testShader = 0
@ -16,7 +16,7 @@ function love.load()
-- create light world -- create light world
lightWorld = LightWorld({ lightWorld = LightWorld({
drawBackground = drawBackground, drawBackground = drawBackground,
drawForground = drawForground, drawForeground = drawForeground,
ambient = {55,55,55}, ambient = {55,55,55},
refractionStrength = 32.0, refractionStrength = 32.0,
reflectionVisibility = 0.75, reflectionVisibility = 0.75,
@ -77,6 +77,12 @@ function love.keypressed(k)
if colorAberration == 0.0 then if colorAberration == 0.0 then
colorAberration = 3.0 colorAberration = 3.0
end end
elseif k == "f" then
lightWorld:remove(lightMouse)
elseif k == "g" then
lightWorld:remove(circleTest)
elseif k == "h" then
lightWorld:remove(rectangleTest)
end end
end end
@ -110,7 +116,7 @@ function love.update(dt)
lightWorld.post_shader:removeEffect("chromatic_aberration") lightWorld.post_shader:removeEffect("chromatic_aberration")
end end
lightMouse:setPosition(love.mouse.getX()/scale, love.mouse.getY()/scale) lightMouse:setPosition((love.mouse.getX() - x)/scale, (love.mouse.getY() - y)/scale)
end end
function love.draw() function love.draw()
@ -132,7 +138,7 @@ function drawBackground(l,t,w,h)
love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale) love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale)
end end
function drawForground(l,t,w,h) function drawForeground(l,t,w,h)
love.graphics.setColor(63, 255, 127) love.graphics.setColor(63, 255, 127)
local cx, cy = circleTest:getPosition() local cx, cy = circleTest:getPosition()
love.graphics.circle("fill", cx, cy, circleTest:getRadius()) love.graphics.circle("fill", cx, cy, circleTest:getRadius())

BIN
gfx/rock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
gfx/rock_n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -109,6 +109,17 @@ function body:setPosition(x, y)
end end
end end
-- move position
function body:move(x, y)
if x then
self.x = self.x + x
end
if y then
self.y = self.y + y
end
self:refresh()
end
-- get x position -- get x position
function body:getPosition() function body:getPosition()
return self.x, self.y return self.x, self.y
@ -617,10 +628,12 @@ function body:calculateCircleShadow(light)
curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength
curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength
curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength
curShadowGeometry.alpha = self.alpha
curShadowGeometry.red = self.red curShadowGeometry.red = self.red
curShadowGeometry.green = self.green curShadowGeometry.green = self.green
curShadowGeometry.blue = self.blue curShadowGeometry.blue = self.blue
curShadowGeometry.alpha = self.alpha
return curShadowGeometry return curShadowGeometry
else else
return nil return nil

View File

@ -21,21 +21,24 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" local _PACKAGE = string.gsub(...,"%.","/") or ""
local class = require(_PACKAGE..'/class') if string.len(_PACKAGE) > 0 then
local Light = require(_PACKAGE..'/light') _PACKAGE = _PACKAGE .. "/"
local Body = require(_PACKAGE..'/body') end
local util = require(_PACKAGE..'/util') local class = require(_PACKAGE..'class')
local normal_map = require(_PACKAGE..'/normal_map') local Light = require(_PACKAGE..'light')
local PostShader = require(_PACKAGE..'/postshader') local Body = require(_PACKAGE..'body')
require(_PACKAGE..'/postshader') local util = require(_PACKAGE..'util')
local normal_map = require(_PACKAGE..'normal_map')
local PostShader = require(_PACKAGE..'postshader')
require(_PACKAGE..'postshader')
local light_world = class() local light_world = class()
light_world.blurv = love.graphics.newShader(_PACKAGE.."/shaders/blurv.glsl") light_world.blurv = love.graphics.newShader(_PACKAGE.."shaders/blurv.glsl")
light_world.blurh = love.graphics.newShader(_PACKAGE.."/shaders/blurh.glsl") light_world.blurh = love.graphics.newShader(_PACKAGE.."shaders/blurh.glsl")
light_world.refractionShader = love.graphics.newShader(_PACKAGE.."/shaders/refraction.glsl") light_world.refractionShader = love.graphics.newShader(_PACKAGE.."shaders/refraction.glsl")
light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."/shaders/reflection.glsl") light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."shaders/reflection.glsl")
function light_world:init(options) function light_world:init(options)
self.lights = {} self.lights = {}
@ -55,7 +58,7 @@ function light_world:init(options)
self.glowDown = false self.glowDown = false
self.drawBackground = function() end self.drawBackground = function() end
self.drawForground = function() end self.drawForeground = function() end
options = options or {} options = options or {}
for k, v in pairs(options) do self[k] = v end for k, v in pairs(options) do self[k] = v end
@ -99,7 +102,7 @@ function light_world:draw(l,t,s)
util.drawto(self.render_buffer, l, t, s, function() util.drawto(self.render_buffer, l, t, s, function()
self.drawBackground( l,t,w,h,s) self.drawBackground( l,t,w,h,s)
self:drawShadow( l,t,w,h,s) self:drawShadow( l,t,w,h,s)
self.drawForground( l,t,w,h,s) self.drawForeground( l,t,w,h,s)
self:drawMaterial( l,t,w,h,s) self:drawMaterial( l,t,w,h,s)
self:drawShine( l,t,w,h,s) self:drawShine( l,t,w,h,s)
self:drawPixelShadow(l,t,w,h,s) self:drawPixelShadow(l,t,w,h,s)
@ -177,7 +180,7 @@ function light_world:drawPixelShadow(l,t,w,h,s)
self.pixelShadow2:clear() self.pixelShadow2:clear()
for i = 1, #self.lights do for i = 1, #self.lights do
self.lights[i]:drawPixelShadow(l,t,w,h, self.normalMap, self.pixelShadow2) self.lights[i]:drawPixelShadow(l,t,w,h,s, self.normalMap, self.pixelShadow2)
end end
self.pixelShadow:clear(255, 255, 255) self.pixelShadow:clear(255, 255, 255)
@ -185,7 +188,7 @@ function light_world:drawPixelShadow(l,t,w,h,s)
util.drawto(self.pixelShadow, l, t, s, function() util.drawto(self.pixelShadow, l, t, s, function()
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]})
love.graphics.rectangle("fill", l/s,t/s,w/s,h/s) love.graphics.rectangle("fill", -l/s, -t/s, w/s,h/s)
end) end)
util.drawCanvasToCanvas(self.pixelShadow, self.render_buffer, {blendmode = "multiplicative"}) util.drawCanvasToCanvas(self.pixelShadow, self.render_buffer, {blendmode = "multiplicative"})
@ -277,7 +280,7 @@ end
function light_world:clear() function light_world:clear()
light_world:clearLights() light_world:clearLights()
light_world:clearBodys() light_world:clearBodies()
end end
-- clear lights -- clear lights
@ -287,7 +290,7 @@ function light_world:clearLights()
end end
-- clear objects -- clear objects
function light_world:clearBodys() function light_world:clearBodies()
self.body = {} self.body = {}
self.isShadows = false self.isShadows = false
self.isRefraction = false self.isRefraction = false
@ -299,7 +302,7 @@ function light_world:setBackgroundMethod(fn)
end end
function light_world:setForegroundMethod(fn) function light_world:setForegroundMethod(fn)
self.drawForground = fn or function() end self.drawForeground = fn or function() end
end end
-- set ambient color -- set ambient color
@ -340,7 +343,7 @@ end
-- new rectangle -- new rectangle
function light_world:newRectangle(x, y, w, h) function light_world:newRectangle(x, y, w, h)
self.isShadows = true self.isShadows = true
return self:newBody("rectangle", x, y, width, height) return self:newBody("rectangle", x, y, w, h)
end end
-- new circle -- new circle
@ -414,4 +417,25 @@ function light_world:getLight(n)
return self.lights[n] return self.lights[n]
end end
function light_world:remove(to_kill)
if to_kill:is_a(Body) then
for i = 1, #self.body do
if self.body[i] == to_kill then
table.remove(self.body, i)
return true
end
end
elseif to_kill:is_a(Light) then
for i = 1, #self.lights do
if self.lights[i] == to_kill then
table.remove(self.lights, i)
return true
end
end
end
-- failed to find it
return false
end
return light_world return light_world

View File

@ -32,6 +32,8 @@ function light:refresh(w, h)
self.shadow = love.graphics.newCanvas(w, h) self.shadow = love.graphics.newCanvas(w, h)
self.shine = love.graphics.newCanvas(w, h) self.shine = love.graphics.newCanvas(w, h)
self.normalInvertShader:send('screenResolution', {w, h})
self.normalShader:send('screenResolution', {w, h})
end end
-- set position -- set position
@ -47,7 +49,7 @@ end
-- get x -- get x
function light:getPosition() function light:getPosition()
return self.x, self.y return self.x, self.y, self.z
end end
-- set color -- set color
@ -105,15 +107,17 @@ function light:setGlowStrength(strength)
self.glowStrength = strength self.glowStrength = strength
end end
function light:inRange(l,t,w,h) function light:inRange(l,t,w,h,s)
return self.x + self.range > l and local lx, ly, rs = (self.x + l/s) * s, (self.y + t/s) * s, self.range * s
self.x - self.range < (l+w) and
self.y + self.range > t and return (lx + rs) > 0 and
self.y - self.range < (t+h) (lx - rs) < w/s and
(ly + rs) > 0 and
(ly - rs) < h/s
end end
function light:drawShadow(l,t,w,h,s,bodies, canvas) function light:drawShadow(l,t,w,h,s,bodies, canvas)
if self.visible and self:inRange(l,t,w,h) then if self.visible and self:inRange(l,t,w,h,s) then
-- calculate shadows -- calculate shadows
local shadow_geometry = {} local shadow_geometry = {}
for i = 1, #bodies do for i = 1, #bodies do
@ -126,7 +130,8 @@ function light:drawShadow(l,t,w,h,s,bodies, canvas)
-- draw shadow -- draw shadow
self.shadow:clear() self.shadow:clear()
util.drawto(self.shadow, l, t, s, function() util.drawto(self.shadow, l, t, s, function()
self.shader:send("lightPosition", {self.x*s, (h/s - self.y)*s, self.z})
self.shader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z/255.0})
self.shader:send("lightRange", self.range*s) self.shader:send("lightRange", self.range*s)
self.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.shader:send("lightSmooth", self.smooth) self.shader:send("lightSmooth", self.smooth)
@ -164,7 +169,7 @@ function light:drawShadow(l,t,w,h,s,bodies, canvas)
end end
function light:drawShine(l,t,w,h,s,bodies,canvas) function light:drawShine(l,t,w,h,s,bodies,canvas)
if self.visible then if self.visible and self:inRange(l,t,w,h,s) then
--update shine --update shine
self.shine:clear(255, 255, 255) self.shine:clear(255, 255, 255)
util.drawto(self.shine, l, t, s, function() util.drawto(self.shine, l, t, s, function()
@ -179,21 +184,19 @@ function light:drawShine(l,t,w,h,s,bodies,canvas)
end end
end end
function light:drawPixelShadow(l,t,w,h, normalMap, canvas) function light:drawPixelShadow(l,t,w,h,s, normalMap, canvas)
if self.visible then if self.visible and self:inRange(l,t,w,h,s) then
if self.normalInvert then if self.normalInvert then
self.normalInvertShader:send('screenResolution', {w, h})
self.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.normalInvertShader:send('lightPosition',{self.x, lh - self.y, self.z / 255.0}) self.normalInvertShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z / 255.0})
self.normalInvertShader:send('lightRange',{self.range}) self.normalInvertShader:send('lightRange',{self.range})
self.normalInvertShader:send("lightSmooth", self.smooth) self.normalInvertShader:send("lightSmooth", self.smooth)
self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0)
self.normalInvertShader:send("lightDirection", self.direction) self.normalInvertShader:send("lightDirection", self.direction)
util.drawCanvasToCanvas(normalMap, canvas, {shader = self.normalInvertShader}) util.drawCanvasToCanvas(normalMap, canvas, {shader = self.normalInvertShader})
else else
self.normalShader:send('screenResolution', {w, h})
self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.normalShader:send('lightPosition',{self.x, h - self.y, self.z / 255.0}) self.normalShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z / 255.0})
self.normalShader:send('lightRange',{self.range}) self.normalShader:send('lightRange',{self.range})
self.normalShader:send("lightSmooth", self.smooth) self.normalShader:send("lightSmooth", self.smooth)
self.normalShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalShader:send("lightAngle", math.pi - self.angle / 2.0)
@ -203,4 +206,8 @@ function light:drawPixelShadow(l,t,w,h, normalMap, canvas)
end end
end end
function light:setVisible(visible)
self.visible = visible
end
return light return light

View File

@ -1,5 +1,4 @@
extern Image glowImage; extern Image glowImage;
extern float glowTime; extern float glowTime;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {

350
main.lua
View File

@ -7,7 +7,7 @@
-- Updated by Dresenpai -- Updated by Dresenpai
require "lib/postshader" require "lib/postshader"
local LightWorld = require "lib/light_world" local LightWorld = require "lib"
exf = {} exf = {}
exf.current = nil exf.current = nil
@ -15,32 +15,32 @@ exf.current = nil
exf.available = {} exf.available = {}
function love.load() function love.load()
exf.list = List:new() exf.list = List:new()
exf.smallfont = love.graphics.newFont(love._vera_ttf,12) exf.smallfont = love.graphics.newFont(love._vera_ttf,12)
exf.bigfont = love.graphics.newFont(love._vera_ttf, 24) exf.bigfont = love.graphics.newFont(love._vera_ttf, 24)
exf.list.font = exf.smallfont exf.list.font = exf.smallfont
exf.bigball = love.graphics.newImage("gfx/love-big-ball.png") exf.bigball = love.graphics.newImage("gfx/love-big-ball.png")
-- Find available demos. -- Find available demos.
local files = love.filesystem.getDirectoryItems("examples") local files = love.filesystem.getDirectoryItems("examples")
local n = 0 local n = 0
for i, v in ipairs(files) do for i, v in ipairs(files) do
n = n + 1 n = n + 1
table.insert(exf.available, v); table.insert(exf.available, v);
local file = love.filesystem.newFile(v, love.file_read) local file = love.filesystem.newFile(v, love.file_read)
file:open("r") file:open("r")
local contents = love.filesystem.read("examples/" .. v, 100) local contents = love.filesystem.read("examples/" .. v, 100)
local s, e, c = string.find(contents, "Example: ([%a%p ]-)[\r\n]") local s, e, c = string.find(contents, "Example: ([%a%p ]-)[\r\n]")
file:close(file) file:close(file)
if not c then c = "Untitled" end if not c then c = "Untitled" end
local title = exf.getn(n) .. " " .. c .. " (" .. v .. ")" local title = exf.getn(n) .. " " .. c .. " (" .. v .. ")"
exf.list:add(title, v) exf.list:add(title, v)
end end
exf.list:done() exf.list:done()
exf.resume() exf.resume()
end end
function love.update(dt) end function love.update(dt) end
@ -49,7 +49,6 @@ function love.keypressed(k) end
function love.keyreleased(k) end function love.keyreleased(k) end
function love.mousepressed(x, y, b) end function love.mousepressed(x, y, b) end
function love.mousereleased(x, y, b) end function love.mousereleased(x, y, b) end
function exf.empty() end function exf.empty() end
function exf.update(dt) function exf.update(dt)
@ -77,7 +76,7 @@ function exf.drawBackground()
exf.list:draw() exf.list:draw()
end end
function exf.drawForground() function exf.drawForeground()
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5) love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5)
end end
@ -89,32 +88,32 @@ function exf.keyreleased(k)
end end
function exf.mousepressed(x, y, b) function exf.mousepressed(x, y, b)
exf.list:mousepressed(x, y, b) exf.list:mousepressed(x, y, b)
end end
function exf.mousereleased(x, y, b) function exf.mousereleased(x, y, b)
exf.list:mousereleased(x, y, b) exf.list:mousereleased(x, y, b)
end end
function exf.getn(n) function exf.getn(n)
local s = "" local s = ""
n = tonumber(n) n = tonumber(n)
local r = n local r = n
if r <= 0 then error("Example IDs must be bigger than 0. (Got: " .. r .. ")") end if r <= 0 then error("Example IDs must be bigger than 0. (Got: " .. r .. ")") end
if r >= 10000 then error("Example IDs must be less than 10000. (Got: " .. r .. ")") end if r >= 10000 then error("Example IDs must be less than 10000. (Got: " .. r .. ")") end
while r < 1000 do while r < 1000 do
s = s .. "0" s = s .. "0"
r = r * 10 r = r * 10
end end
s = s .. n s = s .. n
return s return s
end end
function exf.intable(t, e) function exf.intable(t, e)
for k, v in ipairs(t) do for k, v in ipairs(t) do
if v == e then return true end if v == e then return true end
end end
return false return false
end end
function exf.start(item, file) function exf.start(item, file)
@ -159,32 +158,30 @@ function exf.start(item, file)
end end
function exf.clear() function exf.clear()
love.graphics.setBackgroundColor(0,0,0) love.graphics.setBackgroundColor(0,0,0)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setLineWidth(1) love.graphics.setLineWidth(1)
love.graphics.setLineStyle("smooth") love.graphics.setLineStyle("smooth")
--love.graphics.setLine(1, "smooth") love.graphics.setBlendMode("alpha")
--love.graphics.setColorMode("replace") love.mouse.setVisible(true)
love.graphics.setBlendMode("alpha")
love.mouse.setVisible(true)
end end
function exf.resume() function exf.resume()
load = nil load = nil
love.update = exf.update love.update = exf.update
love.draw = exf.draw love.draw = exf.draw
love.keypressed = exf.keypressed love.keypressed = exf.keypressed
love.keyreleased = exf.keyreleased love.keyreleased = exf.keyreleased
love.mousepressed = exf.mousepressed love.mousepressed = exf.mousepressed
love.mousereleased = exf.mousereleased love.mousereleased = exf.mousereleased
love.mouse.setVisible(true) love.mouse.setVisible(true)
love.window.setTitle("LOVE Example Browser") love.window.setTitle("LOVE Example Browser")
-- create light world -- create light world
lightWorld = LightWorld({ lightWorld = LightWorld({
drawBackground = exf.drawBackground, drawBackground = exf.drawBackground,
drawForground = exf.drawForground drawForeground = exf.drawForeground
}) })
lightWorld:setAmbientColor(127, 127, 127) lightWorld:setAmbientColor(127, 127, 127)
@ -197,7 +194,7 @@ function exf.resume()
end end
function inside(mx, my, x, y, w, h) function inside(mx, my, x, y, w, h)
return mx >= x and mx <= (x+w) and my >= y and my <= (y+h) return mx >= x and mx <= (x+w) and my >= y and my <= (y+h)
end end
@ -208,29 +205,29 @@ end
List = {} List = {}
function List:new() function List:new()
o = {} o = {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
o.items = {} o.items = {}
o.files = {} o.files = {}
o.x = 50 o.x = 50
o.y = 70 o.y = 70
o.width = 400 o.width = 400
o.height = 500 o.height = 500
o.item_height = 23 o.item_height = 23
o.sum_item_height = 0 o.sum_item_height = 0
o.bar_size = 20 o.bar_size = 20
o.bar_pos = 0 o.bar_pos = 0
o.bar_max_pos = 0 o.bar_max_pos = 0
o.bar_width = 15 o.bar_width = 15
o.bar_lock = nil o.bar_lock = nil
return o return o
end end
function List:add(item, file) function List:add(item, file)
@ -239,161 +236,164 @@ function List:add(item, file)
end end
function List:done() function List:done()
self.items.n = #self.items self.items.n = #self.items
-- Recalc bar size. -- Recalc bar size.
self.bar_pos = 0 self.bar_pos = 0
local num_items = (self.height/self.item_height) local num_items = (self.height/self.item_height)
local ratio = num_items/self.items.n local ratio = num_items/self.items.n
self.bar_size = self.height * ratio self.bar_size = self.height * ratio
self.bar_max_pos = self.height - self.bar_size - 3 self.bar_max_pos = self.height - self.bar_size - 3
-- Calculate height of everything. -- Calculate height of everything.
self.sum_item_height = (self.item_height+1) * self.items.n + 2 self.sum_item_height = (self.item_height+1) * self.items.n + 2
end end
function List:hasBar() function List:hasBar()
return self.sum_item_height > self.height return self.sum_item_height > self.height
end end
function List:getBarRatio() function List:getBarRatio()
return self.bar_pos/self.bar_max_pos return self.bar_pos/self.bar_max_pos
end end
function List:getOffset() function List:getOffset()
local ratio = self.bar_pos/self.bar_max_pos local ratio = self.bar_pos/self.bar_max_pos
return math.floor((self.sum_item_height-self.height)*ratio + 0.5) return math.floor((self.sum_item_height-self.height)*ratio + 0.5)
end end
function List:update(dt) function List:update(dt)
if self.bar_lock then if self.bar_lock then
local dy = math.floor(love.mouse.getY()-self.bar_lock.y+0.5) local dy = math.floor(love.mouse.getY()-self.bar_lock.y+0.5)
self.bar_pos = self.bar_pos + dy self.bar_pos = self.bar_pos + dy
if self.bar_pos < 0 then if self.bar_pos < 0 then
self.bar_pos = 0 self.bar_pos = 0
elseif self.bar_pos > self.bar_max_pos then elseif self.bar_pos > self.bar_max_pos then
self.bar_pos = self.bar_max_pos self.bar_pos = self.bar_max_pos
end end
self.bar_lock.y = love.mouse.getY() self.bar_lock.y = love.mouse.getY()
end
end
end end
function List:mousepressed(mx, my, b) function List:mousepressed(mx, my, b)
if self:hasBar() then if self:hasBar() then
if b == "l" then if b == "l" then
local x, y, w, h = self:getBarRect() local x, y, w, h = self:getBarRect()
if inside(mx, my, x, y, w, h) then if inside(mx, my, x, y, w, h) then
self.bar_lock = { x = mx, y = my } self.bar_lock = { x = mx, y = my }
end end
end end
local per_pixel = (self.sum_item_height-self.height)/self.bar_max_pos local per_pixel = (self.sum_item_height-self.height)/self.bar_max_pos
local bar_pixel_dt = math.floor(((self.item_height)*3)/per_pixel + 0.5) local bar_pixel_dt = math.floor(((self.item_height)*3)/per_pixel + 0.5)
if b == "wd" then if b == "wd" then
self.bar_pos = self.bar_pos + bar_pixel_dt self.bar_pos = self.bar_pos + bar_pixel_dt
if self.bar_pos > self.bar_max_pos then self.bar_pos = self.bar_max_pos end if self.bar_pos > self.bar_max_pos then
elseif b == "wu" then self.bar_pos = self.bar_max_pos
end
elseif b == "wu" then
self.bar_pos = self.bar_pos - bar_pixel_dt self.bar_pos = self.bar_pos - bar_pixel_dt
if self.bar_pos < 0 then self.bar_pos = 0 end if self.bar_pos < 0 then
end self.bar_pos = 0
end end
end
end
if b == "l" and inside(mx, my, self.x+2, self.y+1, self.width-3, self.height-3) then if b == "l" and inside(mx, my, self.x+2, self.y+1, self.width-3, self.height-3) then
local tx, ty = mx-self.x, my + self:getOffset() - self.y local tx, ty = mx-self.x, my + self:getOffset() - self.y
local index = math.floor((ty/self.sum_item_height)*self.items.n) local index = math.floor((ty/self.sum_item_height)*self.items.n)
local i = self.items[index+1] local i = self.items[index+1]
local f = self.files[index+1] local f = self.files[index+1]
if f then if f then
exf.start(i, f) exf.start(i, f)
end
end end
end
end end
function List:mousereleased(x, y, b) function List:mousereleased(x, y, b)
if self:hasBar() then if self:hasBar() then
if b == "l" then if b == "l" then
self.bar_lock = nil self.bar_lock = nil
end end
end end
end end
function List:getBarRect() function List:getBarRect()
return return self.x+self.width+2, self.y+1+self.bar_pos,
self.x+self.width+2, self.y+1+self.bar_pos, self.bar_width-3, self.bar_size
self.bar_width-3, self.bar_size
end end
function List:getItemRect(i) function List:getItemRect(i)
return return self.x+2, self.y+((self.item_height+1)*(i-1)+1)-self:getOffset(),
self.x+2, self.y+((self.item_height+1)*(i-1)+1)-self:getOffset(), self.width-3, self.item_height
self.width-3, self.item_height
end end
function List:draw() function List:draw()
love.graphics.setLineWidth(2) love.graphics.setLineWidth(2)
love.graphics.setLineStyle("rough") love.graphics.setLineStyle("rough")
love.graphics.setFont(self.font) love.graphics.setFont(self.font)
love.graphics.setColor(48, 156, 225) love.graphics.setColor(48, 156, 225)
local mx, my = love.mouse.getPosition() local mx, my = love.mouse.getPosition()
-- Get interval to display. -- Get interval to display.
local start_i = math.floor( self:getOffset()/(self.item_height+1) ) + 1 local start_i = math.floor( self:getOffset()/(self.item_height+1) ) + 1
local end_i = start_i+math.floor( self.height/(self.item_height+1) ) + 1 local end_i = start_i+math.floor( self.height/(self.item_height+1) ) + 1
if end_i > self.items.n then end_i = self.items.n end
if end_i > self.items.n then
end_i = self.items.n
end
love.graphics.setScissor(self.x, self.y, self.width, self.height) love.graphics.setScissor(self.x, self.y, self.width, self.height)
-- Items. -- Items.
for i = start_i,end_i do for i = start_i,end_i do
local x, y, w, h = self:getItemRect(i) local x, y, w, h = self:getItemRect(i)
local hover = inside(mx, my, x, y, w, h) local hover = inside(mx, my, x, y, w, h)
if hover then if hover then
love.graphics.setColor(0, 0, 0, 127) love.graphics.setColor(0, 0, 0, 127)
else else
love.graphics.setColor(0, 0, 0, 63) love.graphics.setColor(0, 0, 0, 63)
end
love.graphics.rectangle("fill", x+1, y+i+1, w-3, h)
if hover then
love.graphics.setColor(255, 255, 255)
else
love.graphics.setColor(255, 255, 255, 127)
end
local e_id = string.sub(self.items[i], 1, 5)
local e_rest = string.sub(self.items[i], 5)
love.graphics.print(e_id, x+10, y+i+6) --Updated y placement -- Used to change position of Example IDs
love.graphics.print(e_rest, x+50, y+i+6) --Updated y placement -- Used to change position of Example Titles
end end
love.graphics.setScissor() love.graphics.rectangle("fill", x+1, y+i+1, w-3, h)
-- Bar. if hover then
if self:hasBar() then love.graphics.setColor(255, 255, 255)
local x, y, w, h = self:getBarRect() else
local hover = inside(mx, my, x, y, w, h) love.graphics.setColor(255, 255, 255, 127)
if hover or self.bar_lock then
love.graphics.setColor(0, 0, 0, 127)
else
love.graphics.setColor(0, 0, 0, 63)
end
love.graphics.rectangle("fill", x, y, w, h)
end end
-- Border. local e_id = string.sub(self.items[i], 1, 5)
love.graphics.setColor(0, 0, 0, 63) local e_rest = string.sub(self.items[i], 5)
love.graphics.rectangle("line", self.x+self.width, self.y, self.bar_width, self.height)
love.graphics.rectangle("line", self.x, self.y, self.width, self.height) love.graphics.print(e_id, x+10, y+i+6) --Updated y placement -- Used to change position of Example IDs
love.graphics.print(e_rest, x+50, y+i+6) --Updated y placement -- Used to change position of Example Titles
end
love.graphics.setScissor()
-- Bar.
if self:hasBar() then
local x, y, w, h = self:getBarRect()
local hover = inside(mx, my, x, y, w, h)
if hover or self.bar_lock then
love.graphics.setColor(0, 0, 0, 127)
else
love.graphics.setColor(0, 0, 0, 63)
end
love.graphics.rectangle("fill", x, y, w, h)
end
-- Border.
love.graphics.setColor(0, 0, 0, 63)
love.graphics.rectangle("line", self.x+self.width, self.y, self.bar_width, self.height)
love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
end end