-
Notifications
You must be signed in to change notification settings - Fork 84
Handling Input (v3)
Our starting point for this page is the template from A First Oak Program.
Both mouse and keyboard events, which we'll cover in this page, are reacted to through the event
package. Reacting to events occurs by creating a binding on a CID
or Caller ID from that package, through CID.Bind
, for example. In this page, however, we are not reacting in the context of a particular entity or caller, so we'll use event.GlobalBind
, a function that reacts to all events triggered of the appropriate event name.
both CID.Bind
and event.GlobalBind
take in two arguments: an event.Bindable
and an event string. When the appropriate event, named by the event string, occurs, the bindable will be called.
Bindables have the following function signature:
type Bindable func(CID, interface{}) int
The first argument to a bindable is the integer CID of the entity triggered on, or in the case of event.GlobalBind
, 0. The interface{}
argument is whatever data was included with the triggering event, documented by each event itself. The return value of a bindable is a success or error code. Returning 0 indicates to the event handler to do nothing. Other return results are detailed elsewhere.
The set of mouse events is documented by the mouse
package, in strings.go:
// Mouse events: MousePress, MouseRelease, MouseScrollDown, MouseScrollUp, MouseDrag
// Payload: (*mouse.Event) details on the mouse event
const (
Press = "MousePress"
Release = "MouseRelease"
ScrollDown = "MouseScrollDown"
ScrollUp = "MouseScrollUp"
Click = "MouseClick"
Drag = "MouseDrag"
//
PressOn = Press + "On"
ReleaseOn = Release + "On"
ScrollDownOn = ScrollDown + "On"
ScrollUpOn = ScrollUp + "On"
ClickOn = Click + "On"
DragOn = Drag + "On"
)
We bind to these events in our scene start function:
(mouse.Binding handles casting the payload from a event.Bindable
to a *mouse.Event
.)
//...
func (*scene.Context) {
event.GlobalBind(mouse.Press, mouse.Binding(func(no event.CID, ev *mouse.Event) int {
return 0
})
},
//...
For now, lets just print out the position the mouse was pressed at:
//...
func (*scene.Context) {
event.GlobalBind(mouse.Press, mouse.Binding(func(no event.CID, ev *mouse.Event) int {
fmt.Println("Mouse position:", me.X(), me.Y())
return 0
})
},
//...
Now if we go run core.go
and click on the screen, we'll see print statements in the console informing us where we clicked. For more info about when each mouse event is triggered, see the Mouse Events page.
Oak tracks three keyboard events: key.Down
, key.Up
, and key.Held
. For each of these events you can also bind it for any specific key code. The key
package tracks all keys that can be bound to. When a key event is triggered, the payload data it will send is a key.Event
:
//...
func (*scene.Context) {
event.GlobalBind(key.Down, func(no int, ev interface{}) int {
k := ev.(key.Event)
fmt.Println("Key pressed:", k.Code)
return 0
})
event.GlobalBind(key.Down + key.Spacebar, func(no int, ev interface{}) int {
fmt.Println("Spacebar pressed")
return 0
}, )
},
//...
key.Down
is triggered when a key is first pressed down. If the OS sends this key again because it continues to be held down, key.Held
will be triggered.
key.Up
is triggered when a key is released.
To check how long a key has been held for, use (key.State).IsHeld(key string)
, which will return both whether the key is currently held and for how long it has been held. Similarly, whether a key is currently held down can be checked with (key.State).IsDown(key string)
. The scene context passed into a scene start contains this key state object, but if you are only using a single oak window you can also use oak.IsHeld
or oak.IsDown
.