From c0a80da546d7929fa2d22bae471e252662284ed8 Mon Sep 17 00:00:00 2001 From: Tim Anema Date: Tue, 2 Dec 2014 21:26:46 -0500 Subject: [PATCH] made polygons moveable --- README.md | 2 -- examples/complex.lua | 2 +- examples/short.lua | 16 +++++++++- lib/body.lua | 69 ++++++++++++++++++++++++-------------------- 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 64b6dce..7c6b346 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ :todoing -make sure all draw calls check if the object is within range -refactor rectablges to be polygons to reduce code --handle polygons in a moveable way -optimize shadow body calculations and drawing methods - # light_world.lua This is the light modeling done by Priorblue [here](https://bitbucket.org/PriorBlue/love2d-light-and-shadow-engine), diff --git a/examples/complex.lua b/examples/complex.lua index dd1b0e4..f0a9e26 100644 --- a/examples/complex.lua +++ b/examples/complex.lua @@ -195,7 +195,7 @@ function love.update(dt) for i = 1, phyCnt do if phyBody[i] and (phyBody[i]:isAwake() or offsetChanged) then if phyLight[i]:getType() == "polygon" then - phyLight[i]:setPoints(phyBody[i]:getWorldPoints(phyShape[i]:getPoints())) + --phyLight[i]:setPoints(phyBody[i]:getWorldPoints(phyShape[i]:getPoints())) elseif phyLight[i]:getType() == "circle" then phyLight[i]:setPosition(phyBody[i]:getPosition()) elseif phyLight[i]:getType() == "image" then diff --git a/examples/short.lua b/examples/short.lua index 47528d8..5d25f0c 100644 --- a/examples/short.lua +++ b/examples/short.lua @@ -31,6 +31,7 @@ function love.load() -- create shadow bodys circleTest = lightWorld:newCircle(256, 256, 16) rectangleTest = lightWorld:newRectangle(512, 512, 64, 64) + polygonTest = lightWorld:newPolygon(100, 200, 120, 200, 150, 250, 100, 250) imageTest = lightWorld:newImage(image, 64, 64, 24, 6) imageTest:setNormalMap(image_normal) @@ -83,7 +84,7 @@ function love.keypressed(k) lightWorld:remove(lightMouse) elseif k == "g" then lightWorld:remove(circleTest) - elseif k == "h" then + elseif k == "d" then lightWorld:remove(rectangleTest) end end @@ -103,6 +104,18 @@ function love.update(dt) x = x + dt * 200 end + + if love.keyboard.isDown("k") then + polygonTest:move(0, -(dt * 200)) + elseif love.keyboard.isDown("j") then + polygonTest:move(0, (dt * 200)) + end + if love.keyboard.isDown("h") then + polygonTest:move(-(dt * 200), 0) + elseif love.keyboard.isDown("l") then + polygonTest:move((dt * 200), 0) + end + if love.keyboard.isDown("-") then scale = scale - 0.01 elseif love.keyboard.isDown("=") then @@ -141,6 +154,7 @@ function love.draw() local cx, cy = circleTest:getPosition() love.graphics.circle("fill", cx, cy, circleTest:getRadius()) love.graphics.polygon("fill", rectangleTest:getPoints()) + love.graphics.polygon("fill", polygonTest:getPoints()) love.graphics.setColor(255, 255, 255) love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5) end) diff --git a/lib/body.lua b/lib/body.lua index b62cfd9..313c64a 100644 --- a/lib/body.lua +++ b/lib/body.lua @@ -58,34 +58,7 @@ function body:init(id, type, ...) self:setShadowType('rectangle', args[3], args[4]) elseif self.type == "polygon" then - local points = {...} - self.x, self.y, self.width, self.height = points[1], points[2], 0, 0 - for i = 1, #points, 2 do - local px, py = points[i], points[i+1] - if px < self.x then self.x = px end - if py < self.y then self.y = py end - if px > self.width then self.width = px end - if py > self.height then self.height = py end - end - self.width = self.width - self.x - self.height = self.height - self.y - for i = 1, #points, 2 do - points[i], points[i+1] = points[i] - self.x, points[i+1] - self.y - end - - poly_canvas = love.graphics.newCanvas(self.width, self.height) - util.drawto(poly_canvas, 0, 0, 1, function() - love.graphics.polygon('fill', points) - end) - self.img = love.graphics.newImage(poly_canvas:getImageData()) - self.imgWidth = self.img:getWidth() - self.imgHeight = self.img:getHeight() - self.ix = self.imgWidth * 0.5 - self.iy = self.imgHeight * 0.5 - self:generateNormalMapFlat("top") - - - self:setShadowType('polygon', ...) + self:setPoints(...) elseif self.type == "image" then self.img = args[1] self.x = args[2] or 0 @@ -106,6 +79,7 @@ function body:init(id, type, ...) self:initNormal(...) self.reflection = true end + self.old_x, self.old_y = self.x, self.y end function body:initNormal(...) @@ -138,13 +112,19 @@ end -- refresh function body:refresh() - if self.x and self.y and self.width and self.height and self.ox and self.oy then + if self.shadowType == "rectangle" then self.data = { self.x - self.ox, self.y - self.oy, self.x - self.ox + self.width, self.y - self.oy, self.x - self.ox + self.width, self.y - self.oy + self.height, self.x - self.ox, self.y - self.oy + self.height } + elseif self.shadowType == 'polygon' and (self.old_x ~= self.x or self.old_y ~= self.y) then + local dx, dy = self.x - self.old_x, self.y - self.old_y + for i = 1, #self.data, 2 do + self.data[i], self.data[i+1] = self.data[i] + dx, self.data[i+1] + dy + end + self.old_x, self.old_y = self.x, self.y end end @@ -214,7 +194,6 @@ function body:setImageOffset(ix, iy) if ix ~= self.ix or iy ~= self.iy then self.ix = ix self.iy = iy - self:refresh() end end @@ -223,7 +202,6 @@ function body:setNormalOffset(nx, ny) if nx ~= self.nx or ny ~= self.ny then self.nx = nx self.ny = ny - self:refresh() end end @@ -253,7 +231,34 @@ end -- set polygon data function body:setPoints(...) - self.data = {...} + local points = {...} + self.x, self.y, self.width, self.height = points[1], points[2], 0, 0 + for i = 1, #points, 2 do + local px, py = points[i], points[i+1] + if px < self.x then self.x = px end + if py < self.y then self.y = py end + if px > self.width then self.width = px end + if py > self.height then self.height = py end + end + self.width = self.width - self.x + self.height = self.height - self.y + for i = 1, #points, 2 do + points[i], points[i+1] = points[i] - self.x, points[i+1] - self.y + end + + poly_canvas = love.graphics.newCanvas(self.width, self.height) + util.drawto(poly_canvas, 0, 0, 1, function() + love.graphics.polygon('fill', points) + end) + self.img = love.graphics.newImage(poly_canvas:getImageData()) + self.imgWidth = self.img:getWidth() + self.imgHeight = self.img:getHeight() + self.ix = self.imgWidth * 0.5 + self.iy = self.imgHeight * 0.5 + self:generateNormalMapFlat("top") + self.nx, self.ny = 0, 0 + + self:setShadowType('polygon', ...) end -- get polygon data