From bee71fe254767c7eab5bbdfca9cb7513468867bc Mon Sep 17 00:00:00 2001 From: Ivan Yuriev Date: Sat, 2 Aug 2025 23:58:59 +0300 Subject: [PATCH] - improved camera smoothness - implemented camera zoom --- camera.lua | 36 +++++++++++++++++++++++++----------- lib/panning.lua | 22 ++++++++++++++++++++++ lib/tree.lua | 2 +- lib/wheelscroll.lua | 22 ---------------------- main.lua | 2 +- 5 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 lib/panning.lua delete mode 100644 lib/wheelscroll.lua diff --git a/camera.lua b/camera.lua index 7a7b952..7ef7bca 100644 --- a/camera.lua +++ b/camera.lua @@ -3,7 +3,7 @@ local tree = require "lib/tree" local EPSILON = 0.001 ---- @class (exact) Camera +--- @class Camera --- @field position Vec3 --- @field velocity Vec3 --- @field speed number @@ -11,22 +11,34 @@ local EPSILON = 0.001 local camera = { position = Vec3 {}, velocity = Vec3 {}, + acceleration = 0.2, speed = 5, - pixelsPerMeter = 100 + pixelsPerMeter = 100, + scale = 1 } +love.wheelmoved = function(x, y) + if camera.scale > 2 and y > 0 then return end; + if camera.scale < 0.5 and y < 0 then return end; + camera.scale = camera.scale + 0.1 * y +end + ---@todo Отрефакторить и вынести кнопки управления в controls, не должно быть таких ужасных проверок function camera:update(dt) - local ws = tree.instance().wheelscroll - if ws.delta:length() > 0 then - local worldDelta = ws.delta:scale(1 / self.pixelsPerMeter):scale(dt):scale(self.speed) + local ps = tree.instance().panning + if ps.delta:length() > 0 then + local worldDelta = ps.delta:scale(1 / (self.pixelsPerMeter * self.scale)):scale(dt):scale(self.speed) self.velocity = self.velocity + worldDelta elseif love.keyboard.isDown("w") or love.keyboard.isDown("a") or love.keyboard.isDown("s") or love.keyboard.isDown("d") then - if love.keyboard.isDown("w") then self.velocity = self.velocity + Vec3({ 0, -1 }) end - if love.keyboard.isDown("a") then self.velocity = self.velocity + Vec3({ -1 }) end - if love.keyboard.isDown("s") then self.velocity = self.velocity + Vec3({ 0, 1 }) end - if love.keyboard.isDown("d") then self.velocity = self.velocity + Vec3({ 1 }) end - self.velocity = (self.velocity:normalize() or Vec3 {}):scale(self.speed):scale(dt) + local input = Vec3 {} + if love.keyboard.isDown("w") then input = input + Vec3({ 0, -1 }) end + if love.keyboard.isDown("a") then input = input + Vec3({ -1 }) end + if love.keyboard.isDown("s") then input = input + Vec3({ 0, 1 }) end + if love.keyboard.isDown("d") then input = input + Vec3({ 1 }) end + input = input:normalize() or Vec3 {} + + self.velocity = self.velocity:add(input:scale(self.acceleration):scale(dt)) + if self.velocity:length() > self.speed then self.velocity = self.velocity:normalize() * self.speed end end self.position = self.position + self.velocity @@ -37,8 +49,10 @@ function camera:update(dt) end function camera:attach() + local wc, hc = love.graphics.getWidth() / 2, love.graphics.getHeight() / 2 love.graphics.push() - love.graphics.scale(self.pixelsPerMeter) + love.graphics.translate(wc, hc) + love.graphics.scale(self.pixelsPerMeter * self.scale) love.graphics.translate(-self.position.x, -self.position.y) end diff --git a/lib/panning.lua b/lib/panning.lua new file mode 100644 index 0000000..29e16cd --- /dev/null +++ b/lib/panning.lua @@ -0,0 +1,22 @@ +local Vec3 = require "lib/vec3" + +--- @class PanningState +--- @field pos Vec3 | nil +--- @field delta Vec3 +local panning = { + pos = nil, + delta = Vec3 {}, +} + +function panning:update(dt) + if love.mouse.isDown(3) then + local mouseX, mouseY = love.mouse.getPosition() + if (panning.pos) then panning.delta = panning.pos - Vec3 { mouseX, mouseY } end + panning.pos = Vec3 { mouseX, mouseY } + return + end + panning.pos = nil + panning.delta = Vec3 {} +end + +return panning diff --git a/lib/tree.lua b/lib/tree.lua index dd2a2b5..74f74cb 100644 --- a/lib/tree.lua +++ b/lib/tree.lua @@ -7,7 +7,7 @@ local tree local function instance() tree = tree or { - wheelscroll = require "lib/wheelscroll" + panning = require "lib/panning" } return tree end diff --git a/lib/wheelscroll.lua b/lib/wheelscroll.lua deleted file mode 100644 index 978b153..0000000 --- a/lib/wheelscroll.lua +++ /dev/null @@ -1,22 +0,0 @@ -local Vec3 = require "lib/vec3" - ---- @class WheelScroll ---- @field pos Vec3 | nil ---- @field delta Vec3 -local wheelscroll = { - pos = nil, - delta = Vec3 {} -} - -function wheelscroll:update(dt) - if love.mouse.isDown(3) then - local mouseX, mouseY = love.mouse.getPosition() - if (wheelscroll.pos) then wheelscroll.delta = wheelscroll.pos - Vec3 { mouseX, mouseY } end - wheelscroll.pos = Vec3 { mouseX, mouseY } - return - end - wheelscroll.pos = nil - wheelscroll.delta = Vec3 {} -end - -return wheelscroll diff --git a/main.lua b/main.lua index 5693c50..6338f84 100644 --- a/main.lua +++ b/main.lua @@ -28,7 +28,7 @@ end function love.update(dt) Camera:update(dt) - tree.instance().wheelscroll:update(dt) + tree.instance().panning:update(dt) end function love.draw()