diff options
author | the lemons <citrons@mondecitronne.com> | 2022-12-22 16:09:25 -0600 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2022-12-22 16:09:25 -0600 |
commit | 477c3126484591b1ebb21df69c77ca2d7524c4f6 (patch) | |
tree | 64eecb08511fd89182cdc52173463ef6062d114d | |
parent | b2501ddc96481dd8f5a5dd6a40e3db785bab6ae3 (diff) |
implement dragging and multiselect
-rw-r--r-- | main.lua | 46 | ||||
-rw-r--r-- | obj.lua | 29 |
2 files changed, 54 insertions, 21 deletions
@@ -11,6 +11,7 @@ local cam = { scale = 1.1, panning = false, } +local drag_start local dragging local selecting local selection @@ -76,13 +77,19 @@ local function draw_world() set_color(1, 1, 1) o:draw() end + set_color(1, 1, 0.5) if selection then - set_color(1, 1, 0.5) for o in pairs(selection) do local x, y = unpack(o.data.pos) box(x - o.hitbox, y - o.hitbox, o.hitbox*2, o.hitbox*2) end end + if selecting then + local x1, y1 = unpack(selecting.p1) + local x2, y2 = unpack(selecting.p2) + local w, h = x2 - x1, y2 - y1 + box(x1, y1, w, h) + end love.graphics.pop() end @@ -111,6 +118,7 @@ end function love.mousepressed(x, y, button) local x, y = view_transform():inverseTransformPoint(x, y) if button == 1 then + drag_start = {x, y} elseif button == 2 then cam.panning = true end @@ -131,10 +139,10 @@ function love.mousereleased(x, y, button) selection = selection or {} selection[clicked] = true end - else - selecting = nil end - dragging = nil + dragging = false + drag_start = nil + selecting = nil elseif button == 2 then cam.panning = false end @@ -142,9 +150,33 @@ end function love.mousemoved(x, y, dx, dy) local x, y = view_transform():inverseTransformPoint(x, y) - if cam.panning then - local scale = view_scale() - dx, dy = dx * scale, dy * scale + local scale = view_scale() + dx, dy = dx * scale, dy * scale + if drag_start then + if not dragging then + local clicked = obj.at(x, y)() + selecting = not clicked + end + if selecting then + local sx, sy = unpack(drag_start) + selecting = { + p1 = {math.min(x, sx), math.min(y, sy)}, + p2 = {math.max(x, sx), math.max(y, sy)}, + } + selection = {} + for o in obj.in_box( + selecting.p1[1], selecting.p1[2], + selecting.p2[1], selecting.p2[2]) do + selection[o] = true + end + if not next(selection) then selection = nil end + elseif selection then + for o in pairs(selection) do + o:set_pos(o.data.pos[1] + dx, o.data.pos[2] + dy) + end + end + dragging = true + elseif cam.panning then cam.x = cam.x - dx cam.y = cam.y - dy end @@ -96,11 +96,20 @@ function obj:init(...) return self:overload("init", ...) end +function obj:set_pos(x, y) + self.data.pos[1] = x + self.data.pos[2] = y + local chunk = world.chunk(unpack(self.data.pos)) + if chunk ~= self.chunk then + self.chunk.objects[self.id] = nil + chunk.objects[self.id] = self + self.chunk = chunk + end +end + function obj:tick(...) local vx, vy = unpack(self.data.vel) - self.data.pos[1] = self.data.pos[1] + vx - self.data.pos[2] = self.data.pos[2] + vy - + self:set_pos(self.data.pos[1] + vx, self.data.pos[2] + vy) self.data.angle = (self.data.angle or 0) + self.data.avel / pi if self.hitbox then @@ -117,10 +126,9 @@ function obj:tick(...) self:collision(o, angle) o:collision(self, pi - angle) -- reposition self outside of collided object - self.data.pos[1] = - self.data.pos[1] - math.cos(angle) * dist + dx - self.data.pos[2] = - self.data.pos[2] - math.sin(angle) * dist + dy + self:set_pos( + self.data.pos[1] - math.cos(angle) * dist + dx, + self.data.pos[2] - math.sin(angle) * dist + dy) self:collision_exit(o, angle) o:collision_exit(self, pi - angle) end @@ -129,13 +137,6 @@ function obj:tick(...) end self:overload("tick", ...) - - local chunk = world.chunk(unpack(self.data.pos)) - if chunk ~= self.chunk then - self.chunk.objects[self.id] = nil - chunk.objects[self.id] = self - self.chunk = chunk - end end function obj:draw(...) |