From 9a9b40748dacbd6535ab658cef960d465fe58db9 Mon Sep 17 00:00:00 2001 From: Neckrat Date: Sun, 3 Aug 2025 23:04:35 +0300 Subject: [PATCH] control refactor Co-authored-by: Ivan Yuriev --- lib/camera.lua | 20 ++++++++++++++------ lib/controls.lua | 36 ++++++++++++++++++++++++++++++++++++ lib/tree.lua | 1 + lib/utils.lua | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/lib/camera.lua b/lib/camera.lua index 7a69072..2ef79a9 100644 --- a/lib/camera.lua +++ b/lib/camera.lua @@ -1,4 +1,5 @@ local Vec3 = require "lib/vec3" +local utils = require "lib/utils" local EPSILON = 0.001 @@ -32,18 +33,25 @@ love.wheelmoved = function(x, y) camera.scale = camera.scale + (camera.scale * 0.1 * y) end ----@todo Отрефакторить и вынести кнопки управления в controls, не должно быть таких ужасных проверок +local controlMap = { + cameraMoveUp = Vec3({ 0, -1 }), + cameraMoveLeft = Vec3({ -1 }), + cameraMoveDown = Vec3({ 0, 1 }), + cameraMoveRight = Vec3({ 1 }) +} + function camera:update(dt) local ps = Tree.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 + elseif utils.any(utils.keys(controlMap), function(el) + return Tree.controls:isDown(el) + end) then 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 + for k, v in pairs(controlMap) do + if Tree.controls:isDown(k) then input = input + v end + end input = input:normalize() or Vec3 {} self.velocity = self.velocity:add(input:scale(self.acceleration):scale(dt)) diff --git a/lib/controls.lua b/lib/controls.lua index e69de29..bd788e2 100644 --- a/lib/controls.lua +++ b/lib/controls.lua @@ -0,0 +1,36 @@ +--- @alias Device "mouse" | "key" | "pad" + +--- @param device Device +--- @param key string +local function control(device, key) + --- @type {type: Device, key: string} + local t = { type = device, key = key } + return t +end + + +local keymap = { + cameraMoveUp = control("key", "w"), + cameraMoveLeft = control("key", "a"), + cameraMoveRight = control("key", "d"), + cameraMoveDown = control("key", "s"), + cameraMoveScroll = control("mouse", "3"), +} + +function keymap:isDown(key) + if not keymap[key] then return false end + local type = keymap[key].type + local idx = keymap[key].key + if type == "key" then + return love.keyboard.isDown(idx) + end + + if type == "mouse" then + if not tonumber(idx) then return false end + return love.mouse.isDown(tonumber(idx) --[[@as number]]) + end + + return false +end + +return keymap diff --git a/lib/tree.lua b/lib/tree.lua index cb1a843..c3480b7 100644 --- a/lib/tree.lua +++ b/lib/tree.lua @@ -6,5 +6,6 @@ Tree = { panning = require "lib/panning", assets = (require "lib/asset_bundle"):load(), + controls = require "lib/controls", level = (require "lib/level"):new() -- для теста у нас только один уровень, который сразу же загружен } diff --git a/lib/utils.lua b/lib/utils.lua index 3e3e4d8..c0700b6 100644 --- a/lib/utils.lua +++ b/lib/utils.lua @@ -23,7 +23,7 @@ function P.sign(number) return (number > 0 and 1) or (number == 0 and 0) or -1 end ---- Applies a side effect for each element of a table +--- Applies a side effect for each value of a table --- @generic T --- @param table {[any] : T} --- @param fn fun(el: T): nil @@ -33,4 +33,40 @@ function P.each(table, fn) end end +--- Returns true if the given function returns true for all the values in the given table. +--- Returns false after the first value which evaluates to false. +--- @generic T +--- @param table {[any] : T} +--- @param fn fun(el: T): boolean +function P.all(table, fn) + for _, value in ipairs(table) do + if not fn(value) then return false end + end + return true +end + +--- Returns true if the given function returns true for any of the values in the given table. +--- @generic T +--- @param table {[any] : T} +--- @param fn fun(el: T): boolean +function P.any(table, fn) + for _, value in ipairs(table) do + if fn(value) then return true end + end + return false +end + +--- Returns the list of keys of the given table. +--- The order of the keys is not guaranteed. +--- @generic T +--- @param t {T: any} +--- @return T[] +function P.keys(t) + local _t = {} + for k, _ in pairs(t) do + table.insert(_t, k) + end + return _t +end + return P