mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/ui: bug fix: input state should be reset for each tick, not frame
Before this change, input states were reset for each frame. When FPS is bigger than TPS, the input state was reset more often than expected and then some inputs were missing. This change fixes the issue by resetting input states not for each frame but for each tick. This change also updates some comments of the input API. Updates #2496 Closes #2501
This commit is contained in:
parent
d80f1112ed
commit
59295cc85f
8
input.go
8
input.go
@ -49,7 +49,7 @@ func InputChars() []rune {
|
||||
|
||||
// IsKeyPressed returns a boolean indicating whether key is pressed.
|
||||
//
|
||||
// If you want to know whether the key started being pressed in the current frame,
|
||||
// If you want to know whether the key started being pressed in the current tick,
|
||||
// use inpututil.IsKeyJustPressed
|
||||
//
|
||||
// Note that a Key represents a pysical key of US keyboard layout.
|
||||
@ -91,7 +91,7 @@ func Wheel() (xoff, yoff float64) {
|
||||
|
||||
// IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed.
|
||||
//
|
||||
// If you want to know whether the mouseButton started being pressed in the current frame,
|
||||
// If you want to know whether the mouseButton started being pressed in the current tick,
|
||||
// use inpututil.IsMouseButtonJustPressed
|
||||
//
|
||||
// IsMouseButtonPressed is concurrent-safe.
|
||||
@ -206,7 +206,7 @@ func GamepadButtonNum(id GamepadID) int {
|
||||
|
||||
// IsGamepadButtonPressed reports whether the given button of the gamepad (id) is pressed or not.
|
||||
//
|
||||
// If you want to know whether the given button of gamepad (id) started being pressed in the current frame,
|
||||
// If you want to know whether the given button of gamepad (id) started being pressed in the current tick,
|
||||
// use inpututil.IsGamepadButtonJustPressed
|
||||
//
|
||||
// IsGamepadButtonPressed is concurrent-safe.
|
||||
@ -349,7 +349,7 @@ type TouchID = ui.TouchID
|
||||
// AppendTouchIDs appends the current touch states to touches, and returns the extended buffer.
|
||||
// Giving a slice that already has enough capacity works efficiently.
|
||||
//
|
||||
// If you want to know whether a touch started being pressed in the current frame,
|
||||
// If you want to know whether a touch started being pressed in the current tick,
|
||||
// use inpututil.JustPressedTouchIDs
|
||||
//
|
||||
// AppendTouchIDs doesn't append anything when there are no touches.
|
||||
|
@ -89,9 +89,7 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the input state and use it for one frame to give a consistent result for one frame (#2496).
|
||||
var inputState InputState
|
||||
ui.beginFrame(&inputState)
|
||||
ui.beginFrame()
|
||||
defer ui.endFrame()
|
||||
|
||||
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
|
||||
@ -128,13 +126,19 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
|
||||
if err := hooks.RunBeforeUpdateHooks(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the input state and use it for one tick to give a consistent result for one tick (#2496, #2501).
|
||||
var inputState InputState
|
||||
ui.readInputState(&inputState)
|
||||
if err := c.game.Update(inputState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Catch the error that happened at (*Image).At.
|
||||
if err := theGlobalState.error(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ui.resetForTick()
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ type InputState struct {
|
||||
RunesCount int
|
||||
}
|
||||
|
||||
func (i *InputState) resetForFrame() {
|
||||
func (i *InputState) resetForTick() {
|
||||
i.WheelX = 0
|
||||
i.WheelY = 0
|
||||
i.RunesCount = 0
|
||||
|
@ -696,13 +696,8 @@ func (u *userInterfaceImpl) createWindow(width, height int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) beginFrame(inputState *InputState) {
|
||||
func (u *userInterfaceImpl) beginFrame() {
|
||||
atomic.StoreUint32(&u.inFrame, 1)
|
||||
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
*inputState = u.inputState
|
||||
u.inputState.resetForFrame()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
@ -1416,6 +1411,7 @@ func (u *userInterfaceImpl) resetForTick() {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
u.windowBeingClosed = false
|
||||
u.inputState.resetForTick()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
||||
|
@ -680,16 +680,19 @@ func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
||||
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
||||
*inputState = u.inputState
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) resetForTick() {
|
||||
u.inputState.resetForTick()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) Window() Window {
|
||||
return &nullWindow{}
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) beginFrame(inputState *InputState) {
|
||||
*inputState = u.inputState
|
||||
u.inputState.resetForFrame()
|
||||
func (u *userInterfaceImpl) beginFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
|
@ -418,7 +418,16 @@ func (u *userInterfaceImpl) DeviceScaleFactor() float64 {
|
||||
return deviceScale()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
*inputState = u.inputState
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) resetForTick() {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
u.inputState.resetForTick()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) Window() Window {
|
||||
@ -448,12 +457,7 @@ func (u *userInterfaceImpl) ScheduleFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) beginFrame(inputState *InputState) {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
|
||||
*inputState = u.inputState
|
||||
u.inputState.resetForFrame()
|
||||
func (u *userInterfaceImpl) beginFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
|
@ -92,7 +92,12 @@ func (*userInterfaceImpl) ScreenSizeInFullscreen() (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) resetForTick() {
|
||||
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
||||
*inputState = u.inputState
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) resetForTick() {
|
||||
u.inputState.resetForTick()
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) CursorMode() CursorMode {
|
||||
@ -133,9 +138,7 @@ func (*userInterfaceImpl) Window() Window {
|
||||
return &nullWindow{}
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) beginFrame(inputState *InputState) {
|
||||
*inputState = u.inputState
|
||||
u.inputState.resetForFrame()
|
||||
func (u *userInterfaceImpl) beginFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
|
Loading…
Reference in New Issue
Block a user