Davidobot / love.js

LÖVE ported to the web using Emscripten, updated to the latest Emscripten and LÖVE (v11.5)
MIT License
624 stars 28 forks source link

Controller Support #71

Open 44100hertz opened 1 year ago

44100hertz commented 1 year ago

Wrap the Web Gamepad API to the Love Joystick API and I would be very happy.

Davidobot commented 1 year ago

This should work out the box with SDL? Maybe we're on an old version of it.

44100hertz commented 1 year ago

:thinking: Maybe I should write a gamepad test...

Saturn91 commented 1 year ago

Am I correct that controllers are not supported currently? ;-)

idbrii commented 1 year ago

Gamepads have worked for quite a while, but maybe with bugs. My lovejs web builds are playable with gamepad even back on this 2021 project: https://idbrii.itch.io/explorb (It seems I had some web-only problem getting initial gamepad input, but moving and launching the ball with gamepad works.)

wiredmatt commented 1 year ago

A minimal example doesn't seem to work on the web, it does for desktop build. No console errors or warnings.

local joystick, position, speed

function love.load()
  local joysticks = love.joystick.getJoysticks()
  joystick = joysticks[1]

  position = { x = 400, y = 300 }
  speed = 300
end

function love.update(dt)
  if not joystick then return end

  if joystick:isGamepadDown("dpleft") then
    position.x = position.x - speed * dt
  elseif joystick:isGamepadDown("dpright") then
    position.x = position.x + speed * dt
  end

  if joystick:isGamepadDown("dpup") then
    position.y = position.y - speed * dt
  elseif joystick:isGamepadDown("dpdown") then
    position.y = position.y + speed * dt
  end
end

function love.draw()
  love.graphics.circle("fill", position.x, position.y, 50)
end

doing print(joystick) returns nil to the browser console.

doing like this:

function love.joystickadded(joystick)
  gamepad = joystick
end

will at least output something in the console, however if gamepad:isGamepadDown("...") doesn't seem to get picked up

function love.gamepadpressed(joystick, button)
  print("pressed" .. button)
end

with gamepadpressed, on buttons (x,a,b,y) you'll get output.

However, no dpad or sticks detected.

Final update:

Got it working, the key is to use getGamepadAxis instead, I suggest this gets added to the docs, even if it was easy to figure out some people might get demotivated immediately by not having proper gamepad support

local joystick, position, speed

function love.load()
  position = { x = 400, y = 300 }
  speed = 300
end

function love.joystickadded(_joystick)
  joystick = _joystick
end

function love.update(dt)
  print(joystick)

  if not joystick then return end

  position.x = position.x + speed * dt * joystick:getGamepadAxis("leftx")
  position.y = position.y + speed * dt * joystick:getGamepadAxis("lefty")
end

function love.draw()
  love.graphics.circle("fill", position.x, position.y, 50)
end