implemented smooth camera & scrolling w/ mousewheel

This commit is contained in:
Ivan Yuriev 2025-08-02 04:38:38 +03:00
parent 0293409dd9
commit 16ea474526
5 changed files with 39 additions and 22 deletions

View File

@ -1,34 +1,45 @@
local Vec3 = require "lib/vec3"
local tree = require "lib/tree"
local EPSILON = 0.001
--- @class (exact) Camera
--- @field target Vec3
--- @field position Vec3
--- @field velocity Vec3
--- @field speed number
--- @field pixelsPerMeter integer
local camera = {
target = Vec3 {},
position = Vec3 {},
velocity = Vec3 {},
speed = 5,
pixelsPerMeter = 100
}
---@todo Отрефакторить и вынести кнопки управления в controls, не должно быть таких ужасных проверок
function camera:update(dt)
local ws = tree.instance().wheelscroll
if ws.delta:length() > 0 then
local worldDelta = ws.delta * (1 / self.pixelsPerMeter)
self.target = self.target + worldDelta
return
local worldDelta = ws.delta:scale(1 / self.pixelsPerMeter):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)
end
if love.keyboard.isDown("w") then self.target = self.target + Vec3({ 0, -dt * self.speed }) end
if love.keyboard.isDown("a") then self.target = self.target + Vec3({ -dt * self.speed }) end
if love.keyboard.isDown("s") then self.target = self.target + Vec3({ 0, dt * self.speed }) end
if love.keyboard.isDown("d") then self.target = self.target + Vec3({ dt * self.speed }) end
self.position = self.position + self.velocity
self.velocity = self.velocity -
self.velocity * 5 *
dt -- магическая формула, которая означает "экспоненциально замедлиться до нуля"
if self.velocity:length() < EPSILON then self.velocity = Vec3 {} end
end
function camera:attach()
love.graphics.push()
love.graphics.scale(self.pixelsPerMeter)
love.graphics.translate(-self.target.x, -self.target.y)
love.graphics.translate(-self.position.x, -self.position.y)
end
function camera:detach()

0
lib/controls.lua Normal file
View File

View File

@ -16,4 +16,8 @@ function P.generateList(count, generator)
return xs
end
function P.sign(number)
return (number > 0 and 1) or (number == 0 and 0) or -1
end
return P

View File

@ -1,22 +1,22 @@
local Vec3 = require "lib/vec3"
local MIDDLE_BUTTON = 3
--- @class (exact) WheelScroll
--- @field x number
--- @field y number
--- @class WheelScroll
--- @field pos Vec3 | nil
--- @field delta Vec3
local wheelscroll = {
x = 0.0,
y = 0.0,
pos = nil,
delta = Vec3 {}
}
function love.mousepressed(x, y, button)
if button == MIDDLE_BUTTON then
wheelscroll.delta = Vec3 { wheelscroll.x, wheelscroll.y } - Vec3 { x, y }
wheelscroll.x = x
wheelscroll.y = y
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

View File

@ -4,6 +4,7 @@ require "character"
local camera = require 'camera'
local Vec3 = require "lib/vec3"
local tree = require "lib/tree"
function love.conf(t)
t.console = true
@ -11,7 +12,7 @@ end
function love.load()
Camera = camera.new()
Camera.target = Vec3({})
Camera.position = Vec3({})
-- PlayerFaction = Faction
-- Hero1 = Character:create("Petya", 10)
@ -27,6 +28,7 @@ end
function love.update(dt)
Camera:update(dt)
tree.instance().wheelscroll:update(dt)
end
function love.draw()