Gamepad stick input

Is it possible to get both the x and y stick input values with the same input event?

No, they’re separated by axis.
But you should be able to store the value as usual, by using addition?

function update(self, dt)
    self.input = vmath.vector3(0,0,0)
end

function on_input(self, action_id, action)
    if action_id == hash("LSTICK_UP") then
        self.input.y =  self.input.y + action.value
    elseif action_id == hash("LSTICK_DOWN") then
        self.input.y =  self.input.y - action.value
    elseif action_id == hash("LSTICK_LEFT") then
        self.input.x =  self.input.x - action.value
    elseif action_id == hash("LSTICK_RIGHT") then
        self.input.x =  self.input.x + action.value
    end
end

(Untested code, but you get the idea)

3 Likes

Yes, no problem in creating a vector from signed scalar values.

The point is that, in this way, the input is invalid in the interval from the first input event, say for the x axis, and the second input event, say for the y axis. I hope this make sense.

Well, no. You will receive all input events before you get the next update.

Okay, thanks! This is reassuring! Ciao!

Sorry but shouldn’t it be separated into 2 separate conditional statements? One per axis?

Like

function on_input(self, action_id, action)
    if action_id == hash("LSTICK_UP") then
        self.input.y =  self.input.y + action.value
    elseif action_id == hash("LSTICK_DOWN") then
        self.input.y =  self.input.y - action.value
    end

if action_id == hash("LSTICK_LEFT") then
        self.input.x =  self.input.x - action.value
    elseif action_id == hash("LSTICK_RIGHT") then
        self.input.x =  self.input.x + action.value
    end
end

That way both can be checked not only independent of each other but also at the same time.

During a frame you will get multiple calls to on_input, one per triggered binding. In your code example you assume that action_id will change during a single call to on_input. If you think about it it can’t really happen can it? The action_id will be either up, down, left or right. It will not be both up/down and left/right.

5 Likes

You’re not really being fair in your assumption are you?
Have you ever played an arcade game*? You know how they have 8 way directional joysticks? Diagonal inputs are up or down in tandem with left or right. Diagonal inputs are just as valid as perpendicular ones. You’re definitely not thinking like a gamer might be thinking.

Even in the provided 2d platformer tutorial if you were to map the jump to the up direction of a joystick and movement to the left or right directions of a joystick you’d require both to be able to jump to the left or right. In fact in Defold I have actually used this configuration with that tutorial.

Back to the arcade example, a real world application of this input logic in programmed use, you have the arcade game of Solomon’s Key. In that game you jump with the up direction on the joystick and you move left or right with the same joystick.

Also see this:

Not sure what you mean here.
Björn’s comment wasn’t about game logic, but the behavior of a joystick axis, and also about this particular function:

  1. we mention that all input events collected during the frame will generate a call to on_input. So, you might get a left and then a right event. Hence the suggestion to use addition to handle such a case.
  2. During a function call, the input argument action_id won’t change, so the if-statement doesn’t need to be split up.

Have you ever played an arcade game*? You know how they have 8 way directional joysticks? Diagonal inputs are up or down in tandem with left or right. Diagonal inputs are just as valid as perpendicular ones. You’re definitely not thinking like a gamer might be thinking.

I’d like to ask you to be a little more mindful of the tone as well, if you wouldn’t mind please. .We’d like to keep an as friendly and approachable forum as possible here.

2 Likes

I am unsure how your example invalidates Björns point that its not possible to move your physical Left Joystick in both the up and down direction at the same time.

If you remap what the left joystick does to a different key and use that instead you are no longer using the left joystick :thinking:

3 Likes

Writing it as two separate conditional statements is logically equivalent to the original one, regardless of game engine implementation or language.

1 Like

I was merely pointing out that you are wasting CPU cycles by splitting the conditional action_id check in on_input().

If you move an analog stick, arcade controller or an old classic c64 joystick up-left you will get one reading of the horizontal axis (left) and one of the vertical (up), and in Defold this translates to two (2) calls to on_input(), on for left/right and one for up/down.

The effect of splitting the conditional check in two (up/down and left/right) is that for each of the above mentioned calls to on_input() you have to check two if-elseif-end conditionals instead of one.

It has little impact performance wise, but I thought I should point out the flaw in the logic since you specifically advocated for splitting it.

3 Likes

So, it will completely ignore the second set of conditional statements with in the one call?

Yes, if you have one long if-elseif-end with all four directions the interpreter will go through them one by one until it finds a match. If a match is found it will enter the body of that condition and run the code and then exit. It will not check the conditions below the matching one.

It might be that the compiler does something smart in the case of two if-elseif-end checks of the same variable. But probably not.

Technically with the placement vectors you’re not dealing with one variable. You’re dealing with two or three variables. One variable for each vector, right? With regards to input it would be 2 variables one of each of the axis vectors being read by the joystick.

Do your conditional statements have a hidden embedded return?