Gamepad

Instructions

  • Click on demo to allow inputs
  • Use left stick to move sprite
  • Buttons also move sprite (layout may be inconsistent between controllers)
gamepad.go
  1package main
  2
  3import (
  4 "embed"
  5 "log"
  6 "math"
  7
  8 "github.com/TheBitDrifter/bappa/blueprint"
  9 "github.com/TheBitDrifter/bappa/blueprint/client"
 10 "github.com/TheBitDrifter/bappa/blueprint/input"
 11 "github.com/TheBitDrifter/bappa/coldbrew"
 12 "github.com/TheBitDrifter/bappa/coldbrew/coldbrew_clientsystems"
 13 "github.com/TheBitDrifter/bappa/coldbrew/coldbrew_rendersystems"
 14 "github.com/TheBitDrifter/bappa/tteokbokki/spatial"
 15
 16 "github.com/TheBitDrifter/bappa/warehouse"
 17 "github.com/hajimehoshi/ebiten/v2"
 18)
 19
 20//go:embed assets/*
 21var assets embed.FS
 22
 23var actions = struct {
 24 Movement, Up, Down, Left, Right input.Input
 25}{
 26 Movement: input.NewInput(),
 27 Up:       input.NewInput(),
 28 Down:     input.NewInput(),
 29 Left:     input.NewInput(),
 30 Right:    input.NewInput(),
 31}
 32
 33func lerp(start, end, t float64) float64 {
 34 return start + t*(end-start)
 35}
 36
 37func main() {
 38 client := coldbrew.NewClient(
 39  640,
 40  360,
 41  10,
 42  10,
 43  10,
 44  assets,
 45 )
 46 client.SetTitle("Capturing Gamepad Inputs")
 47 err := client.RegisterScene(
 48  "Example Scene",
 49  640,
 50  360,
 51  exampleScenePlan,
 52  []coldbrew.RenderSystem{},
 53  []coldbrew.ClientSystem{},
 54  []blueprint.CoreSystem{
 55   &inputSystem{},
 56  },
 57 )
 58 if err != nil {
 59  log.Fatal(err)
 60 }
 61 client.RegisterGlobalRenderSystem(coldbrew_rendersystems.GlobalRenderer{})
 62 client.RegisterGlobalClientSystem(coldbrew_clientsystems.InputBufferSystem{})
 63 client.ActivateCamera()
 64 receiver, _ := client.ActivateReceiver()
 65 receiver.RegisterPad(0)
 66 receiver.RegisterGamepadAxes(true, actions.Movement)
 67
 68 receiver.RegisterGamepadButton(ebiten.GamepadButton4, actions.Up)
 69 receiver.RegisterGamepadButton(ebiten.GamepadButton0, actions.Down)
 70
 71 receiver.RegisterGamepadButton(ebiten.GamepadButton1, actions.Right)
 72 receiver.RegisterGamepadButton(ebiten.GamepadButton3, actions.Left)
 73
 74 if err := client.Start(); err != nil {
 75  log.Fatal(err)
 76 }
 77}
 78
 79func exampleScenePlan(height, width int, sto warehouse.Storage) error {
 80 spriteArchetype, err := sto.NewOrExistingArchetype(
 81  input.Components.InputBuffer,
 82  spatial.Components.Position,
 83  client.Components.SpriteBundle,
 84 )
 85 if err != nil {
 86  return err
 87 }
 88 err = spriteArchetype.Generate(1,
 89  input.Components.InputBuffer,
 90  spatial.NewPosition(255, 20),
 91  client.NewSpriteBundle().
 92   AddSprite("sprite.png", true),
 93 )
 94 if err != nil {
 95  return err
 96 }
 97 return nil
 98}
 99
100type inputSystem struct {
101 StickX float64
102 StickY float64
103}
104
105func (sys *inputSystem) Run(scene blueprint.Scene, dt float64) error {
106 query := warehouse.Factory.NewQuery().
107  And(input.Components.InputBuffer, spatial.Components.Position)
108
109 cursor := scene.NewCursor(query)
110
111 for range cursor.Next() {
112  pos := spatial.Components.Position.GetFromCursor(cursor)
113  inputBuffer := input.Components.InputBuffer.GetFromCursor(cursor)
114
115  if stampedMovement, ok := inputBuffer.ConsumeInput(actions.Movement); ok {
116   sys.StickX = float64(stampedMovement.X)
117   sys.StickY = float64(stampedMovement.Y)
118
119   magnitude := math.Sqrt(sys.StickX*sys.StickX + sys.StickY*sys.StickY)
120   deadzone := 0.15
121
122   if magnitude > deadzone {
123    if magnitude > 1.0 {
124     sys.StickX /= magnitude
125     sys.StickY /= magnitude
126    }
127
128    const moveSpeed = 3.0
129    pos.X += sys.StickX * moveSpeed
130    pos.Y -= sys.StickY * moveSpeed
131   }
132  }
133
134  moveSpeed := 2.0
135
136  if _, ok := inputBuffer.ConsumeInput(actions.Up); ok {
137   pos.Y -= moveSpeed
138  }
139  if _, ok := inputBuffer.ConsumeInput(actions.Down); ok {
140   pos.Y += moveSpeed
141  }
142  if _, ok := inputBuffer.ConsumeInput(actions.Left); ok {
143   pos.X -= moveSpeed
144  }
145  if _, ok := inputBuffer.ConsumeInput(actions.Right); ok {
146   pos.X += moveSpeed
147  }
148 }
149
150 return nil
151}