oakmound/oak

Best way to get whether a button was just pressed?

Closed this issue · 3 comments

The obvious solution is to use oak.IsHeld and check if the duration is less than 1 frame. The problem with that is that it can miss inputs if the game lags.

One solution that should always work is storing the state of the key on the last check. Here's a simplified example:

isJumpHeld := false
for gameRunning { 
	if oak.IsDown(jumpButton) {
		if isJumpHeld == false {
			jump()
		}
		isJumpHeld = true
	}
}

There are a few problems with it:

  1. it is long, and brings the line count up from 3 to 7
  2. you need a variable outside the scope of the loop
  3. it isn't very readable

Is there a better solution?

200sc commented

Have you looked into reacting to key press bindings? It lets you immediately respond once a button has been pressed, and with vectors you can have an enter frame that continually applies a vector of force that is altered by the key press

One use is in the flappy bird example:
https://github.com/oakmound/oak/blob/master/examples/flappy-bird/core.go#L123

f.Bind(func(int, interface{}) int {
	f.Delta.ShiftY(-4)
	return 0
}, key.Down+key.W)

Thanks! On the topic of bindings, is there a way to bind an event so it is triggered once when the entity comes onscreen? I know I could use event.Enter and then unbind the event, but then it wouldn't happen again if it goes offscreen and back on.

200sc commented

Not exactly, there's the concept of phase collision objects in both the mouse and collision trees that could be used for this with a collision space that followed the viewport around, but there's no event triggered without setting one of those collision objects up.