• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3646
  • Last Modified:

How to jump with gravity always pulling down

I have created a program that makes my blob fall from the sky and when it hits the block sprite it stops from falling. If I walk off of it I fall again (When I fall past a certain spot I come back from the top just to make it easier to work with for now). Anyways, but one of my problems here is my collision isn't working properly, I am going about half way into the object before I stop. So how can I fix that?

My next problem is jumping with the gravity being consistent, I press space but I only go up a very small amount and I am back down. I can I fix this so I jump say about 200 pixels high and then gravity kicks back in and pulls me down again? I want to fix this problem with the gravity not being set to 0 all the time. (If that is possible).

Here is my code(C++),

//set sprites properties
	blob.x = 150;
	blob.y = 0;
	blob.width = 64;
	blob.height = 64;
	blob.speed.x = 0;
	blob.speed.y = 0;
	blob.accel.x = 2;
	blob.accel.y = 10;
	blob.direct.x = 0;
	blob.direct.y = 0;
	blob.gravity = 2;
	blob.inAir = true;
 
	land.x = 100;
	land.y = SCREEN_HEIGHT - 192;
	land.width = 800;
	land.height = 64;
 
	block.x = 400;
	block.y = land.y - 64;
	block.width = 64;
	block.height = 64;
 
//collision function
int Collision(SPRITE sprite1, SPRITE sprite2)
{
	RECT rect1;
    rect1.left = sprite1.x + 1;
    rect1.top = sprite1.y + 1;
    rect1.right = sprite1.x + sprite1.width - 1;
    rect1.bottom = sprite1.y + sprite1.height - 1;
 
    RECT rect2;
    rect2.left = sprite2.x + 1;
    rect2.top = sprite2.y + 1;
    rect2.right = sprite2.x + sprite2.width - 1;
    rect2.bottom = sprite2.y + sprite2.height - 1;
 
	RECT dest;
	return IntersectRect(&dest, &rect1, &rect2);
}
 
//jump function
void jump()
{
	if(!blob.inAir) //if inAir = false
	{
		blob.inAir = true;
		blob.direct.y = -1;
		blob.speed.y += blob.accel.y;
	}
 
}
 
//movement function
void movement()
{
	if(Key_Down(DIK_LEFT))
	{
		blob.speed.x += blob.accel.x;
		blob.direct.x = -1;
		if(blob.speed.x > 8) //allow only a certain speed
			blob.speed.x = 8;
	}
	else if(Key_Down(DIK_RIGHT))
	{
		blob.speed.x += blob.accel.x;
		blob.direct.x = 1;
		if(blob.speed.x > 8) //allows only a certain speed
			blob.speed.x = 8;
	}
	else
		blob.speed.x = 0; //if I am not pressing button my speed is 0
 
	if(Key_Down(DIK_SPACE))
	{
		jump(); //call to jump function
	}
}
//check collision function
void checkCollision()
{
	if(Collision(blob, land))
	{
		blob.speed.y = 0;
		blob.direct.y = 0;
		blob.inAir = false;
	}
	else if(!Collision(blob, land))
	{
		blob.speed.y += blob.gravity;
		blob.direct.y = 1;
		blob.inAir = true;
	}
}
 
//update function
void update()
{
	blob.x += blob.speed.x * blob.direct.x;
	blob.y += blob.speed.y * blob.direct.y;
 
	if(blob.inAir == true)
	{
		blob.direct.y = 1;
		if(blob.speed.y > 30)
			blob.speed.y = 30;
	}
 
	if(blob.y >= SCREEN_HEIGHT + 64)
	{
		blob.y = -64;
	}
}

Open in new window

0
jschmuff
Asked:
jschmuff
1 Solution
 
SunnyDarkCommented:
Here are some pointers:
In your checkCollision function - no need to call Collision twice - not effective ,
change to:
if(Collision(blob, land))
{
blob.speed.y = 0;
blob.direct.y = 0;
blob.inAir = false;
}
else {
blob.speed.y += blob.gravity;
blob.direct.y = 1;
blob.inAir = true;
}
 
In you update function:
if(blob.inAir == true)
{
blob.direct.y = 1; <=====
You are effectively reversing the direction of the blob so that the next update call will reverce the speed as well wich probably just a little smaller then the initial speed of the jump due to gravity (I also don't see you calling checkCollision anywhere but I imagine you do...)
So instead you should just reduce the speed (up)  by the gravity until it reached zero... then reverse direction and increase with gravity.
 
Hope it helps.


0
 
jgordosCommented:
Is IntersectRect in your sample the windows version?

If so, you might be running into issues because you haven't normalized the rectangles that you're comparing.

Basically, the longest side of each rectangle shouldn't be any bigger than 1, and the small sides should be the fractional amount that's left from (short side length)/(long side length)

Odd things result sometimes if you don't do this.

http://msdn.microsoft.com/en-us/library/dd145001(VS.85).aspx

-john
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now