From 9fdeb7326c49ac5b6e94e9f5268bca1d3c0667a0 Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Sun, 10 Aug 2025 02:59:11 +0300 Subject: [PATCH] controls rework --- lib/controls.lua | 80 +++++++++++++++++++++++------------------------- main.lua | 2 ++ 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/lib/controls.lua b/lib/controls.lua index 5d3b19e..eba01c6 100644 --- a/lib/controls.lua +++ b/lib/controls.lua @@ -1,3 +1,5 @@ +local utils = require "lib/utils" + --- @alias Device "mouse" | "key" | "pad" --- @param device Device @@ -8,7 +10,8 @@ local function control(device, key) return t end -local keymap = { +local controls = {} +controls.keymap = { cameraMoveUp = control("key", "w"), cameraMoveLeft = control("key", "a"), cameraMoveRight = control("key", "d"), @@ -17,51 +20,44 @@ local keymap = { select = control("mouse", "1") } -local keymapCache = {} +local currentKeys = {} +local cachedKeys = {} -function keymap:isDown(key) - if not keymap[key] then - keymapCache[key] = false - return false +--- polling controls in O(n) +--- should be called at the beginning of every frame +function controls:poll() + for k, v in pairs(self.keymap) do + local type = v.type + local idx = v.key + if type == "key" then + currentKeys[k] = love.keyboard.isDown(idx) + end + + if type == "mouse" then + if not tonumber(idx) then return false end + currentKeys[k] = love.mouse.isDown(tonumber(idx) --[[@as number]]) + end end - - local type = keymap[key].type - local idx = keymap[key].key - if type == "key" then - keymapCache[key] = love.keyboard.isDown(idx) - end - - if type == "mouse" then - if not tonumber(idx) then return false end - keymapCache[key] = love.mouse.isDown(tonumber(idx) --[[@as number]]) - end - - return keymapCache[key] end - ---- Вернуть true, если клавиша нажата в этот тик (ток) и не была нажата в прошлый тик (youtube shorts) -function keymap:isJustPressed(key) - if not keymap[key] then - return false +--- store active controls +--- should be called at the end of every frame +function controls:cache() + for k, v in pairs(currentKeys) do + cachedKeys[k] = v end - - if keymapCache[key] then - return false - end - - local type = keymap[key].type - local idx = keymap[key].key - if type == "key" then - keymapCache[key] = love.keyboard.isDown(idx) - end - - if type == "mouse" then - if not tonumber(idx) then return false end - keymapCache[key] = love.mouse.isDown(tonumber(idx) --[[@as number]]) - end - - return keymapCache[key] end -return keymap +--- check if a control is active +--- @param key string +function controls:isDown(key) + return not not currentKeys[key] +end + +--- check if a control was activated during current logical frame +--- @param key string +function controls:isJustPressed(key) + return currentKeys[key] and not cachedKeys[key] +end + +return controls diff --git a/main.lua b/main.lua index c126c4a..de491ec 100644 --- a/main.lua +++ b/main.lua @@ -16,8 +16,10 @@ function love.load() end function love.update(dt) + Tree.controls:poll() Tree.panning:update(dt) Tree.level:update(dt) + Tree.controls:cache() end function love.draw()