-- Input management for keyboard and gamepad (Xbox-style controllers) -- Player slots assigned in join order: first device to press a button becomes P1, etc. InputManager = {} InputManager.__index = InputManager InputManager.ACTIONS = { MOVE_LEFT = 1, MOVE_RIGHT = 2, JUMP = 3, ATTACK = 4, DEFEND = 5, ITEM = 6, INTERACT = 7, PAUSE = 8 } InputManager.KEY_MAP = { [InputManager.ACTIONS.MOVE_LEFT] = {"left"}, [InputManager.ACTIONS.MOVE_RIGHT] = {"right"}, [InputManager.ACTIONS.JUMP] = {"lshift", "space"}, [InputManager.ACTIONS.ATTACK] = {"z"}, [InputManager.ACTIONS.DEFEND] = {"x"}, [InputManager.ACTIONS.ITEM] = {"c"}, [InputManager.ACTIONS.INTERACT] = {"tab"}, [InputManager.ACTIONS.PAUSE] = {"escape"} } InputManager.JOY_MAP = { [InputManager.ACTIONS.MOVE_LEFT] = {"dpleft"}, [InputManager.ACTIONS.MOVE_RIGHT] = {"dpright"}, [InputManager.ACTIONS.JUMP] = {"a"}, [InputManager.ACTIONS.ATTACK] = {"x"}, [InputManager.ACTIONS.DEFEND] = {"b"}, [InputManager.ACTIONS.ITEM] = {"y"}, [InputManager.ACTIONS.INTERACT] = {"select", "lbumper"}, [InputManager.ACTIONS.PAUSE] = {"start"} } InputManager.DEADZONE = 0.25 InputManager.KEYBOARD_SOURCE = 999 function InputManager:new() local self = setmetatable({}, InputManager) self.globalAnySource = nil self.globalAny = false self.players = {} for i = 1, Config.MAX_PLAYERS do local actions = {} for k, v in pairs(InputManager.ACTIONS) do actions[v] = false end self.players[i] = { source = nil, actions = actions, } end return self end function InputManager:setPlayerAction(playerIdx, action, active) self.players[playerIdx].actions[action] = active end function InputManager:getSourcePlayerIdx(source) for i = 1, Config.MAX_PLAYERS do if self.players[i].source == source then return i end end return nil end function InputManager:hasPlayerAnyInput(playerIdx) for action, active in ipairs(self.players[playerIdx].actions) do if active then return true end end return false end function InputManager:isDown(playerIdx, action) return (self.players[playerIdx] and self.players[playerIdx].actions[action]) or false end function InputManager:wasPressed(playerIdx, action) if self.players[playerIdx] and self.players[playerIdx].actions[action] then self:setPlayerAction(playerIdx, action, false) return true end return false end function InputManager:assignPlayerToSource(source) for i = 1, Config.MAX_PLAYERS do if self.players[i].source == nil then self.players[i].source = source return i end end return nil end function InputManager:anyPlayerPressed() for i = 1, Config.MAX_PLAYERS do if self:hasPlayerAnyInput(i) then return true end end return false end function InputManager:getPlayerInputName(playerIdx) local source = (self.players[playerIdx] and self.players[playerIdx].source) if source == InputManager.KEYBOARD_SOURCE then return "KEYBOARD" end return "GAMEPAD" end -- Raw inputs function InputManager:setInput(source, input, active) self.globalAny = active self.globalAnySource = source local inputMap = InputManager.JOY_MAP if source == InputManager.KEYBOARD_SOURCE then inputMap = InputManager.KEY_MAP end playerIdx = self:getSourcePlayerIdx(source) if playerIdx ~= nil then for action, binds in pairs(inputMap) do for _, binding in ipairs(binds) do if binding == input then self:setPlayerAction(playerIdx, action, active) end end end end end function InputManager:pushGamepadAxis(gamepad, axis, value) end