Limiting the jump

Hi,

I am still writing on my game. But I habe come to a problem where I don't know right now how to solve it. Basically it is a platform game. Everything works so far good but I need to limit the jump hight of the player. But I don't really now right now how to do this. Maybe you can give me a hint?

This is what I have got so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
		if( keystates[SDLK_RIGHT] )
		{
			playerH.vx +=0.5;
		}

		if( keystates[SDLK_LEFT] )
		{
			playerH.vx -=0.5;
		}

		if( keystates[SDLK_SPACE] )
		{
			playerH.vy -= 4;
			playerH.isOnGround = false;
		}

		if( playerH.vx > playerH.speedMax )
		{
			playerH.vx = 3;
		}

		if( playerH.vx < -playerH.speedMax )
		{
			playerH.vx = -3;
		}

		if( playerH.isOnGround == false )
		{
			if( playerH.vy < 10 )
			{
				playerH.vy += 1;
			}
		}
		
		playerH.vx = playerH.vx * playerH.friction;
		//playerH.vy = playerH.vy * playerH.friction;

		playerH.x += playerH.vx;
		playerH.y += playerH.vy;		

What happens when playerH.vy is not < 10 but > 10 in the 'if( playerH.isOnGround == false )' block? Let him go down again I suggest.

Don't forget to set playerH.isOnGround to 'true' again when he reaches the ground.
Last edited on
I know that but the problem is that the platforms have different hights. So he needs to be able to jump at each block like 10 point up. Oh and it is set in an different function back to true.
Last edited on
Save the vertical coordinate when he jumps.
I was thinking about that before. But if the players presses space again he will overwrite the old coordinates. So it would be like a cheat :D
Not if you set it in a block where the player is on the ground.

pseudo-code:
If player.isOnGround == true
if player presses jump-key
save position: jumpY
isOnGround = false;
isJumping = true;
Endif
Endif

If player.isOnGround == false
if player.H.vy == jumpY && isJumping == true
isJumping = false;
isOnGround = true;
endif
if playerH.vy < jumpY + 10 && isJumping == true
playerH.vy++;
endif
if playerH.vy >= jumpY + 10 && isJumping == true
playerH.vy--;
Endif

Also, I would personally not use '== true' and '==false'. If you write 'if(playerH.isOnGround)' this is the same as 'if(playerH.isOnGround == true', and 'if(!playerH.isOnGround)' is the same as 'if(playerH.isOnGround == false)'. The workings are the same, it just looks better.

I used 'playerH.vy++' which is the same as 'playerH.vy += 1;'

--EDIT: Added a bit more code
Last edited on
If I write the jump function like that
1
2
3
4
5
6
7
8
9
10
11
		if( playerH.isOnGround == true )
		{
			if( keystates[SDLK_SPACE] )
			{
				//playerH.yOld = playerH.y;
			
				playerH.vy -= 2.5;

				playerH.isOnGround = false;
			}
		}

He won't jump at all. That is strange too me since isOnGround is definitely true.
@Kelevra: First of all, does your player class hold all of it's variables as either floats or doubles? (as opposed to ints)

Second: if you are having trouble with what you think is absolutely true, run the program through your debugger. Step through the program at specific key breakpoints and you will see where the error is.

Third: Don't use friction as a multiplier. If you have the ability, make it a constant.

Fourth, it looks like you don't have persistent velocity, is that true?
Ok a while ago I wondered the same thing and I came up with this idea:
What if you had two bounding boxes around the floor? The first one would keep you falling through and the second one would go as high above the floor as you wanted the player to be able to jump. Then when the player presses the jump key AND he is in the jump box he will go up. When he gets out of the jumpbox has_jumped is set to true until he touches the floor bounding box again.
Last edited on
Since we are not allowed to use classes I used a Typedef for my player
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Typedef
typedef struct playerHandle
{
	double x;
	double y;
	double yOld;
	double vx;
	double vy;
	double friction;

	int speedMax;
	int gravity;

	bool isOnGround;
}playerHandle;


Okay the Bool was true but I found a different problem thanks for the tip.

I wrote the code now like that. I bet there is lots to do better, please tell me. But it works quite nicely.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//Playermovement
		Uint8 *keystates = SDL_GetKeyState( NULL );

		if( keystates[SDLK_RIGHT] )
		{
			playerH.vx +=0.5;
		}

		if( keystates[SDLK_LEFT] )
		{
			playerH.vx -=0.5;
		}

		if( playerH.isOnGround )
		{
			if( keystates[SDLK_SPACE] )
			{
				playerH.vy -= 25;

				playerH.isOnGround = false;
			}
		}

		if( playerH.vx > playerH.speedMax )
		{
			playerH.vx = 3;
		}

		if( playerH.vx < -playerH.speedMax )
		{
			playerH.vx = -3;
		}

		if( !playerH.isOnGround )
		{
			if( playerH.vy < 10 )
			{
				playerH.vy += 0.6;
			}
		}
		
		if( playerH.isOnGround )
		{
			playerH.vx = playerH.vx * playerH.friction;
		}

		playerH.x += playerH.vx;
		playerH.y += playerH.vy;

		player_boundaries( &playerH );


But this part still dosn't work
1
2
3
4
5
6
7
8
9
10
11
12
13
			if( keystates[SDLK_SPACE] )
			{
				playerH.yOld = playerH.y;

				if( playerH.y <= playerH.yOld - 100 )
				{
					playerH.vy -= 10;
				}
				else
				{
					playerH.isOnGround = false;
				}
			}

Last edited on
What exactly do you mean by 'doesn't work'? Does it give an error, does it do something strange, does it do nothing, ...

instead of:
1
2
3
4
else
{
   playerH.isOnGround = false;
}

could you have it output playerH.vy, because I think it might be >= 10 in which case it does not increase by 0.6.

Last edited on
Since we are not allowed to use classes I used a Typedef for my player


why? That's completely pointless....

(btw a struct is a class, it just has a different default protection for the included variables and methods)

and this
1
2
 playerH.yOld = playerH.y;
 if( playerH.y <= playerH.yOld - 100 )


will obviously not work. you set the variables = to eachother than check if they're 100 px apart??!
I would personally add a variable that says whether or not the player is jumping. As I suggested in my pseudo-code 'isJumping' boolean.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Typedef
typedef struct playerHandle
{
	double x;
	double y;
	double yOld;
	double vx;
	double vy;
	double friction;

	int speedMax;
	int gravity;

	bool isOnGround;
	bool isJumping;        

}playerHandle;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//Playermovement
		Uint8 *keystates = SDL_GetKeyState( NULL );

		if( keystates[SDLK_RIGHT] ) {
			playerH.vx +=0.5;
		}

		if( keystates[SDLK_LEFT] ) {
			playerH.vx -=0.5;
		}

		if( keystates[SDLK_SPACE] ) {
			if( playerH.isOnGround && !playerH.isJumping) { //Starting jump
				playerH.isOnGround = false;
				playerH.isJumping = true;
				playerH.yOld = playerH.y;
				playerH.vy -= 25; //Kickstart
			}
			if( playerH.isOnGround && playerH.isJumping) { //Coming down reaching floor
				playerH.isJumping = false;
			}
			if( !playerH.isOnGround && playerH.isJumping) { //Jumping
				if( playerH.y <= playerH.yOld - 100 ) { //Max height
					playerH.vy += 10;
					playerH.isJumping = false;
				}
				else if( playerH.y > playerH.yOld - 100 ) { //Not max height, go higher
					playerH.vy -= 10;
				}
			}
			if( !playerH.isOnGround && !playerH.isJumping) { //Falling
				if( playerH.y == playerH.yOld) { //On the ground yet?
					playerH.isJumping = false;
					playerH.isOnGround = true;
					playerH.vy = 0;
				}
				else { //Not on the ground yet, keep falling
					playerH.vy += 10;
				}
			}
		}

		if( playerH.vx > playerH.speedMax ) {
			playerH.vx = 3;
		}

		if( playerH.vx < -playerH.speedMax ) {
			playerH.vx = -3;
		}

		playerH.x += playerH.vx;
		playerH.y += playerH.vy;

		player_boundaries( &playerH );
Last edited on
Thank you very much for your code. I rewrote it so that it works very well for my jumping but I still have the problem of the double jump. I thought that I would set a boolean to false if the key is released so that pressing space isn't accepted by the game until the player reaches the ground. But there is no way with keystates to tell if the player released the space key. So maybe somebody of you has an idea for that.
But thanks a lot so far!

Btw. this the code for the jump:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
if( keystates[SDLK_SPACE] ) 
		{
			//Check if jump is allowed
			if( pPlayer->isOnGround && !pPlayer->isJumping )
			{
				pPlayer->isOnGround = false;
				pPlayer->isJumping = true;
				pPlayer->yOld = pPlayer->y;
				pPlayer->vy -= 3;
			}

			//Check for MAXHEIGHT and go on if not reached
			if( !pPlayer->isOnGround && pPlayer->isJumping )
			{
				if( pPlayer->y > pPlayer->yOld - MAXHEIGHT_JUMP )
				{
					pPlayer->vy = -5;
				}
				else if( pPlayer->y <= pPlayer->yOld - MAXHEIGHT_JUMP )
				{
					pPlayer->isJumping = false;
				}
			}
		}

		//Gravity
		if( !pPlayer->isOnGround )
		{
			pPlayer->vy += 0.35;
		}

		if( pPlayer->isOnGround )
		{
			pPlayer->isJumping = false;
		}


Okay, I solved it myself. I just said if he once started to fall you can't jump again.
1
2
3
4
5
pPlayer->vy += 0.35;
			if( pPlayer->vy > 0.35 )
			{
				pPlayer->spaceLocked = true;
			}


Thank you all!
Last edited on
No problem, glad you solved it :)
Topic archived. No new replies allowed.