Created
January 11, 2023 18:56
-
-
Save SolarLune/2a345a7fd886fea6fed4a1c576a6e225 to your computer and use it in GitHub Desktop.
An input system I made for my Golang game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Input interface { | |
Poll() float64 | |
} | |
type GamepadAxisInput struct { | |
ID ebiten.GamepadID | |
Axis ebiten.StandardGamepadAxis | |
Direction int | |
Deadzone float64 | |
} | |
func NewGamepadAxisInput(id ebiten.GamepadID, axis ebiten.StandardGamepadAxis, direction int) *GamepadAxisInput { | |
return &GamepadAxisInput{ | |
ID: id, | |
Axis: axis, | |
Direction: direction, | |
Deadzone: 0.1, | |
} | |
} | |
func (axis *GamepadAxisInput) Poll() float64 { | |
axisValue := ebiten.StandardGamepadAxisValue(axis.ID, axis.Axis) | |
if axis.Direction > 0 { | |
if axisValue > axis.Deadzone { | |
return axisValue | |
} | |
return 0 | |
} else { | |
if axisValue < -axis.Deadzone { | |
return axisValue | |
} | |
return 0 | |
} | |
} | |
type GamepadButtonInput struct { | |
ID ebiten.GamepadID | |
Button ebiten.StandardGamepadButton | |
} | |
func NewGamepadButtonInput(id ebiten.GamepadID, button ebiten.StandardGamepadButton) *GamepadButtonInput { | |
return &GamepadButtonInput{ | |
ID: id, | |
Button: button, | |
} | |
} | |
func (button *GamepadButtonInput) Poll() float64 { | |
if ebiten.IsStandardGamepadButtonPressed(button.ID, button.Button) { | |
return 1 | |
} | |
return 0 | |
} | |
// FirstGamepad returns the first connected gamepad. | |
func FirstGamepad() ebiten.GamepadID { | |
for i := 0; i < 16; i++ { | |
gid := ebiten.GamepadID(i) | |
if ebiten.GamepadName(gid) != "" { | |
// if ebiten.GamepadName(gid) != "" && ebiten.IsStandardGamepadLayoutAvailable(gid) { | |
return gid | |
} | |
} | |
return ebiten.GamepadID(0) | |
} | |
type KeyboardInput struct { | |
Key ebiten.Key | |
} | |
func NewKeyboardInput(key ebiten.Key) *KeyboardInput { | |
return &KeyboardInput{Key: key} | |
} | |
func (key *KeyboardInput) Poll() float64 { | |
if ebiten.IsKeyPressed(key.Key) { | |
return 1 | |
} | |
return 0 | |
} | |
type Keybindings struct { | |
Actions map[string][]int | |
Strengths map[string]float64 | |
Inputs map[string][]Input | |
} | |
func NewKeybindings() *Keybindings { | |
return &Keybindings{ | |
Actions: map[string][]int{}, | |
Inputs: map[string][]Input{}, | |
Strengths: map[string]float64{}, | |
} | |
} | |
func (kb *Keybindings) Update() { | |
for actionName, inputList := range kb.Inputs { | |
pressed := false | |
kb.Strengths[actionName] = 0 | |
for _, input := range inputList { | |
strength := input.Poll() | |
if strength != 0 { | |
kb.Strengths[actionName] = math.Abs(strength) | |
pressed = true | |
break | |
} | |
} | |
v := 0 | |
if len(kb.Actions[actionName]) > 0 { | |
v = kb.Actions[actionName][len(kb.Actions[actionName])-1] | |
} | |
if pressed { | |
if v == 0 { | |
v = 1 | |
} else { | |
v = 2 | |
} | |
} else { | |
if v > 0 && v < 3 { | |
v = 3 | |
} else { | |
v = 0 | |
} | |
} | |
kb.Actions[actionName] = append(kb.Actions[actionName], v) | |
maxBufferLength := 15 | |
if len(kb.Actions[actionName]) > maxBufferLength { | |
kb.Actions[actionName] = kb.Actions[actionName][1:] | |
} | |
} | |
} | |
func (kb *Keybindings) Add(actionName string, actionInputs ...Input) { | |
if _, exists := kb.Inputs[actionName]; !exists { | |
kb.Inputs[actionName] = []Input{} | |
} | |
kb.Inputs[actionName] = append(kb.Inputs[actionName], actionInputs...) | |
} | |
func (kb *Keybindings) ActionPressed(bufferLength int, actionNames ...string) bool { | |
for _, actionName := range actionNames { | |
max := len(kb.Actions[actionName]) - (bufferLength + 1) | |
if max < 0 { | |
max = 0 | |
} | |
for i := len(kb.Actions[actionName]) - 1; i >= max; i-- { | |
v := kb.Actions[actionName][i] | |
if v == 1 { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
func (kb *Keybindings) ActionDown(bufferLength int, actionNames ...string) bool { | |
for _, actionName := range actionNames { | |
max := len(kb.Actions[actionName]) - (bufferLength + 1) | |
if max < 0 { | |
max = 0 | |
} | |
for i := len(kb.Actions[actionName]) - 1; i >= max; i-- { | |
v := kb.Actions[actionName][i] | |
if v == 1 || v == 2 { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
func (kb *Keybindings) ActionReleased(bufferLength int, actionNames ...string) bool { | |
for _, actionName := range actionNames { | |
max := len(kb.Actions[actionName]) - (bufferLength + 1) | |
if max < 0 { | |
max = 0 | |
} | |
for i := len(kb.Actions[actionName]) - 1; i >= max; i-- { | |
v := kb.Actions[actionName][i] | |
if v == 3 { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
func (kb *Keybindings) ActionConsume(actionNames ...string) { | |
for _, actionName := range actionNames { | |
for i := 0; i < len(kb.Actions[actionName])-1; i++ { | |
kb.Actions[actionName][i] = 3 | |
} | |
} | |
} | |
func (kb *Keybindings) Empty() bool { | |
return len(kb.Actions) == 0 | |
} | |
func (kb *Keybindings) ActionStrength(actionName string) float64 { | |
return kb.Strengths[actionName] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment