heroes-of-nerevelon/camera.lua

57 lines
2.0 KiB
Lua

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 }