local Vec3 = require "lib/vec3" local tree = require "lib/tree" local EPSILON = 0.001 --- @class (exact) Camera --- @field position Vec3 --- @field velocity Vec3 --- @field speed number --- @field pixelsPerMeter integer local camera = { 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: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 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.position.x, -self.position.y) end function camera:detach() love.graphics.pop() end --- @return Camera local function new() return setmetatable({}, { __index = camera }) end return { new = new }