Hi guys, I have a bit of problems with collisions while jumping,
When the Player jumps on the box it acts weird because while staying on top of the box it keeps going up and down, and I can see that Player jump velocity keeps increasing (so it goes down) and decreasing (so it goes up) and also gravity does the same.
No idea how to fix it, if you can help me it will be highly appreciated.
I have copied the important bits of the code.
Many thanks.
Summary
struct SPlayer
{
void Move();
void ApplyBoxCollision();
float Width = 100.0f;
float Height = 100.0f;
float XPosition = (WINDOW_WIDTH * 0.5f) - (Width * 0.5f); //center of the screen
float YPosition = 362;//top of the player
float YDesiredPosition = 362; //Player DesiredStart Position on Y axis (it updates every time Player.Yposition changes). So if I press S to jump at the very beginning of the program coming down the player will go to start position
float XDesiredPosition = 0;
float XPrevDesiredPosition = 0;
float YPrevDesiredPosition = 0;
float XVelocity = 160.0f;
float YVelocity = 160.0f;
float JumpVelocity = -422.0f;
float Gravity = 0;
EPlayerState State = PLAYER_STILL;
SDL_Texture* playerTexturewr = nullptr;
SDL_Texture* playerTexturewl = nullptr;
SDL_Texture* playerTexturejr = nullptr;
SDL_Texture* playerTexturejl = nullptr;
SDL_Texture* playerTextureclimb = nullptr;
SDL_Rect Quad;
};
Summary
void HandleEvents(void)
{
…
case SDLK_s:
{
if (Player.OnLadder == false) //Player can jump only if not on ladder
{
keyS_Down = 1;//key down (it means we are pressing S)
keyS_Up = 0;//(Releasing S is disabled)
if (spritestill == 2) //was set to 2 when right key is pressed
{
Player.State = PLAYER_JUMP_RIGHT;
}
if (spritestill == 1) //was set to 1 when left key is pressed
Player.State = PLAYER_JUMP_LEFT;
if (Player.State == PLAYER_STILL)
{
Player.State = PLAYER_JUMP_RIGHT;
}
}
break;
}
......
else if( Event.type == SDL_KEYUP && Event.key.repeat == 0 )
{
....
case SDLK_s:
{
keyS_Down = 1; //important: so player keeps jumping also when released (until it jump before being affected by gravity)
}
break;
}
Summary
void SPlayer::Move()
{
switch (Player.State)
{
case PLAYER_MOVING_LEFT:
//converting double DeltaTime in float
Player.XPosition += -Player.XVelocity*(float)DeltaTime;
break;
case PLAYER_MOVING_RIGHT:
Player.XPosition += Player.XVelocity * (float)DeltaTime;
break;
case PLAYER_MOVING_UP:
Player.YPosition += -Player.YVelocity * (float)DeltaTime;
break;
case PLAYER_MOVING_DOWN:
Player.YPosition += +Player.YVelocity * (float)DeltaTime;
break;
}
default:
break;
}
}
Summary
void Update(void) {
HandleEvents(); //check events every time we update…
// Calculate the deltatime every time we update....
NewTime = SDL_GetTicks(); //time in msecs running since this call
DeltaTime = (NewTime - OldTime) / 1000.0; //convert msecs in seconds
OldTime = NewTime;.....
…
if(keyS_Down == 1 ) //it means is true that I pressed S (the jump key)
{
Player.Gravity = 1022.0f;
Player.JumpVelocity = Player.JumpVelocity += Player.Gravity * (float)DeltaTime;
Player.YPosition += Player.JumpVelocity * (float)DeltaTime;
if (Player.YPosition >= Player.YDesiredPosition)
{
Player.Gravity = 0;
Player.JumpVelocity = -422.0f;
Player.YPosition = Player.YDesiredPosition;
/* every time the player gets down it is set to the current YDesiredPosition that is updated every time except when jumping*/
keyS_Down = 0;
Player.State = PLAYER_STILL;
}
}
if (keyS_Down && keyL_Down)
{
Player.State = PLAYER_JUMP_LEFT;
Player.XPosition -= 2.5f; //jump on the left
}
if (keyS_Down && keyR_Down)
{
Player.State = PLAYER_JUMP_RIGHT;
Player.XPosition += 2.5f; //jump on the right
}
Player.ApplyBoxCollision();
Summary
void SPlayer::ApplyBoxCollision()
{
for( int i = 0; i<2; i++)
if ((QuadVsQuad(Player.Quad, Block[i].Quad) == true))
{
blockCollision = 1;
Player.XPrevDesiredPosition = Player.XDesiredPosition;
Player.YPrevDesiredPosition = Player.YDesiredPosition;
//move back if we have collisions
switch (Player.State)
{
case PLAYER_MOVING_LEFT:
Player.XPosition += +Player.XVelocity*(float)DeltaTime;
break;
case PLAYER_MOVING_RIGHT:
Player.XPosition += -Player.XVelocity * (float)DeltaTime;
break;
case PLAYER_MOVING_UP:
Player.YPosition += +Player.YVelocity * (float)DeltaTime;
break;
case PLAYER_MOVING_DOWN:
Player.YPosition += -Player.YVelocity * (float)DeltaTime;
break;
case PLAYER_JUMP_RIGHT:
Player.YPosition = Player.YPosition -50; //to get on top of the box
Player.Gravity = 0;
Player.JumpVelocity = 0;
KeyD_Down = 0;
break;
case PLAYER_JUMP_LEFT:
Player.YPosition = Player.YPosition - 50; // top get on top of the box
Player.Gravity = 0;
Player.JumpVelocity = 0;
break;
default:
break;
}
//update player quad after collision
Player.Quad = {static_cast<int>(Player.XPosition), static_cast<int>(Player.YPosition) , static_cast<int>(Player.Width), static_cast<int>(Player.Height)};
}
else
blockCollision = 0;
}