diff --git a/lib/body.lua b/lib/body.lua index e9b201c..83bccb6 100644 --- a/lib/body.lua +++ b/lib/body.lua @@ -117,30 +117,22 @@ end -- refresh function body:refresh() if self.shadowType == 'polygon' and self:has_changed() then - local dx, dy, dr, dsx, dsy = self:changes() - if self:position_changed() then - for i = 1, #self.data, 2 do - self.data[i], self.data[i+1] = self.data[i] + dx, self.data[i+1] + dy - end - end - if self:rotation_changed() then - local center = vector(self.x, self.y) - for i = 1, #self.data, 2 do - self.data[i], self.data[i+1] = vector(self.data[i], self.data[i+1]):rotateAround(center, dr):unpack() - end - end - if self:scale_changed() then - for i = 1, #self.data, 2 do - self.data[i] = self.x + (self.data[i] - self.x) + ((self.data[i] - self.x) * dsx) - self.data[i+1] = self.y + (self.data[i+1] - self.y) + ((self.data[i+1] - self.y) * dsy) - end + self.data = {unpack(self.unit_data)} + local center = vector(self.x, self.y) + for i = 1, #self.data, 2 do + local point = vector(self.data[i], self.data[i+1]) + point = point:rotate(self.rotation) + point = point:scale(self.scalex, self.scaley) + self.data[i], self.data[i+1] = (point + center):unpack() end self:commit_changes() end end function body:has_changed() - return self:position_changed() or self:rotation_changed() or self:scale_changed() + return self:position_changed() or + self:rotation_changed() or + self:scale_changed() end function body:position_changed() @@ -157,14 +149,6 @@ function body:scale_changed() self.old_scaley ~= self.scaley end -function body:changes() - return self.x - self.old_x, - self.y - self.old_y, - self.rotation - self.old_rotation, - self.scalex - self.old_scalex, - self.scaley - self.old_scaley -end - function body:commit_changes() self.old_x, self.old_y = self.x, self.y self.old_rotation = self.rotation @@ -331,28 +315,37 @@ end -- set polygon data function body:setPoints(...) - 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] + self.unit_data = {...} + + --calculate l,r,t,b + self.x, self.y, self.width, self.height = self.unit_data[1], self.unit_data[2], 0, 0 + for i = 1, #self.unit_data, 2 do + local px, py = self.unit_data[i], self.unit_data[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 + -- normalize width and height 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 + for i = 1, #self.unit_data, 2 do + self.unit_data[i], self.unit_data[i+1] = self.unit_data[i] - self.x, self.unit_data[i+1] - self.y end self.x = self.x + (self.width * 0.5) self.y = self.y + (self.height * 0.5) local poly_canvas = love.graphics.newCanvas(self.width, self.height) util.drawto(poly_canvas, 0, 0, 1, function() - love.graphics.polygon('fill', points) + love.graphics.polygon('fill', self.unit_data) end) + + --normalize points to be around the center x y + for i = 1, #self.unit_data, 2 do + self.unit_data[i], self.unit_data[i+1] = self.unit_data[i] - self.width * 0.5, self.unit_data[i+1] - self.height * 0.5 + end + self.img = love.graphics.newImage(poly_canvas:getImageData()) self.imgWidth = self.img:getWidth() self.imgHeight = self.img:getHeight() diff --git a/lib/vector.lua b/lib/vector.lua index c2fade3..27b5d0f 100644 --- a/lib/vector.lua +++ b/lib/vector.lua @@ -47,19 +47,13 @@ function vector:unpack() return self.x, self.y end -function vector:rotateAround(origin, angle) - local s = math.sin(angle) - local c = math.cos(angle) - -- translate point back to origin - self.x = self.x - origin.x - self.y = self.y - origin.y - -- rotate point - self.x = (self.x * c - self.y * s) - self.y = (self.x * s + self.y * c) - -- translate point back - self.x = self.x + origin.x - self.y = self.y + origin.y - return self +function vector:rotate(theta) + return new((math.cos(theta) * self.x) - (math.sin(theta) * self.y), + (math.sin(theta) * self.x) + (math.cos(theta) * self.y)) +end + +function vector:scale(sx, sy) + return new(self.x * sx, self.y * sy) end return setmetatable({new = new}, {__call = function(_, ...) return new(...) end})