Wrong behavior when trying to move on air

I´m using Andengine and jBox2D to implement a Mario-like platform videogame. Jumping and moving works fine. The problem comes in a very specific case:

1. I keep the "Move left" button pressed all the time
2. Player is on air and when moving left, it hits a wall and it stops moving left (while it keeps falling) This is correct.
3. When the player passes the wall, if the "Move left" button is pressed, it should start moving left while falling but it doesn't. If I lift my finger and press "Move left" again, it works.

The code to move left/right is:

_playerBody.setLinearVelocity(-mLinearVelocityX, _playerBody.getLinearVelocity().y);


The jump code is:

_playerBody.applyLinearImpulse(0, -mImpulseY, _playerBody.getPosition().x, // /////JUMP
_playerBody.getPosition().y);


This is the code for the hud:

Sprite left = new Sprite(-10, CAMERA_HEIGHT - 150, mLeftTextureRegion) {
@Override
public boolean onAreaTouched(TouchEvent pEvent, float pX, float pY) {

if (!pEvent.isActionOutside() && !isDead && !isPaused) {
movePlayerLeft(player_self_sprite, player_self_body);
}

if (pEvent.isActionUp())  {
if (isPlayerMoving) {
stopPlayer(player_self_sprite, player_self_body);
isPlayerMoving = false;
}
}
return true;
}
};

• The hud is fine, the "TouchEvent" needs a callback for when the button is continued to be pressed! Thus when the wall is left, the 0 velocity from the jump event is again replaced with the "TouchEvent". Oct 22 '15 at 17:48

I don't see the entire game loop and how the positions are updated. But it appears that your player is still in jump mode and x velocity is set to 0 as the previous impulse of -mLinearVelocityX is overridden at some point and the input is not refreshed. As you probably have an algorithm to detect a collision, try something like that:

if (contact_with_wall) x_case = 0; else {x_case=-mLinearVelocityX;}

_playerBody.applyLinearImpulse(x_case, -mImpulseY, _playerBody.getPosition().x, // /////JUMP
_playerBody.getPosition().y);

• I think it has to do with the "Hud" becase it works normally when I lift and press again. I included the code for it Oct 22 '15 at 17:33
• I don't know which hud you use, but depends on your input code, do you have something like if (button_state==down) ? You seem to have only collected the impulse, i.e. if (button==pressed) and when you then override the velocity with 0 in x direction, that input is no more. Note: The above solution is a workaround if you do not have a proper callback for a button continuing to be pressed. Oct 22 '15 at 17:46
• Thanks, It worked with some corrections. I was detecting the isJumping with a sensor in the feet and I had to include a check to set x_case accordingly when the feet was on air and the whole body of the player was not touching a wall. Oct 23 '15 at 16:30
• You are welcome, although, try to look into button_down and button_up input callbacks, as then you avoid many complications in future, as what gets overriden, bounces back once you stop pressing the key. Oct 24 '15 at 1:19

It seems that when the collision on the wall occurs, your code is resetting the speed of the character to zero.

I see two possible solutions:

1. Do not reset the speed, but just relocate the position of the character out of the wall. This way, the speed before the collision is preserved and once the obstacle is out of the way, the character will return to move. I think Mega Man games are like that.

2. Have a method on state of the character to update every frame and in it check if the diracional is hold and then apply the speed.X of the character.