Hello again! I am trying to make a jump and run game using SDL, but I am stuck at the jumping part. Whenever I press the Up key, the sprite should go up. However, when I press it, it goes down. I have changed it and done math that should make it go up, but it does nothing. I have also a loop that while jumping, decreases the value of the variables for gravity. But if I have it set up as a loop (I use the "while" command), nothing happens. But if I change "while" to "if", the sprite jumps! Unfortunately, it only runs the math for my "gravity" once and every button pressed after that increases the Y value. (Which is weird). I know this is once again something small that I missed, or maybe I did it wrong. Please help. Here is my code:

Wolf::Wolf()
{

    offSet = 0;
    velocity = 0;
    posy = 275;
    vely = 0;
    accel = 10;
    jump = false;

    frame = 0;
    status = WOLF_RIGHT;
}

void Wolf::get_keystate()
{	
	Uint8 *keystates = SDL_GetKeyState( NULL );
	if( event.type == SDL_KEYDOWN )
	{
		if( keystates [SDLK_RIGHT] )
		{
			velocity +=  WOLF_WIDTH / 4;
		}
		if( keystates [SDLK_LEFT] )
		{
			velocity -= WOLF_WIDTH / 4;
		}
	
	  if( keystates [SDLK_UP] )
	  {
		vely = 100;
		posy = posy - vely;
		jump = true;
	  }
	  while( jump == true )
	  {
		posy = posy - vely;
		vely = vely - 10;
	  	if( posy > 275 )
	   	{			
			vely = 0;
			posy = 275;
			jump = false;
			break;
		}	
	   }

	}
	if( event.type == SDL_KEYUP )
	{
		velocity = 0;
	}
}

I suggest you change the structure of your code to look something more like this. Handle all key events and make them only change the velocity, not the actual sprite location. Then at the end, when you have done all the key event handling, then add the velocity to the current location.

I haven't tested this so dont assume that it will work

// vx = Velocity x
// vy = Velocity y

if (event.type == SDL_KEYDOWN) {
   
   static bool jumping = false;
   
   if (keystates [SDLK_RIGHT]) {
      vx += VXSPEED;
   } else
   if (keystates [SDLK_LEFT]) {
      vx -= VXSPEED;
   }

   if (!jumping && keystates [SDLK_UP]) {
      vy = -JUMPSTRENGTH; // Jump upwards
      jumping = true;
   } else

   if (jumping) {
      vy += GRAVITY;
      if (posy > FLOOR_Y) {
         // Hit the floor
         posy = FLOOR_Y;
         vy = 0; // Stop falling
         jumping = false;
      }
   }
   
} else {
   
}

// Mabey add friction to slow sprite down
// About 0.95 would be appropriate
posx *= FRICTION;

// Now apply velocity to current position
posx += vx;
posy += vy;

Remember, this is only how you should structure the code if your going to be using velocity. To be totally honest I dont even think you need velocity for the kind of game that this is, just the jumping. If this code works the way I think it should, then when you press the UP key, the sprite should jump and fall back to the ground, and when you press the LEFT / RIGHT arrow key the sprite should increase speed and slow down when your not pressing either of those keys.

Hope this helps.

HA! I just realized I spelled please wrong in the title! That's embarrassing. Lol!! Anyway thank you so much for your help! I got my guy to jump, but now I have another problem, how do I make the game update the screen when I'm not pressing a button? What happens is, my guy jumps, but then he just floats. If I press ANY button on my keyboard, he moves down again. I have it set at 10 fps. Is my code for him jumping set up wrong again? Or did I miss something. In case your wondering, here is my new jump code.

Wolf::Wolf()
{

    offSet = 0;
    velocity = 0;
    posy = 275;
    gravity = 30;
    newy = 0;
   jump = false;

    frame = 0;
    status = WOLF_RIGHT;
}

void Wolf::handle_events()
{	
	Uint8 *keystates = SDL_GetKeyState( NULL );
	if( event.type == SDL_KEYDOWN )
	{
		if( keystates [SDLK_RIGHT] )
		{
			velocity += WOLF_WIDTH / 4;
		}
		if( keystates [SDLK_LEFT] )
		{
			velocity -= WOLF_WIDTH / 4;
		}
	
	  	if( keystates [SDLK_UP] )
	  	{
			newy = 175;
			jump = true;
	 	 }
	 }
	 if( jump = true )
	  {
		newy += gravity;
		
	   
		  if( newy >= FLOOR_Y )
	   	{			
			newy = FLOOR_Y;
			jump = false;
		}
	}
	if( event.type == SDL_KEYUP )
	{
		velocity = 0;
	}
	
}		


void Wolf::move()
{
    //Move
    offSet += velocity;
    
    //Keep the stick figure in bounds
    if( ( offSet < 0 ) || ( offSet + WOLF_WIDTH > SCREEN_WIDTH ) )
    {
        offSet -= velocity;    
    }
	posy = newy;
}

HA! I just realized I spelled please wrong in the title! That's embarrassing. Lol!!

Ok -- now I'm going to have to ban you for misspelling that word :) Unless you have a Ph.D. in English, don't worry about the small stuff.

One obvious little error ... if( jump = true )

commented: Well spotted :) +3

AncientDragon:
I'm not worried about it. Sad part is, I do have a PhD in English! JkJk. I'm not even old enough to go to college! :P Seriously I'm not though. And thank you for moving this thread from C to C++. I don't know what I was thinking.

mitrmakr:
What should I change the "if" to? If I change my code to:

while( jump = true )
	  {
		newy += gravity;
			   
		  if( newy >= FLOOR_Y )
	   	{			
			newy = FLOOR_Y;
			jump = false;
		}
	}

It freezes the program. But if I add "break;" after "jump = false;" the program loads but he doesn't jump.

I meant that you were misusing the assignment operator = there

if(jump = true)  // sets 'jump' to 'true'
while( jump = true ) // sets 'jump' to 'true'

instead, to check whether jump is true , use ...

if(jump == true) 
// or ...
while( jump == true )

Ha! You're right! Small typo on my part in my code. But sadly it changes nothing. Now if I have it set as "while" the program doesn't freeze. Instead, when I press up, nothing happens. He moves left and right, but doesn't jump. If I change "while" to "if", He jumps, but doesn't go all the way down and he can float. Should I place the code somewhere else? Or am I still missing something. Sorry if you all are getting annoyed with my questions.;) But I appreciate your help. Here is my new code.

Wolf::Wolf()
{

    offSet = 0;
    velocity = 0;
    posy = 275;
    vely = 0;
    gravity = 30;
    newy = FLOOR_Y;
   jump = false;

    frame = 0;
    status = WOLF_RIGHT;
}

void Wolf::get_keystates()
{	
	Uint8 *keystates = SDL_GetKeyState( NULL );
	if( event.type == SDL_KEYDOWN )
	{
		if( keystates [SDLK_RIGHT] )
		{
			velocity += WOLF_WIDTH / 4;
		}
		if( keystates [SDLK_LEFT] )
		{
			velocity -= WOLF_WIDTH / 4;
		}
	
	  	if( keystates [SDLK_UP] )
	  	{
			newy = 100;
			jump = true;
	 	 }
	 }

		 while( jump == true )
	  {
		newy += gravity;
		
	   
		  if( newy > FLOOR_Y )
	   	{			
			newy = FLOOR_Y;
			jump = false;
			break;
		}
	}
	if( event.type == SDL_KEYUP )
	{
		velocity = 0;
	}
}

Just related to the while() loop you have devised

while( jump == true )
{
    newy += gravity;
    
	if( newy > FLOOR_Y )
    {			
        newy = FLOOR_Y;
        jump = false;
        break;
    }
}

if you look at it closely, you'll see that it actually can be written as follows

if( jump == true )
{
    newy = FLOOR_Y;
    jump = false;
}

Ha! Thank you for your help! I figured it out. I had the part of the code in the wrong place. If anyone needs to know how to jump in SDL, PM me. K? Thanks again!:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.