1
\$\begingroup\$

I'd like to implement an event listener that triggers character movement (left/right/up/down or stay) according to the direction of pushed axis on the joystick. Due to jittering, the approach I found is to set area near (0, 0) as dead zone. However, by this approach, I can't tell when the axis is no longer pushed and goes back to the center. It's a very typical usage of joystick axis but I couldn't find helpful info elsewhere. Thanks in advance.

\$\endgroup\$
1
\$\begingroup\$
struct ClassName
{
    static SDL_Joystick* controller;
    static Sint16 axis_x, axis_y;

    // ...initializes everything ...

    inline static void set_axis(const SDL_Event& e)
    {
        if(e.jaxis.which == 0) {
            axis_x = SDL_JoystickGetAxis(controller, 0); // 0 indicates x
            axis_y = SDL_JoystickGetAxis(controller, 1); // 1 indicates y
        }
    }
};

Then, inside the poll-event loop:

while(SDL_PollEvent(&e)) {
    // ..
    if(ClassName::controller)
        if(e.type == SDL_JOYAXISMOTION) ClassName::set_axis(e);
}

Now put this somewhere to get the specific dead zone range:

printf("AX: %d AY: %d\n", ClassName::axis_x, ClassName::axis_y);
\$\endgroup\$
  • \$\begingroup\$ I think I didn't make my question clear. The dead zone is set by myself, I'm looking for a way to determine when the axis is back to center while avoiding spurious motion detection. \$\endgroup\$ – ymfoi Jan 22 '18 at 0:25
  • \$\begingroup\$ if(dead_zone < 0 || dead_zone > 0) // do something else // do nothing is this what you are looking for?? \$\endgroup\$ – Dormin Jan 22 '18 at 0:32
0
\$\begingroup\$

My experience is from working on a gamepad wrapper interfacing with the GLFW library, which appears to have a similar joystick API to SDL.

It can be difficult to discern the difference between a jittery unused joystick and someone slightly nudging it. For this situation, we can rely on duration as a practically differentiating factor i.e. a user likely won't be imitating a jittery yet resting joystick for very long.

This basically means you'll have to keep track of the joystick's previous position and a timestamp of the position when it enters the dead zone. Each time you resolve joystick motion, you'll have to check if the joystick has been in the dead zone for a length of time you decide on. The following pseudo code might help imagine what the reasoning could look like.

if (isInDeadZone()) {

    if (wasNotInDeadZonePreviously()) {
        // Just entered dead zone so record the time

    } else if (hasBeenInDeadZoneLongEnough()) {
        // Assume the user let go of the joystick

    } else {
        // Here the joystick's been in the dead zone but not enough time 
        // has passed to consider the possibility that it was released. 
        // This last clause isn't necessary for finding what you want and 
        // is only here to clarify what happens when the logic falls
        // through.
    }

} else {
    // Someone is presumably using the joystick
}

Of course, the idea above could create false positives when the user manually holds a joystick within the dead zone for long enough. One way to guard against this is to have the dead zone customizable so it can be lowered as much as possible per joystick in order to make it harder to accidentally trigger the resting state.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.