Simple Jumping Code Problem


Godmil

Active Member
Joined
May 6, 2006
Messages
585
Website
www.godmil.com
Hello, I've only recently started to learn how to code, and I'm totally stuck on something that seems very simple. I've been following the Lazy Foo tutorials and decided to adapt this one to give the moving ball some gravity and get it to jump (in a Manic Miner sort of way - so no directional controls mid air).
It was going well, but if you take your fingers off the keys while the ball is in mid air, when it lands it will keep moving in the direction it was going in (until it hits a wall or you press another key). I cant for the life of me undersand why, could someone help please?

Here are the main bits of code:

I have a few int constants (MOVINGVEL, JUMPINGVEL, and GRAVITY), and 'jumping' is a bool set in the dot class.

Code:
void Dot::handle_input()
{ 
	// Stops the dot moving when no keys are pressed
	if (jumping == false)
	{
	   yVel=0;
	   xVel=0;
	}  
	//initialise keystates
	Uint8 *keystates = SDL_GetKeyState( NULL );
	if ( keystates[ SDLK_LEFT ] && jumping == false)
	{
	   xVel=-MOVINGVEL;
	}
	if ( keystates[ SDLK_RIGHT ] && jumping == false)
	{
	   xVel=MOVINGVEL;
	}	
	if ( keystates[ SDLK_UP ] && jumping == false)
	{
	   yVel=-JUMPINGVEL;
	   jumping = true;
	}	
}

void Dot::show()
{
	//Move the dot left or right
	x += xVel;
	
	//If the dot went too far to the left or right
	if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) )
	{
		//move back
		x -= xVel;	
	}
	
	//Move the dot up or down
	y += yVel;
	
	if (jumping == true)
	{
	yVel += GRAVITY;
	}
	
	//If the dot went too far up or down
	if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
	{
		//move back
		if (jumping == true)
		{
		   y -= (yVel - GRAVITY);
		}
		else y -= yVel;
		jumping = false;
	}
	//Show the dot
	apply_surface( x, y, dot, screen );
}

It's like the 'jumping=false' near the bottom isn't being picked up by the conditional near the top, unless another button is pushed first.
exe and full program attached here (edit: had to remove full program, goes against Lazy Foo's copyright)
I'd be soo greatful if anyone could help me, I'd hate to lose my motivation due to something so small :(
Thanks,
Godmil
 
Try extra parenthesis, not sure if it'll make a difference.. i'll keep checking:

EDIT: probably won't make a difference, just checked and presendence says == is before &&

if ( keystates[ SDLK_LEFT ] && (jumping == false))
{
xVel=-MOVINGVEL;
}
if ( keystates[ SDLK_RIGHT ] && (jumping == false))
{
xVel=MOVINGVEL;
}
if ( keystates[ SDLK_UP ] && (jumping == false))
{
yVel=-JUMPINGVEL;
jumping = true;
}
}

are you sure the input handler is being called?

you could try a printing out the value of 'jumping' at crucial points to test if it's being changed.
 
Last edited by a moderator:
Code:
	//Move the dot up or down
	y += yVel;
	
	if (jumping == true)
	{
	yVel += GRAVITY;
	}
	
	//If the dot went too far up or down
	if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
	{
		//move back
		if (jumping == true)
		{
		   y -= (yVel - GRAVITY);
		}
		else y -= yVel;
		jumping = false;
	}

if jumping == true y -= yVel; doesn't get done so take out the else

The jumping = false is dodgy too - this will happen if the dot goes off the top of the screen.
 
ooh good suggestions thanks... I think I have a better idea of what's going wrong now, and I'm afraid I didn't give you the relevant info...
this is the section that calls those function from the main loop...

Code:
//While there's events to handle
		while( SDL_PollEvent( &event ) )
		{
			//Handle events for the dot
			myDot.handle_input();
			
			//If the user has Xed out the window
			if( event.type == SDL_QUIT )
			{
				//Quit the program
				quit = true;
			}
		}
It occured to me, it only does the input handling if there is an event to trigger it (I noticed I could stop the dot sliding by moving the mouse over the window).
YAY fixed it :D
I tried adding a xVel=0 after my jumping=false line (at the bottom), which partially worked, but after each jump there would be one little x movement before it stopped, so I changed the order of the movement code, so it did the y direction (with the xVel=0 if it's the end of a jump) then the x direction. Now works like a dream :D
Thanks guys

EDIT: actually now if you hold the left or right arrow and jump, when you land you have to hit the key again to make it keep move... manalive this coding malarky is tricky :(
 
EDIT: actually now if you hold the left or right arrow and jump, when you land you have to hit the key again to make it keep move... manalive this coding malarky is tricky :(

not sure how sdl input works but it sounds like the input handler is only being called on a key press or release, i.e. you've set xVel = 0, and it won't change until there's been another input event (releasing then pressing the button).
 
Last edited by a moderator:
yeah, you're right, it's the exact same problem I had before, I need to give it an event before it does anything. I guess I could remove the "while( SDL_PollEvent( &event ) )" bit, and have it checking for keystates constantly, but I guess that would slow everything down. :/
 
SDL key events are returned when a key is pressed or released. You can test the event type

event.key.type is SDL_KEYDOWN or SDL_KEYUP

Same for joystick buttons

event.jbutton.type is SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
 
Cool thanks. So, how does everyone else take key inputs... is it typical to check for keystates, and do you wait for events before checking, or should they be checked constantly?
 
There isn't a right and wrong way, I've seen both done.

Looking at other code, I think you should just use SDL_PumpEvents(); in a loop rather than SDL_PollEvent(&event);
 
Back
Top