From b03a017a7ff87083d74938a4d554ac340b1cfe2b Mon Sep 17 00:00:00 2001 From: bloeys Date: Sat, 9 Oct 2021 05:32:17 +0400 Subject: [PATCH] Keyboard and mouse input system --- input/input.go | 47 ++++++++++++++++++++++++++++ input/keyboard.go | 67 ++++++++++++++++++++++++++++++++++++++++ input/mouse.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++ main.go | 14 +++++++++ 4 files changed, 207 insertions(+) create mode 100755 input/input.go create mode 100755 input/keyboard.go create mode 100755 input/mouse.go diff --git a/input/input.go b/input/input.go new file mode 100755 index 0000000..55bcf90 --- /dev/null +++ b/input/input.go @@ -0,0 +1,47 @@ +package input + +import "github.com/veandco/go-sdl2/sdl" + +type InputKey int + +var ( + anyKeyDown bool + anyMouseBtnDown bool +) + +//EventLoopStarted should be called just before processing SDL events +func EventLoopStarted() { + + anyKeyDown = false + anyMouseBtnDown = false + + //Clear XThisFrame which is needed because a repeat event needs multiple frames to happen + for _, v := range mouseBtns { + + v.isDoubleClick = false + v.pressedThisFrame = false + v.releasedThisFrame = false + + if v.state == sdl.PRESSED { + anyMouseBtnDown = true + } + } + + for _, v := range keyboardKeys { + + v.pressedThisFrame = false + v.releasedThisFrame = false + + if v.state == sdl.PRESSED { + anyKeyDown = true + } + } +} + +func AnyKeyDown() bool { + return anyKeyDown +} + +func AnyMouseBtnDown() bool { + return anyMouseBtnDown +} diff --git a/input/keyboard.go b/input/keyboard.go new file mode 100755 index 0000000..62e0c90 --- /dev/null +++ b/input/keyboard.go @@ -0,0 +1,67 @@ +package input + +import "github.com/veandco/go-sdl2/sdl" + +type keyState struct { + key sdl.Keycode + state byte + pressedThisFrame bool + releasedThisFrame bool +} + +var ( + keyboardKeys = make(map[sdl.Keycode]*keyState) +) + +func HandleKeyboardEvent(e *sdl.KeyboardEvent) { + + ks := keyboardKeys[e.Keysym.Sym] + if ks == nil { + ks = &keyState{key: e.Keysym.Sym} + keyboardKeys[e.Keysym.Sym] = ks + } + + ks.state = e.State + ks.pressedThisFrame = e.Repeat == 0 && e.State == sdl.PRESSED + ks.releasedThisFrame = e.Repeat == 0 && e.State == sdl.RELEASED +} + +func KeyClicked(kc sdl.Keycode) bool { + + key := keyboardKeys[kc] + if key == nil { + return false + } + + return key.pressedThisFrame +} + +func KeyReleased(kc sdl.Keycode) bool { + + key := keyboardKeys[kc] + if key == nil { + return false + } + + return key.releasedThisFrame +} + +func KeyDown(kc sdl.Keycode) bool { + + key := keyboardKeys[kc] + if key == nil { + return false + } + + return key.state == sdl.PRESSED +} + +func KeyUp(kc sdl.Keycode) bool { + + key := keyboardKeys[kc] + if key == nil { + return true + } + + return key.state == sdl.RELEASED +} diff --git a/input/mouse.go b/input/mouse.go new file mode 100755 index 0000000..3756eef --- /dev/null +++ b/input/mouse.go @@ -0,0 +1,79 @@ +package input + +import "github.com/veandco/go-sdl2/sdl" + +type mouseBtnState struct { + button byte + state byte + isDoubleClick bool + pressedThisFrame bool + releasedThisFrame bool +} + +var ( + mouseBtns = make(map[byte]*mouseBtnState) +) + +func HandleMouseBtnEvent(e *sdl.MouseButtonEvent) { + + mb := mouseBtns[e.Button] + if mb == nil { + mb = &mouseBtnState{button: e.Button} + mouseBtns[e.Button] = mb + } + + mb.state = e.State + mb.isDoubleClick = e.Clicks > 1 && e.State == sdl.PRESSED + mb.pressedThisFrame = e.State == sdl.PRESSED + mb.releasedThisFrame = e.State == sdl.RELEASED +} + +func MouseClicked(mouseBtn byte) bool { + + mb := mouseBtns[mouseBtn] + if mb == nil { + return false + } + + return mb.pressedThisFrame +} + +func MouseDoubleClicked(mouseBtn byte) bool { + + mb := mouseBtns[mouseBtn] + if mb == nil { + return false + } + + return mb.isDoubleClick +} + +func MouseReleased(mouseBtn byte) bool { + + mb := mouseBtns[mouseBtn] + if mb == nil { + return false + } + + return mb.releasedThisFrame +} + +func MouseDown(mouseBtn byte) bool { + + mb := mouseBtns[mouseBtn] + if mb == nil { + return false + } + + return mb.state == sdl.PRESSED +} + +func MouseUp(mouseBtn byte) bool { + + mb := mouseBtns[mouseBtn] + if mb == nil { + return true + } + + return mb.state == sdl.RELEASED +} diff --git a/main.go b/main.go index ac3d90e..2405392 100755 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" + "github.com/bloeys/go-sdl-engine/input" "github.com/bloeys/go-sdl-engine/timing" "github.com/go-gl/gl/v4.6-compatibility/gl" "github.com/veandco/go-sdl2/sdl" @@ -105,6 +106,7 @@ func gameLoop() { timing.FrameStarted() handleEvents() + update() draw() window.GLSwap() @@ -116,10 +118,18 @@ func gameLoop() { func handleEvents() { + input.EventLoopStarted() + for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch e := event.(type) { + case *sdl.KeyboardEvent: + input.HandleKeyboardEvent(e) + + case *sdl.MouseButtonEvent: + input.HandleMouseBtnEvent(e) + case *sdl.QuitEvent: println("Quit at ", e.Timestamp) isRunning = false @@ -127,6 +137,10 @@ func handleEvents() { } } +func update() { + println(input.AnyKeyDown(), ";", input.AnyMouseBtnDown()) +} + func draw() { //Clear screen and depth buffers gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)