How do you handle input?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
i_love2d_you
Prole
Posts: 6
Joined: Tue Jul 29, 2014 10:15 pm

How do you handle input?

Post by i_love2d_you »

Just wondering how other people set up the input handling for their game. I've run into an interesting situation while trying to implement UI buttons with certain requirements:

1) Buttons are highlighted when moused-over.
2) Clicking a button depresses it, but does not trigger an on_click() event to be called.
3) Releasing a click while on a button that you currently have depressed, triggers an on_click() event to be called.

I had to get a little creative to avoid the following problems:

4) Mousing-over a button while you have another button depressed does not highlight the second button.
5) Releasing a click while off a button that you currently have depressed, does not trigger an on_click() event.

My original solution was very hacky, but I basically made some tables to check for mouse_pressed events and mouse_released events and updated them using Love's built-in callback functions. I then did a lot of testing for hovering and such in my GameObjects.

As a cleaner solution, I'm considering building some kind of InputManager class and just moving as much as I can into there, but I wanted to know what other people did before I started doing that. I realized I couldn't continue cleanly in the way I was writing it because I eventually will need to distinguish between GameObjects that are in front of other GameObjects and having the nearest one take priority. It seems to be the best way to do this is to, as before, use Love's built-in callback functions to update an InputManager, and then somehow pass that information along to my Game class and have the Game class say, "Hey, GameObject #366, you were clicked." In this situation, I would make the InputManager global.

Any insight appreciated.

Thank you.

<3
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: How do you handle input?

Post by rmcode »

I have an InputManager that keeps track of stuff like keyboard and gamepad input. I can have different "control"-mappings (e.g. one for the ingame menu, one for the game, one for the inventory). It is far from perfect and I'll probably need to overhaul it for my next game, but it works fine so far. The good thing about it is, that I don't have to care wether the player uses a gamepad or a keyboard, but instead I only do something like this in my code:

Code: Select all

if InputManager.hasCommand('Foo') then
    ...
end
Personally, I don't think that the InputManager (or any other "global" manager) should handle stuff like testing wether the mouse is over a button or not. Try to keep your classes as decoupled as possible - the less they need to know about each other, the better (of course, sometimes it is much easier to write something hacky and that's okay too). The InputManager should only look at the input that it receives and transform it to something more usable. It shouldn't have to care about what that input does in the game.

I have a button class that allows me to create button objects. Each of these button objects has a draw() and an update() call in which I check wether the mouse is over the button or not. These buttons are then registered in a button manager which handles the updating and drawing of all buttons.

Again, I tried to keep the manager and the buttons separated from each other. The manager doesn't care about how a button looks, as long as it has a draw and an update function. So you could for example have a button that is round (with its own 'mouseover' test) and another one that is rectangular. The ButtonManager will handle both of them without problems.

That's the way I do it at the moment and it has worked fine for me so far.

Are there better ways? Probably. Do I need them yet? Probably not :P
caldur
Prole
Posts: 20
Joined: Tue Mar 13, 2012 3:30 pm

Re: How do you handle input?

Post by caldur »

I'd second rmcode's approach; treat the ui elements as you would do with other game objects and let them be responsible for their own update/draw/collision detection etc. This should work for most game scenarios unless you have some real complicated ui scheme (I am not that into ui programming so forgive me for not being able to think of any concrete example : P)
As for processing input, it will be no different from testing collisions with other objects; just test what the mouse collides with (and with things like space patritioning this could get quite efficient)
User avatar
undef
Party member
Posts: 438
Joined: Mon Jun 10, 2013 3:09 pm
Location: Berlin
Contact:

Re: How do you handle input?

Post by undef »

I work with something like this:

Code: Select all

local keys = {
  escape = "quit"
}
local gamepadButtons = { -- and so on
  

local bindings = {
  quit = love.event.quit
}

function love.keypressed( k )
  local binding = keys[k]
  if binding then return inputHandler( binding ) end
end
function love.joystickpressed( joystick, button )
  -- like above
end

function inputHandler( input )
  local action = bindings[input]
  if action then return action() end
end

That way you have a binding table which contains all of the function you want to have excecuted by input, in this example quiting the game.

I hope this is readable, the forum reformats my spaces bizarrly, therfore I put # instead of spaces below.

Keyboard ------> Keys ---------------------v
Gamepad ------> Buttons ---------------> Bindings ---------> Inputhandler -------> Execution
Mouse ---------> Buttons ----> Coords----^ ###_^
Touch ----------> Coordinates -----------------/

This structure is quite flexible.

Edit:
Depending on the state you're game is in you can just switch out your button tables.
twitter | steam | indieDB

Check out quadrant on Steam!
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 96 guests