[HELP] Problem to understand how implement Joystick/Controller works

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
nice
Party member
Posts: 188
Joined: Sun Sep 15, 2013 12:17 am
Location: Sweden

[HELP] Problem to understand how implement Joystick/Controller works

Post by nice » Mon Jun 17, 2019 4:45 pm

Hello everyone!
I'm currently working on a game where I want to use a gamepad (in this case an Xbox 360 controller) where I have a square that I want to move using the triggers on the controller. But I have a problem understanding how to use "Joystick".

How I want it to work is that I want the input to happen in a function such as "love.joystickaxis(joystick, axis, value)" and the movement update to happen in "love.update(dt)". What I have right now is that I have variables according to directions that are false in the beginning:

Code: Select all

  local isLeftHeld
  local isRightHeld
  local isUpHeld
  local isDownHeld
  
  isLeftHeld = false
  isRightHeld = false
  isUpHeld = false
  isDownHeld = false
And then in the love.joystickaxis function I have the input happen:

Code: Select all

function love.joystickaxis(joystick, axis, value)

local Joysticks = love.joystick.getJoysticks()

  for i, joystick in ipairs(Joysticks) do
    if joystick:isGamepad() then
      local RIGHT = joystick:getGamepadAxis('triggerright')
      local LEFT = joystick:getGamepadAxis('triggerleft')
      if RIGHT then
        print('banana boat going right')
        isRightHeld = true
      end
      if LEFT then
        print('banana boat going left')
      end
    end
  end
end
And in love.update(dt) I have a bool that checks if a direction is true:

Code: Select all

  if isLeftHeld == true then
    Tank.Theta = Tank.Theta - Tank.rotationSpeed * dt
  elseif isRightHeld == true then
    Tank.Theta = Tank.Theta + Tank.rotationSpeed * dt
  end
What actually happens is that as soon as I run my game, it prints a bunch print checks to confirm that input happens (ex: "Banana boat turns left" or "Banana boat turns right") and if I press one of the triggers it prints both of my print checks. This causes my square to rotate automatically and nothing happens if I press the triggers.

I have isolated that the problem lies in my "if isLeftHeld == true" is the problem by moving the movement code into the "love.joystickaxis" and then it works kinda okay but I don't want the movement to happen in that function.


Why do I get a bunch of prints in the beginning and what am I doing wrong?

Full code

Code: Select all

  local isLeftHeld
  local isRightHeld
  local isUpHeld
  local isDownHeld
  local isForwardHeld
  
  isLeftHeld = false
  isRightHeld = false
  isUpHeld = false
  isDownHeld = false
  isForwardHeld = false

function love.load()
  r = 0
  
  Tank = {}
  -- Basically a new sprite (48x80)
  Tank.Body = love.graphics.newImage("Graphics/tempPlayer.png")
  -- Tank Body's position on X/Y
  Tank.posX = love.graphics:getWidth() * 0.5
  Tank.posY = love.graphics:getHeight() * 0.5
  -- Tank Radians (or Rotation)
  Tank.Radians = 0
  -- Scales up (or down) the size of sprite on X/Y
  Tank.scaleFactorX = 1
  Tank.scaleFactorY = 1
  -- Changes origin from where the Sprite is drawn
  Tank.originOffsetX = 0
  Tank.originOffsetY = 0
  
  -- Tank's Width/Height
  Tank.Width = Tank.Body:getWidth()
  Tank.Height = Tank.Body:getHeight()
  
  -- Tank Speed/Velocity
  Tank.rotationSpeed = 5
  Tank.Velocity = 0
  
  -- Tank Direction
  Tank.Direction = 1
  Tank.currentDirection = Tank.Direction
  Tank.Theta = 4.71 -- Angle / Angle area
  
end

function love.update(dt)
  r = r + 1 * dt
  p1Joystick = nil
  
  -- m = math
  local mCos = math.cos
  local mSin = math.sin
  
  local pos = {}
  pos.X = Tank.posX
  pos.Y = Tank.posY
  pos.Theta = Tank.Theta
  

  if isLeftHeld == true then
    Tank.Theta = Tank.Theta - Tank.rotationSpeed * dt
  elseif isRightHeld == true then
    Tank.Theta = Tank.Theta + Tank.rotationSpeed * dt
  end
  
  if isForwardHeld == true then 
    Tank.Velocity = Tank.Velocity + 5 * dt
  end
  
  Tank.posX = Tank.posX + mCos(Tank.Theta) * Tank.Velocity
  Tank.posY = Tank.posY + mSin(Tank.Theta) * Tank.Velocity
  
end

function love.draw()
  love.graphics.print("HELLO, WORLD!", 400, 300, r)
  
  love.graphics.draw(Tank.Body, 
                     Tank.posX, 
                     Tank.posY,
                     Tank.Theta,
                     Tank.scaleFactorX,
                     Tank.scaleFactorY,
                     Tank.originOffsetX,
                     Tank.originOffsetY)
end

function love.joystickaxis(joystick, axis, value)

local Joysticks = love.joystick.getJoysticks()

  for i, joystick in ipairs(Joysticks) do
    if joystick:isGamepad() then
      local RIGHT = joystick:getGamepadAxis('triggerright')
      local LEFT = joystick:getGamepadAxis('triggerleft')
      if RIGHT then
        print('banana boat going right')
        isRightHeld = true
           --Tank.Theta = Tank.Theta - Tank.rotationSpeed
      end
      if LEFT then
        print('banana boat going left')
      end
    end
  end
end

function love.gamepadpressed(joystick, button)
 -- if joystick:isGamepadDown('triggerleft') then
  --  isLeftHeld = true
 -- end
end

function love.gamepadreleased(joystick, button)
  
end

function love.keypressed(key)
  if key == 'left' then
    isLeftHeld = true
  end
  if key == 'right' then
    isRightHeld = true
  end
  --[[
  if love.keyboard.isDown('left', 'right') then
    isForwardHeld = true
  end
  ]]
end

function love.keyreleased(key)
  if key == 'left' then
    isLeftHeld = false
  end
  if key == 'right' then
    isRightHeld = false
  end

end
:awesome: Have a good day! :ultraglee:

User avatar
ReFreezed
Citizen
Posts: 75
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: [HELP] Problem to understand how implement Joystick/Controller works

Post by ReFreezed » Wed Jun 19, 2019 2:40 am

joystick:getGamepadAxis() returns a number, not a boolean, which is why both prints trigger.

Don't bother using love.joystickaxis() if you just want to know the current value of a joystick axis in love.update() - simply call joystick:getGamepadAxis() inside love.update(). love.joystickaxis() gets called when the value of an axis changes for a joystick.

Also note that you never reset isRightHeld or isLeftHeld unless the keyboard is used.
Tools: LuaPreprocess, LuaHotLoader
Games: Momento Temporis: Light from the Deep, Momento Temporis: Arena, Energize!
"If each mistake being made is a new one, then progress is being made."

Post Reply

Who is online

Users browsing this forum: No registered users and 11 guests