Handling User Input – InputManager

There are two ways to handle user input in Moai – by polling or registering callback functions.  I’m going to focus on polling for now, since that is what I am using.  Moai provides some ways to check for input through the MOAIInputMgr.device and it’s properties.  Depending on your device/host, there will be different properties like MOAIInputMgr.device.touch (touch input on a phone) or MOAIInputMgr.device.mouseLeft (left click).  To use these you could do this:

if MOAIInputMgr.device.mouseLeft:down() then
  print("the left button is down!")
  --do your logic here
end

However, this will fail if your device doesn’t actually have a left mouse button, like on an iPhone.

This would work on both platforms:

if MOAIInputMgr.device.mouseLeft ~= nil and MOAIInputMgr.device.mouseLeft:down() then
  print("the left button is down!")
  --do logic here
end
if MOAIInputMgr.device.touch ~= nil and MOAIInputMgr.device.touch:down() then
  print("touched!")
  --do logic here
end

You will repeat yourself everywhere you want to check input though. To clean this up, I wrote my own class called InputManager that handles these two cases for you. Similar to the SceneManager, this is a static class that anyone can call:

InputManager = {}

--If the input was clicked during the last update
function InputManager.isClickPress()
  if MOAIInputMgr.device.mouseLeft ~= nil and MOAIInputMgr.device.mouseLeft:down () then
    return true
  end
  if MOAIInputMgr.device.touch ~= nil and MOAIInputMgr.device.touch:down () then
    return true
  end
  return false
end

This way you can do something like this, and just check it once:

if InputManger.isClickPress() then
  print("click or touched!")
  --do logic here
end

If your device supports neither left mouse buttons or touch, then this will just return false. There are a bunch of other input cases you can detect:

  • If the mouse/touch has been held down since the last update
  • Where the mouse currently is
  • If a key has been pressed since the last update
  • If a key has been held down since the last update
--If the input was held down
function InputManager.isClickDown()
  if MOAIInputMgr.device.mouseLeft ~= nil and MOAIInputMgr.device.mouseLeft:isDown () then
    return true
  end
  if MOAIInputMgr.device.touch ~= nil and MOAIInputMgr.device.touch:isDown () then
    return true
  end
  return false
end

--only handles mouse location for now.  if you pass in a layer, this will return
--in the layer's coordinate system
function InputManager.getMouseLocation(layer)
  if layer == nil then
    return MOAIInputMgr.device.pointer:getLoc ()
  else
    return layer:wndToWorld(MOAIInputMgr.device.pointer:getLoc ())
  end
end

--Note these keyboard ones dont work with Akuma host

--If the key was pressed during the last update
function InputManager.isKeyPress(key)
  return MOAIInputMgr.device.keyboard:keyDown(key)
end

--If the key is held down
function InputManager.isKeyDown(key)
  return MOAIInputMgr.device.keyboard:keyIsDown(key)
end

Leave a Reply