Skip to content

Instantly share code, notes, and snippets.

@SolarLune
Created January 11, 2023 18:56
Show Gist options
  • Save SolarLune/2a345a7fd886fea6fed4a1c576a6e225 to your computer and use it in GitHub Desktop.
Save SolarLune/2a345a7fd886fea6fed4a1c576a6e225 to your computer and use it in GitHub Desktop.
An input system I made for my Golang game
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