2018-02-04 09:51:03 +01:00
|
|
|
// Copyright 2018 The Ebiten Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
// Package inpututil provides utility functions of input like keyboard or mouse.
|
|
|
|
package inpututil
|
|
|
|
|
|
|
|
import (
|
2024-10-26 09:06:39 +02:00
|
|
|
"slices"
|
2018-05-09 16:41:06 +02:00
|
|
|
"sync"
|
2018-04-29 19:43:08 +02:00
|
|
|
|
2020-10-03 19:35:13 +02:00
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
2023-10-06 06:49:42 +02:00
|
|
|
"github.com/hajimehoshi/ebiten/v2/internal/hook"
|
2018-02-04 09:51:03 +01:00
|
|
|
)
|
|
|
|
|
2022-08-15 17:53:53 +02:00
|
|
|
type pos struct {
|
|
|
|
x int
|
|
|
|
y int
|
|
|
|
}
|
|
|
|
|
2018-02-04 09:51:03 +01:00
|
|
|
type inputState struct {
|
2024-10-26 09:06:39 +02:00
|
|
|
keyDurations [ebiten.KeyMax + 1]int
|
|
|
|
prevKeyDurations [ebiten.KeyMax + 1]int
|
2018-02-16 19:10:40 +01:00
|
|
|
|
2024-10-26 09:06:39 +02:00
|
|
|
mouseButtonDurations [ebiten.MouseButtonMax + 1]int
|
|
|
|
prevMouseButtonDurations [ebiten.MouseButtonMax + 1]int
|
2018-02-16 19:10:40 +01:00
|
|
|
|
2020-10-07 18:08:30 +02:00
|
|
|
gamepadIDs map[ebiten.GamepadID]struct{}
|
|
|
|
prevGamepadIDs map[ebiten.GamepadID]struct{}
|
2018-04-29 19:51:38 +02:00
|
|
|
|
2020-10-07 18:08:30 +02:00
|
|
|
gamepadButtonDurations map[ebiten.GamepadID][]int
|
|
|
|
prevGamepadButtonDurations map[ebiten.GamepadID][]int
|
2018-02-16 19:41:45 +01:00
|
|
|
|
2021-07-19 19:25:52 +02:00
|
|
|
standardGamepadButtonDurations map[ebiten.GamepadID][]int
|
|
|
|
prevStandardGamepadButtonDurations map[ebiten.GamepadID][]int
|
|
|
|
|
2021-01-30 20:22:50 +01:00
|
|
|
touchIDs map[ebiten.TouchID]struct{}
|
2020-10-09 20:36:14 +02:00
|
|
|
touchDurations map[ebiten.TouchID]int
|
2022-08-15 17:53:53 +02:00
|
|
|
touchPositions map[ebiten.TouchID]pos
|
2020-10-09 20:36:14 +02:00
|
|
|
prevTouchDurations map[ebiten.TouchID]int
|
2022-08-15 17:53:53 +02:00
|
|
|
prevTouchPositions map[ebiten.TouchID]pos
|
2018-02-04 09:51:03 +01:00
|
|
|
|
2021-07-09 19:03:48 +02:00
|
|
|
gamepadIDsBuf []ebiten.GamepadID
|
|
|
|
touchIDsBuf []ebiten.TouchID
|
|
|
|
|
2018-02-04 09:51:03 +01:00
|
|
|
m sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
var theInputState = &inputState{
|
2020-10-07 18:08:30 +02:00
|
|
|
gamepadIDs: map[ebiten.GamepadID]struct{}{},
|
|
|
|
prevGamepadIDs: map[ebiten.GamepadID]struct{}{},
|
2018-04-29 19:51:38 +02:00
|
|
|
|
2020-10-07 18:08:30 +02:00
|
|
|
gamepadButtonDurations: map[ebiten.GamepadID][]int{},
|
|
|
|
prevGamepadButtonDurations: map[ebiten.GamepadID][]int{},
|
2018-02-16 19:41:45 +01:00
|
|
|
|
2021-07-19 19:25:52 +02:00
|
|
|
standardGamepadButtonDurations: map[ebiten.GamepadID][]int{},
|
|
|
|
prevStandardGamepadButtonDurations: map[ebiten.GamepadID][]int{},
|
|
|
|
|
2021-01-30 20:22:50 +01:00
|
|
|
touchIDs: map[ebiten.TouchID]struct{}{},
|
2020-10-09 20:36:14 +02:00
|
|
|
touchDurations: map[ebiten.TouchID]int{},
|
2022-08-15 17:53:53 +02:00
|
|
|
touchPositions: map[ebiten.TouchID]pos{},
|
2020-10-09 20:36:14 +02:00
|
|
|
prevTouchDurations: map[ebiten.TouchID]int{},
|
2022-08-15 17:53:53 +02:00
|
|
|
prevTouchPositions: map[ebiten.TouchID]pos{},
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2023-10-06 06:49:42 +02:00
|
|
|
hook.AppendHookOnBeforeUpdate(func() error {
|
2018-02-04 09:51:03 +01:00
|
|
|
theInputState.update()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *inputState) update() {
|
|
|
|
i.m.Lock()
|
|
|
|
defer i.m.Unlock()
|
|
|
|
|
2018-02-05 15:45:43 +01:00
|
|
|
// Keyboard
|
2024-10-26 09:06:39 +02:00
|
|
|
copy(i.prevKeyDurations[:], i.keyDurations[:])
|
|
|
|
for idx := range i.keyDurations {
|
|
|
|
if ebiten.IsKeyPressed(ebiten.Key(idx)) {
|
|
|
|
i.keyDurations[idx]++
|
2018-02-04 09:51:03 +01:00
|
|
|
} else {
|
2024-10-26 09:06:39 +02:00
|
|
|
i.keyDurations[idx] = 0
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-05 15:45:43 +01:00
|
|
|
// Mouse
|
2024-10-26 09:06:39 +02:00
|
|
|
copy(i.prevMouseButtonDurations[:], i.mouseButtonDurations[:])
|
|
|
|
for idx := range i.mouseButtonDurations {
|
|
|
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButton(idx)) {
|
|
|
|
i.mouseButtonDurations[idx]++
|
2018-02-04 09:51:03 +01:00
|
|
|
} else {
|
2024-10-26 09:06:39 +02:00
|
|
|
i.mouseButtonDurations[idx] = 0
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-05 15:45:43 +01:00
|
|
|
// Gamepads
|
2018-02-16 19:41:45 +01:00
|
|
|
|
2018-05-10 19:43:19 +02:00
|
|
|
// Copy the gamepad IDs.
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.prevGamepadIDs {
|
|
|
|
delete(i.prevGamepadIDs, id)
|
|
|
|
}
|
2018-04-29 19:51:38 +02:00
|
|
|
for id := range i.gamepadIDs {
|
|
|
|
i.prevGamepadIDs[id] = struct{}{}
|
|
|
|
}
|
|
|
|
|
2018-05-10 19:43:19 +02:00
|
|
|
// Copy the gamepad button durations.
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.prevGamepadButtonDurations {
|
|
|
|
delete(i.prevGamepadButtonDurations, id)
|
|
|
|
}
|
2018-05-10 19:43:19 +02:00
|
|
|
for id, ds := range i.gamepadButtonDurations {
|
2020-05-24 20:20:21 +02:00
|
|
|
i.prevGamepadButtonDurations[id] = append([]int{}, ds...)
|
2018-02-16 19:41:45 +01:00
|
|
|
}
|
2018-04-29 19:51:38 +02:00
|
|
|
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.prevStandardGamepadButtonDurations {
|
|
|
|
delete(i.prevStandardGamepadButtonDurations, id)
|
|
|
|
}
|
2021-07-19 19:25:52 +02:00
|
|
|
for id, ds := range i.standardGamepadButtonDurations {
|
|
|
|
i.prevStandardGamepadButtonDurations[id] = append([]int{}, ds...)
|
|
|
|
}
|
|
|
|
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.gamepadIDs {
|
|
|
|
delete(i.gamepadIDs, id)
|
|
|
|
}
|
2021-07-09 19:03:48 +02:00
|
|
|
i.gamepadIDsBuf = ebiten.AppendGamepadIDs(i.gamepadIDsBuf[:0])
|
|
|
|
for _, id := range i.gamepadIDsBuf {
|
2018-04-29 19:51:38 +02:00
|
|
|
i.gamepadIDs[id] = struct{}{}
|
2021-07-19 19:25:52 +02:00
|
|
|
|
2022-03-31 19:06:26 +02:00
|
|
|
if _, ok := i.gamepadButtonDurations[id]; !ok {
|
|
|
|
i.gamepadButtonDurations[id] = make([]int, ebiten.GamepadButtonMax+1)
|
2022-03-25 06:31:07 +01:00
|
|
|
}
|
2022-06-29 08:55:05 +02:00
|
|
|
for b := ebiten.GamepadButton(0); b <= ebiten.GamepadButtonMax; b++ {
|
2018-02-04 09:51:03 +01:00
|
|
|
if ebiten.IsGamepadButtonPressed(id, b) {
|
2018-04-29 19:19:53 +02:00
|
|
|
i.gamepadButtonDurations[id][b]++
|
2018-02-04 09:51:03 +01:00
|
|
|
} else {
|
2018-04-29 19:19:53 +02:00
|
|
|
i.gamepadButtonDurations[id][b] = 0
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
}
|
2021-07-19 19:25:52 +02:00
|
|
|
|
|
|
|
if _, ok := i.standardGamepadButtonDurations[id]; !ok {
|
|
|
|
i.standardGamepadButtonDurations[id] = make([]int, ebiten.StandardGamepadButtonMax+1)
|
|
|
|
}
|
|
|
|
for b := ebiten.StandardGamepadButton(0); b <= ebiten.StandardGamepadButtonMax; b++ {
|
|
|
|
if ebiten.IsStandardGamepadButtonPressed(id, b) {
|
|
|
|
i.standardGamepadButtonDurations[id][b]++
|
|
|
|
} else {
|
|
|
|
i.standardGamepadButtonDurations[id][b] = 0
|
|
|
|
}
|
|
|
|
}
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
2018-04-29 19:19:53 +02:00
|
|
|
for id := range i.gamepadButtonDurations {
|
2024-10-26 09:52:17 +02:00
|
|
|
if _, ok := i.gamepadIDs[id]; !ok {
|
|
|
|
delete(i.gamepadButtonDurations, id)
|
|
|
|
}
|
2018-02-05 15:45:43 +01:00
|
|
|
}
|
2021-07-19 19:25:52 +02:00
|
|
|
for id := range i.standardGamepadButtonDurations {
|
2024-10-26 09:52:17 +02:00
|
|
|
if _, ok := i.gamepadIDs[id]; !ok {
|
|
|
|
delete(i.standardGamepadButtonDurations, id)
|
|
|
|
}
|
2021-07-19 19:25:52 +02:00
|
|
|
}
|
2018-02-04 09:51:03 +01:00
|
|
|
|
2018-02-05 15:45:43 +01:00
|
|
|
// Touches
|
2018-02-16 19:58:19 +01:00
|
|
|
|
2022-08-15 17:53:53 +02:00
|
|
|
// Copy the touch durations and positions.
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.prevTouchDurations {
|
|
|
|
delete(i.prevTouchDurations, id)
|
|
|
|
}
|
2018-05-10 18:43:31 +02:00
|
|
|
for id := range i.touchDurations {
|
|
|
|
i.prevTouchDurations[id] = i.touchDurations[id]
|
2018-02-16 19:58:19 +01:00
|
|
|
}
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.prevTouchPositions {
|
|
|
|
delete(i.prevTouchPositions, id)
|
|
|
|
}
|
2022-08-15 17:53:53 +02:00
|
|
|
for id := range i.touchPositions {
|
|
|
|
i.prevTouchPositions[id] = i.touchPositions[id]
|
|
|
|
}
|
2018-02-16 19:58:19 +01:00
|
|
|
|
2024-10-26 09:52:17 +02:00
|
|
|
for id := range i.touchIDs {
|
|
|
|
delete(i.touchIDs, id)
|
|
|
|
}
|
2021-07-09 19:03:48 +02:00
|
|
|
i.touchIDsBuf = ebiten.AppendTouchIDs(i.touchIDsBuf[:0])
|
|
|
|
for _, id := range i.touchIDsBuf {
|
2021-01-30 20:22:50 +01:00
|
|
|
i.touchIDs[id] = struct{}{}
|
2018-05-06 17:31:43 +02:00
|
|
|
i.touchDurations[id]++
|
2022-08-15 17:53:53 +02:00
|
|
|
x, y := ebiten.TouchPosition(id)
|
|
|
|
i.touchPositions[id] = pos{x: x, y: y}
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
2018-04-29 19:19:53 +02:00
|
|
|
for id := range i.touchDurations {
|
2021-01-30 20:22:50 +01:00
|
|
|
if _, ok := i.touchIDs[id]; !ok {
|
|
|
|
delete(i.touchDurations, id)
|
2022-08-15 17:53:53 +02:00
|
|
|
delete(i.touchPositions, id)
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-10 15:18:13 +02:00
|
|
|
// AppendPressedKeys append currently pressed keyboard keys to keys and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
2021-04-06 18:48:13 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendPressedKeys must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 15:18:13 +02:00
|
|
|
// AppendPressedKeys is concurrent safe.
|
|
|
|
func AppendPressedKeys(keys []ebiten.Key) []ebiten.Key {
|
2021-04-06 18:48:13 +02:00
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
for i, d := range theInputState.keyDurations {
|
|
|
|
if d == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
keys = append(keys, ebiten.Key(i))
|
|
|
|
}
|
|
|
|
return keys
|
|
|
|
}
|
|
|
|
|
2021-07-10 15:18:13 +02:00
|
|
|
// PressedKeys returns a set of currently pressed keyboard keys.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// PressedKeys must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 15:32:15 +02:00
|
|
|
// Deprecated: as of v2.2. Use AppendPressedKeys instead.
|
2021-07-10 15:18:13 +02:00
|
|
|
func PressedKeys() []ebiten.Key {
|
|
|
|
return AppendPressedKeys(nil)
|
|
|
|
}
|
|
|
|
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustPressedKeys append just pressed keyboard keys to keys and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustPressedKeys must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustPressedKeys is concurrent safe.
|
|
|
|
func AppendJustPressedKeys(keys []ebiten.Key) []ebiten.Key {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
for i, d := range theInputState.keyDurations {
|
|
|
|
if d != 1 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
keys = append(keys, ebiten.Key(i))
|
|
|
|
}
|
|
|
|
return keys
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendJustReleasedKeys append just released keyboard keys to keys and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustReleasedKeys must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustReleasedKeys is concurrent safe.
|
|
|
|
func AppendJustReleasedKeys(keys []ebiten.Key) []ebiten.Key {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
2024-10-26 09:06:39 +02:00
|
|
|
for i := range theInputState.keyDurations {
|
|
|
|
if theInputState.keyDurations[i] != 0 {
|
2022-10-12 09:21:52 +02:00
|
|
|
continue
|
|
|
|
}
|
2024-10-26 09:06:39 +02:00
|
|
|
if theInputState.prevKeyDurations[i] == 0 {
|
2022-10-12 09:21:52 +02:00
|
|
|
continue
|
|
|
|
}
|
2024-10-26 09:06:39 +02:00
|
|
|
keys = append(keys, ebiten.Key(i))
|
2022-10-12 09:21:52 +02:00
|
|
|
}
|
|
|
|
return keys
|
|
|
|
}
|
|
|
|
|
2018-02-04 09:51:03 +01:00
|
|
|
// IsKeyJustPressed returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given key is pressed just in the current tick.
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsKeyJustPressed must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// IsKeyJustPressed is concurrent safe.
|
2018-02-04 09:51:03 +01:00
|
|
|
func IsKeyJustPressed(key ebiten.Key) bool {
|
|
|
|
return KeyPressDuration(key) == 1
|
|
|
|
}
|
|
|
|
|
2018-02-16 19:10:40 +01:00
|
|
|
// IsKeyJustReleased returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given key is released just in the current tick.
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsKeyJustReleased must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// IsKeyJustReleased is concurrent safe.
|
2018-02-16 19:10:40 +01:00
|
|
|
func IsKeyJustReleased(key ebiten.Key) bool {
|
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
return theInputState.keyDurations[key] == 0 && theInputState.prevKeyDurations[key] > 0
|
2018-02-16 19:10:40 +01:00
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// KeyPressDuration returns how long the key is pressed in ticks (Update).
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// KeyPressDuration must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// KeyPressDuration is concurrent safe.
|
2018-02-04 09:51:03 +01:00
|
|
|
func KeyPressDuration(key ebiten.Key) int {
|
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
return theInputState.keyDurations[key]
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// IsMouseButtonJustPressed returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given mouse button is pressed just in the current tick.
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsMouseButtonJustPressed must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// IsMouseButtonJustPressed is concurrent safe.
|
2018-02-04 09:51:03 +01:00
|
|
|
func IsMouseButtonJustPressed(button ebiten.MouseButton) bool {
|
|
|
|
return MouseButtonPressDuration(button) == 1
|
|
|
|
}
|
|
|
|
|
2018-02-16 19:10:40 +01:00
|
|
|
// IsMouseButtonJustReleased returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given mouse button is released just in the current tick.
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsMouseButtonJustReleased must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// IsMouseButtonJustReleased is concurrent safe.
|
2018-02-16 19:10:40 +01:00
|
|
|
func IsMouseButtonJustReleased(button ebiten.MouseButton) bool {
|
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
return theInputState.mouseButtonDurations[button] == 0 && theInputState.prevMouseButtonDurations[button] > 0
|
2018-02-16 19:10:40 +01:00
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// MouseButtonPressDuration returns how long the mouse button is pressed in ticks (Update).
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// MouseButtonPressDuration must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// MouseButtonPressDuration is concurrent safe.
|
2018-02-04 09:51:03 +01:00
|
|
|
func MouseButtonPressDuration(button ebiten.MouseButton) int {
|
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
return theInputState.mouseButtonDurations[button]
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// AppendJustConnectedGamepadIDs appends gamepad IDs that are connected just in the current tick to gamepadIDs,
|
2021-07-10 15:32:15 +02:00
|
|
|
// and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
2018-04-29 19:52:56 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustConnectedGamepadIDs must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 15:32:15 +02:00
|
|
|
// AppendJustConnectedGamepadIDs is concurrent safe.
|
|
|
|
func AppendJustConnectedGamepadIDs(gamepadIDs []ebiten.GamepadID) []ebiten.GamepadID {
|
2018-04-29 19:51:38 +02:00
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
origLen := len(gamepadIDs)
|
2018-04-29 19:51:38 +02:00
|
|
|
for id := range theInputState.gamepadIDs {
|
|
|
|
if _, ok := theInputState.prevGamepadIDs[id]; !ok {
|
2021-07-10 15:32:15 +02:00
|
|
|
gamepadIDs = append(gamepadIDs, id)
|
2018-04-29 19:51:38 +02:00
|
|
|
}
|
|
|
|
}
|
2024-10-26 09:06:39 +02:00
|
|
|
|
|
|
|
slices.Sort(gamepadIDs[origLen:])
|
2021-07-10 15:32:15 +02:00
|
|
|
return gamepadIDs
|
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// JustConnectedGamepadIDs returns gamepad IDs that are connected just in the current tick.
|
2021-07-10 15:32:15 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// JustConnectedGamepadIDs must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 15:32:15 +02:00
|
|
|
// Deprecated: as of v2.2. Use AppendJustConnectedGamepadIDs instead.
|
|
|
|
func JustConnectedGamepadIDs() []ebiten.GamepadID {
|
|
|
|
return AppendJustConnectedGamepadIDs(nil)
|
2018-04-29 19:51:38 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 21:34:15 +02:00
|
|
|
// IsGamepadJustDisconnected returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the gamepad of the given id is released just in the current tick.
|
2018-04-29 19:52:56 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsGamepadJustDisconnected must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-04-29 21:34:15 +02:00
|
|
|
// IsGamepadJustDisconnected is concurrent safe.
|
2020-10-07 18:08:30 +02:00
|
|
|
func IsGamepadJustDisconnected(id ebiten.GamepadID) bool {
|
2018-04-29 19:51:38 +02:00
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
2018-04-29 21:34:15 +02:00
|
|
|
_, prev := theInputState.prevGamepadIDs[id]
|
|
|
|
_, current := theInputState.gamepadIDs[id]
|
|
|
|
return prev && !current
|
2018-04-29 19:51:38 +02:00
|
|
|
}
|
|
|
|
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendPressedGamepadButtons append currently pressed gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendPressedGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendPressedGamepadButtons is concurrent safe.
|
|
|
|
func AppendPressedGamepadButtons(id ebiten.GamepadID, buttons []ebiten.GamepadButton) []ebiten.GamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b, d := range theInputState.gamepadButtonDurations[id] {
|
|
|
|
if d == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
buttons = append(buttons, ebiten.GamepadButton(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendJustPressedGamepadButtons append just pressed gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustPressedGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustPressedGamepadButtons is concurrent safe.
|
|
|
|
func AppendJustPressedGamepadButtons(id ebiten.GamepadID, buttons []ebiten.GamepadButton) []ebiten.GamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b, d := range theInputState.gamepadButtonDurations[id] {
|
|
|
|
if d != 1 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
buttons = append(buttons, ebiten.GamepadButton(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendJustReleasedGamepadButtons append just released gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustReleasedGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustReleasedGamepadButtons is concurrent safe.
|
|
|
|
func AppendJustReleasedGamepadButtons(id ebiten.GamepadID, buttons []ebiten.GamepadButton) []ebiten.GamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
if _, ok := theInputState.prevGamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b := ebiten.GamepadButton(0); b <= ebiten.GamepadButtonMax; b++ {
|
|
|
|
if theInputState.gamepadButtonDurations[id][b] == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if theInputState.prevGamepadButtonDurations[id][b] > 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
buttons = append(buttons, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
2018-02-04 09:51:03 +01:00
|
|
|
// IsGamepadButtonJustPressed returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given gamepad button of the gamepad id is pressed just in the current tick.
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsGamepadButtonJustPressed must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// IsGamepadButtonJustPressed is concurrent safe.
|
2020-10-07 18:08:30 +02:00
|
|
|
func IsGamepadButtonJustPressed(id ebiten.GamepadID, button ebiten.GamepadButton) bool {
|
2018-02-04 09:51:03 +01:00
|
|
|
return GamepadButtonPressDuration(id, button) == 1
|
|
|
|
}
|
|
|
|
|
2018-02-16 19:41:45 +01:00
|
|
|
// IsGamepadButtonJustReleased returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given gamepad button of the gamepad id is released just in the current tick.
|
2018-02-16 19:41:45 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsGamepadButtonJustReleased must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:41:45 +01:00
|
|
|
// IsGamepadButtonJustReleased is concurrent safe.
|
2020-10-07 18:08:30 +02:00
|
|
|
func IsGamepadButtonJustReleased(id ebiten.GamepadID, button ebiten.GamepadButton) bool {
|
2018-02-16 19:41:45 +01:00
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
var prev int
|
2018-04-29 19:19:53 +02:00
|
|
|
if _, ok := theInputState.prevGamepadButtonDurations[id]; ok {
|
|
|
|
prev = theInputState.prevGamepadButtonDurations[id][button]
|
2018-02-16 19:41:45 +01:00
|
|
|
}
|
2024-10-26 09:06:39 +02:00
|
|
|
var current int
|
2018-04-29 19:19:53 +02:00
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; ok {
|
|
|
|
current = theInputState.gamepadButtonDurations[id][button]
|
2018-02-16 19:41:45 +01:00
|
|
|
}
|
|
|
|
return current == 0 && prev > 0
|
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// GamepadButtonPressDuration returns how long the gamepad button of the gamepad id is pressed in ticks (Update).
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// GamepadButtonPressDuration must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:12:58 +01:00
|
|
|
// GamepadButtonPressDuration is concurrent safe.
|
2020-10-07 18:08:30 +02:00
|
|
|
func GamepadButtonPressDuration(id ebiten.GamepadID, button ebiten.GamepadButton) int {
|
2018-02-04 09:51:03 +01:00
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
var s int
|
2018-04-29 19:19:53 +02:00
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; ok {
|
|
|
|
s = theInputState.gamepadButtonDurations[id][button]
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendPressedStandardGamepadButtons append currently pressed standard gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendPressedStandardGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendPressedStandardGamepadButtons is concurrent safe.
|
|
|
|
func AppendPressedStandardGamepadButtons(id ebiten.GamepadID, buttons []ebiten.StandardGamepadButton) []ebiten.StandardGamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.standardGamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b, d := range theInputState.standardGamepadButtonDurations[id] {
|
|
|
|
if d == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
buttons = append(buttons, ebiten.StandardGamepadButton(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendJustPressedStandardGamepadButtons append just pressed standard gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustPressedStandardGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustPressedStandardGamepadButtons is concurrent safe.
|
|
|
|
func AppendJustPressedStandardGamepadButtons(id ebiten.GamepadID, buttons []ebiten.StandardGamepadButton) []ebiten.StandardGamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b, d := range theInputState.standardGamepadButtonDurations[id] {
|
|
|
|
if d != 1 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
buttons = append(buttons, ebiten.StandardGamepadButton(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendJustReleasedStandardGamepadButtons append just released standard gamepad buttons to buttons and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustReleasedStandardGamepadButtons must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-10-12 09:21:52 +02:00
|
|
|
// AppendJustReleasedStandardGamepadButtons is concurrent safe.
|
|
|
|
func AppendJustReleasedStandardGamepadButtons(id ebiten.GamepadID, buttons []ebiten.StandardGamepadButton) []ebiten.StandardGamepadButton {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.gamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
if _, ok := theInputState.prevGamepadButtonDurations[id]; !ok {
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
|
|
|
for b := ebiten.StandardGamepadButton(0); b <= ebiten.StandardGamepadButtonMax; b++ {
|
|
|
|
if theInputState.standardGamepadButtonDurations[id][b] == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if theInputState.prevStandardGamepadButtonDurations[id][b] > 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
buttons = append(buttons, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
return buttons
|
|
|
|
}
|
|
|
|
|
2021-07-19 19:25:52 +02:00
|
|
|
// IsStandardGamepadButtonJustPressed returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given standard gamepad button of the gamepad id is pressed just in the current tick.
|
2021-07-19 19:25:52 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsStandardGamepadButtonJustPressed must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-19 19:25:52 +02:00
|
|
|
// IsStandardGamepadButtonJustPressed is concurrent safe.
|
|
|
|
func IsStandardGamepadButtonJustPressed(id ebiten.GamepadID, button ebiten.StandardGamepadButton) bool {
|
|
|
|
return StandardGamepadButtonPressDuration(id, button) == 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsStandardGamepadButtonJustReleased returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given standard gamepad button of the gamepad id is released just in the current tick.
|
2021-07-19 19:25:52 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsStandardGamepadButtonJustReleased must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-19 19:25:52 +02:00
|
|
|
// IsStandardGamepadButtonJustReleased is concurrent safe.
|
|
|
|
func IsStandardGamepadButtonJustReleased(id ebiten.GamepadID, button ebiten.StandardGamepadButton) bool {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
var prev int
|
|
|
|
if _, ok := theInputState.prevStandardGamepadButtonDurations[id]; ok {
|
|
|
|
prev = theInputState.prevStandardGamepadButtonDurations[id][button]
|
|
|
|
}
|
|
|
|
var current int
|
|
|
|
if _, ok := theInputState.standardGamepadButtonDurations[id]; ok {
|
|
|
|
current = theInputState.standardGamepadButtonDurations[id][button]
|
|
|
|
}
|
|
|
|
return current == 0 && prev > 0
|
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// StandardGamepadButtonPressDuration returns how long the standard gamepad button of the gamepad id is pressed in ticks (Update).
|
2021-07-19 19:25:52 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// StandardGamepadButtonPressDuration must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-19 19:25:52 +02:00
|
|
|
// StandardGamepadButtonPressDuration is concurrent safe.
|
|
|
|
func StandardGamepadButtonPressDuration(id ebiten.GamepadID, button ebiten.StandardGamepadButton) int {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
if _, ok := theInputState.standardGamepadButtonDurations[id]; ok {
|
|
|
|
return theInputState.standardGamepadButtonDurations[id][button]
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// AppendJustPressedTouchIDs append touch IDs that are created just in the current tick to touchIDs,
|
2021-07-10 16:28:32 +02:00
|
|
|
// and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
2018-04-29 20:03:12 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustPressedTouchIDs must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 16:28:32 +02:00
|
|
|
// AppendJustPressedTouchIDs is concurrent safe.
|
|
|
|
func AppendJustPressedTouchIDs(touchIDs []ebiten.TouchID) []ebiten.TouchID {
|
2018-04-07 21:59:13 +02:00
|
|
|
theInputState.m.RLock()
|
2022-08-15 17:53:53 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
origLen := len(touchIDs)
|
2018-04-29 19:19:53 +02:00
|
|
|
for id, s := range theInputState.touchDurations {
|
2018-04-07 21:59:13 +02:00
|
|
|
if s == 1 {
|
2021-07-10 16:28:32 +02:00
|
|
|
touchIDs = append(touchIDs, id)
|
2018-04-07 21:59:13 +02:00
|
|
|
}
|
|
|
|
}
|
2022-08-15 17:53:53 +02:00
|
|
|
|
2024-10-26 09:06:39 +02:00
|
|
|
slices.Sort(touchIDs[origLen:])
|
2021-07-10 16:28:32 +02:00
|
|
|
return touchIDs
|
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// JustPressedTouchIDs returns touch IDs that are created just in the current tick.
|
2021-07-10 16:28:32 +02:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// JustPressedTouchIDs must be called in a game's Update, not Draw.
|
|
|
|
//
|
2021-07-10 16:28:32 +02:00
|
|
|
// Deprecated: as of v2.2. Use AppendJustPressedTouchIDs instead.
|
|
|
|
func JustPressedTouchIDs() []ebiten.TouchID {
|
|
|
|
return AppendJustPressedTouchIDs(nil)
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
|
|
|
|
2022-08-15 17:53:53 +02:00
|
|
|
// AppendJustReleasedTouchIDs append touch IDs that are released just in the current tick to touchIDs,
|
|
|
|
// and returns the extended buffer.
|
|
|
|
// Giving a slice that already has enough capacity works efficiently.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// AppendJustReleasedTouchIDs must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-08-15 17:53:53 +02:00
|
|
|
// AppendJustReleasedTouchIDs is concurrent safe.
|
|
|
|
func AppendJustReleasedTouchIDs(touchIDs []ebiten.TouchID) []ebiten.TouchID {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
origLen := len(touchIDs)
|
|
|
|
for id := range theInputState.prevTouchDurations {
|
|
|
|
if theInputState.touchDurations[id] == 0 && theInputState.prevTouchDurations[id] > 0 {
|
|
|
|
touchIDs = append(touchIDs, id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-26 09:06:39 +02:00
|
|
|
slices.Sort(touchIDs[origLen:])
|
2022-08-15 17:53:53 +02:00
|
|
|
return touchIDs
|
|
|
|
}
|
|
|
|
|
2018-02-16 19:58:19 +01:00
|
|
|
// IsTouchJustReleased returns a boolean value indicating
|
2022-05-06 13:40:43 +02:00
|
|
|
// whether the given touch is released just in the current tick.
|
2018-02-16 19:58:19 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// IsTouchJustReleased must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-02-16 19:58:19 +01:00
|
|
|
// IsTouchJustReleased is concurrent safe.
|
2020-10-09 20:36:14 +02:00
|
|
|
func IsTouchJustReleased(id ebiten.TouchID) bool {
|
2018-02-16 19:58:19 +01:00
|
|
|
theInputState.m.RLock()
|
2022-08-15 17:53:53 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
return theInputState.touchDurations[id] == 0 && theInputState.prevTouchDurations[id] > 0
|
2018-02-16 19:58:19 +01:00
|
|
|
}
|
|
|
|
|
2022-05-06 13:40:43 +02:00
|
|
|
// TouchPressDuration returns how long the touch remains in ticks (Update).
|
2018-02-16 19:12:58 +01:00
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// TouchPressDuration must be called in a game's Update, not Draw.
|
|
|
|
//
|
2018-04-30 13:23:58 +02:00
|
|
|
// TouchPressDuration is concurrent safe.
|
2020-10-09 20:36:14 +02:00
|
|
|
func TouchPressDuration(id ebiten.TouchID) int {
|
2018-02-04 09:51:03 +01:00
|
|
|
theInputState.m.RLock()
|
2024-10-26 09:06:39 +02:00
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
return theInputState.touchDurations[id]
|
2018-02-04 09:51:03 +01:00
|
|
|
}
|
2022-08-15 17:53:53 +02:00
|
|
|
|
|
|
|
// TouchPositionInPreviousTick returns the position in the previous tick.
|
|
|
|
// If the touch is a just-released touch, TouchPositionInPreviousTick returns the last position of the touch.
|
|
|
|
//
|
2022-11-20 06:28:38 +01:00
|
|
|
// TouchPositionInPreviousTick must be called in a game's Update, not Draw.
|
|
|
|
//
|
2022-08-15 17:53:53 +02:00
|
|
|
// TouchJustReleasedPosition is concurrent safe.
|
|
|
|
func TouchPositionInPreviousTick(id ebiten.TouchID) (int, int) {
|
|
|
|
theInputState.m.RLock()
|
|
|
|
defer theInputState.m.RUnlock()
|
|
|
|
|
|
|
|
p := theInputState.prevTouchPositions[id]
|
|
|
|
return p.x, p.y
|
|
|
|
}
|