# SDL Input not behaving as expected.

This topic is 912 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm currently developing a game using SDL and at the moment I have a character on the screen who's expected behaviour is:

1. to accelerate to the left when pressing left and slow down when left has been let go until he stops.

2. accelerate to the right when right is pressed and slow down when right has been let go until he stops.

3. if left and right are being pressed do nothing.

He does 1 and 2 partially, in the sense that he does not stop when the button is released and after pressing right after left, the buttons become reversed (left now moves him right and right now moves him left) he then behaves as expected (with the reversed buttons).

This says to me that something isn't being initialized correctly and once mapped the buttons work as expected.

(apologies for the bad explanation, it's hard to describe).

Game.cpp: http://pastebin.com/Ckj6sNaN

Player.cpp: http://pastebin.com/upv1BZNR

Input.cpp: http://pastebin.com/j9if5b0m

Any help clearing this up would be most appreciated, It's been bugging me for hours -_-

##### Share on other sites

As far as I understand it, it looks like you've swapped the bodies of keyUpEvent and keyDownEvent.

##### Share on other sites

Yes, as Kercyn says, your keyUpEvent and keyDownEvent are indeed swapped.

Also, just as an example, I'll post a different way you could do it.

void Player::update(int elapsed_time_ms)
{
sprite->update(elapsed_time_ms);

//OK, this 2 variables don't exist in your code (user_pressed_left and user_pressed_right), but they are
//simply bools that are set, if the left or right keys are pressed.

//EDIT: Here, there's no 'else' in the second 'if', because if the user is pressing both directional keys,
//      the acceleration gained from both will cancel each other, and will behave as if no key is pressed.
//Update acceleration based on user input
if(user_pressed_left)
acceleration_x_ -= kWalkingAcceleration * elapsed_time_ms;
if(user_pressed_right)
acceleration_x_ += kWalkingAcceleration * elapsed_time_ms;

//Make sure that the acceleration doesn't exceed the maximum speed
if(acceleration_x_ > kMaxSpeedX)
acceleration_x_ = kMaxSpeedX;
//Same goes for negative acceleration (moving left)
//EDIT: Added 'else' here, because acceleration can only be either max positive or max negative
else if(acceleration_x_ < -kMaxSpeedX)
acceleration_x_ = -kMaxSpeedX;

//Update player's position
x_ += acceleration_x_;

//Now, you can apply kSlowdownFactor (AKA friction).
//The simplest way, is to check if the player has not pressed any direction buttons (or both),
//and apply friction if so.
if((!user_pressed_left && !user_pressed_right) ||  //No keys pressed
( user_pressed_left &&  user_pressed_left )   ) //Both keys pressed
{

//EDIT: If the acceleration is 0.0f, then the player is already stopped, so don't apply friction
//      By the way, be careful with equal comparison of floating point numbers.
if(acceleration_x_ == 0.0f)
break;

//If acceleration is negative, apply friction to get it closer to 0.0f
if(acceleration_x_ < 0.0f)
{
//EDIT: If acceleration is bigger than friction, then just apply it
if(acceleration_x_ < -kSlowdownFactor)
acceleration_x_ += kSlowdownFactor;
//EDIT: But if acceleration would become positive, then just set it to 0.0
else
acceleration = 0.0f;
}

//Same goes for positive acceleration
else if(acceleration_x_ > 0.0f)
{
//EDIT: If acceleration is bigger than friction, then just apply it
if(acceleration_x_ > kSlowdownFactor)
acceleration_x_ -= kSlowdownFactor;
//EDIT: But if acceleration would become negative, then just set it to 0.0
else
acceleration = 0.0f;
?        }

}

//Keep player within screen bounds
if(x_ < 0)
x_ = 0;
else if(x_ > 640)
x_ = 600;
}

void Player::startMovingLeft()
{
user_pressed_left = true;
}

void Player::startMovingRight()
{
user_pressed_right = true;
}

void Player::stopMoving()
{
//Do nothing
return;
}


Note that you don't need the velocity variable this way

This code is untested, so sorry if there're any errors.

I hope the explanation is concise, but if it's not (or you have any doubt) hit me up, and I'll try to explain better,

Hope it helps.

EDIT: I forgot one thing, and that is to stop applying friction when the acceleration would become 0.0. The way it is now, the player would "wiggle" in place, due to the fact that acceleration keeps jumping from positive to negative.

Also added a few "else" to make the code a bit more efficient.

Sorry for the mistake.

Edited by __SKYe

##### Share on other sites

Thank you both for your input on this! it solved it!

I really appreciate you taking the time to look at my question :)

Euden

1. 1
2. 2
3. 3
Rutin
19
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633657
• Total Posts
3013197
×