Feedback on Input design

Monkey Forums/Monkey Programming/Feedback on Input design

Tibit(Posted 2011) [#1]
I have been working a little on providing a nice input interface, but I'd be interested in some feedback. Here is how it looks atm:

Global Accessors are:
Mouse, Keyboard, Touch

Each of these are of type "InputKey" and have functions for:
IsDown --> Is the Key down right now?
Pressed --> Was the key pressed down during the last frame?
Released --> Was the key released during the last frame?

So your code could look like this:

(In OnUpdate)
If Mouse.Left.Pressed Then Print "Mouse is now down. Pressed at X: "+Mouse.Position.X+", Y: "+Mouse.Position.X
If Mouse.Left.Released Then Print "Mouse is no longer down"
If Keyboard.A.IsDown Then Print "Holding A-Key..."

' Touch is special in that each point also contains a Position
If Touch.Point0.Pressed 
      Print Touch.Point0.Position.X
End

'Touch also contains a MultiKey containing all TouchPoints
If Touch.Any.Pressed
    Print "A touch was detected"
End

' You can also Iterate TouchPoints using Point( index ) and Position(index)
For Local i:Int = 0 To 5
    If Touch.Point(i).IsDown Then Print "Touch point ["+i+"] is now down... X = "+Touch.Position(i).X
Next

' Of course since all this is using Vectors you can do:
' Local distanceToClickFromCar:Float = Touch.Point0.DistanceTo( myCar.Position )
What do you say? Improvement? Ideas?


Samah(Posted 2011) [#2]
I actually made something similar to this and checked it into the diddy project. My version allows you to register for certain events rather than reading in the state of every input type. All the values are stored as public fields to increase performance in Android. It also has no calls to New (apart from array initialisation).

I'll check in an example at some point too.

http://code.google.com/p/diddy/


Tibit(Posted 2011) [#3]
My version allows you to register for certain events rather than reading in the state of every input type.

That sounds smart, I'm looping every key in Update calling KeyDown once on each to determine the state.

Is it like:
Keyboard.RegisterKey.A() ?

And then you can use:
Keyboard.A.Released

Hope you don't mind me asking, but could you explain more on how to optimize for performance in Andriod using public field?


Samah(Posted 2011) [#4]
' In your app class...
Field ic:InputCache

' In OnCreate...
ic = New InputCache
ic.MonitorKey(KEY_A)

' In OnUpdate...
ic.ReadInput()
If ic.keyDown[KEY_A] Then ...
If ic.keyHit[KEY_A] Then ...
If ic.keyReleased[KEY_A] Then ...

For mouse and touch you can use mouseDown/Hit/Released/X/Y, and touchDown/Hit/Released/X/Y.

There are also some fields to keep track of the number of mouse buttons and/or keys pressed at any given time (assuming they are being monitored).

The reason for using public fields rather than accessor methods is because that's one less method call. In this situation it's probably not a big deal, but I think it was worth it.

When designing Android games, it's generally best to limit the number of method calls to keep the call stack small and reduce the time/cycles needed for switching scope. It's minor, but it adds up (especially in CPU-intensive apps like games).

All fields, methods, and functions in Monkey are public by default, unless you specify Private.

In the near future I may add some property calls for the "hit" fields to automatically clear them like in bmx.