Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Fluid object movement with gamepad stick [problem]

This thread is locked; no one can reply to it. rss feed Print
Fluid object movement with gamepad stick [problem]
gamedevmike
Member #16,733
September 2017
avatar

Hello.
I'm creating a simple fighter game with Allegro 5. One of my basic establishments was the possibility to use gamepads (they feel more comfortable in fighters, don't they).

The problem I encountered is that I somehow cannot make my character move (right, left) fluently when the left stick is held (position 1.0 or -1.0 on axis 0, stick 0).

Here's how I'm trying to achieve it:

#SelectExpand
1if( event.type == ALLEGRO_EVENT_TIMER ) 2{ 3 al_get_joystick_state( joy1, &gamepadstate ) 4 if( gamepadstate.stick[0].axis[0] && event.joystick.pos == 1.0 ) position += movespeed; 5 if( gamepadstate.stick[0].axis[0] && event.joystick.pos == -1.0 ) position -= movespeed; 6}

This is based on keyboard movement procedure, which looks like this:

#SelectExpand
1if( event.type == ALLEGRO_EVENT_TIMER ) 2{ 3 if( al_key_down( &keystate, ALLEGRO_KEY_RIGHT ) ) position += movespeed; 4 if( al_key_down( &keystate, ALLEGRO_KEY_LEFT ) ) position -= movespeed; 5}

Unfortunately, such an approach does not work.
if(gamepadstate.stick[0].axis[0]) cout << event.joystick.pos; shows some float number from 0.2 to 0.7 (approximately, hardly ever reaches 1) when I move the stick. The number is always non-negative, no matter if I flick my stick left or right.

Position output is valid under
if( event.type == ALLEGRO_EVENT_JOYSTICK_AXIS )
but there's no fluid move either. One object (character) position change on one flick, nothing more when held (which is completely expected ofc).

And finally some questions.
Is there anything I missed?
Is my approach any good?
What don't I understand here?
Could I get any advice on how to move my character with gamepad stick?

Thanks in advance. Sorry if I'm unclear anywhere.

Edgar Reynaldo
Member #8,592
May 2007
avatar

beoran
Member #12,636
March 2011

An analog stick may not report an axis at a full 1.0 or - 1.0. This is normal for analog sticks since they can sense how much you are tilting the stick. In stead of comparing with 1, set a threshold for motion >0.1 or so.

gamedevmike
Member #16,733
September 2017
avatar

Thanks for answers.
I wondered if there's a ready resolution to use.

@beoran Tried this. It's not the case.

Audric
Member #907
January 2001

The error is that for ALLEGRO_EVENT_TIMER event, you are allowed to read event.timer, but not event.joystick - the latter will read as "garbage" data.

You can use something like this:

#SelectExpand
1if( event.type == ALLEGRO_EVENT_TIMER ) 2{ 3 bool controler_left = 0; 4 bool controler_right = 0; 5 // poll keyboard 6 ALLEGRO_KEYBOARD_STATE keystate; 7 al_get_keyboard_state(&keystate); 8 if( al_key_down( &keystate, ALLEGRO_KEY_RIGHT ) ) controler_right = 1; 9 if( al_key_down( &keystate, ALLEGRO_KEY_LEFT ) ) controler_left = 1 ; 10 11 // poll joystick 12 al_get_joystick_state( joy1, &gamepadstate ); 13 float axis_x = gamepadstate.stick[0].axis[0]; 14 if( axis_x > 0.3) controler_right = 1; 15 if( axis_x < -0.3) controler_left = 1; 16 17 // logic 18 if (controler_right && !controler_left) position += movespeed; 19 if (controler_left && !controler_right) position -= movespeed; 20 21}

The alternative is skip the part where you poll the entire keyboard/joystick, and instead react to the events, for example :

if( event.type == ALLEGRO_EVENT_JOYSTICK )
{
   // A movement of the horizontal axis on first joystick
   if (event.joystick.stick == 0 && event.joystick.axis == 0)
   {
      float axis_x = event.joystick.pos;
      if( axis_x > 0.3) controler_right = 1;
      if( axis_x < -0.3) controler_left = 1;
   }
}

Go to: