Gravity. Player shakes when jumping because of contradicting velocity/

Hello my issue is that when my player jumps. There is a tiny but noticeable shake because of how Jumping and gravity is worked.

There are the variables concerning jumpping and gravity,


	private float gravity = 0.5f;
	private final double MAX_SPEED = 10;

And here a method called in the tick/update method for position. Standard 60 ticks/s.


public void getNextPosition() {
		x += velX;
		y += velY;                                               //Exhibit A
		tileCollision(gameState.getObject());
		if (falling || jumping) {
			velY += gravity;
			if (velY > MAX_SPEED) {
				velY = MAX_SPEED;
			}
		}

		if (right && left) {
			if (timeRight > timeLeft) {
				velX = 5;
			} else if (timeLeft > timeRight) {
				velX = -5;
			}
		} else if (right && !left) {
			velX = 5;
		} else if (left && !right) {
			velX = -5;
		} else if (!left && !right) {
			velX = 0;
		}

	}

And here is how my jump works


if (key == KeyEvent.VK_SPACE) {
			if(player.isJumping() == false){
				player.setVelY(-10);   //Exhibit C
				player.setJumping(true);
			}
			
		}

As you can see from code in the update method y += velY; is causing the problem because the jump sets velY to -10. And at the same time applying the gravity as well velY += gravity;

This is my first attempt at a game and I don’t know how to approach gravity another way.

Here is a github link the my eclipse project file.
https://github.com/andrevicencio21/onepiecegame
It’s still at the early stage so hopefully it’s easier to trace.
Menu Controls: Up and Down and Enter;

Game Controls:
A,D for left and right movement
Space for Jump

If you want to add proper gravity, you are going to have to dig a little deeper and learn how acceleration, speed and velocity work and why they are different.

Ideally you want to apply gravity over time to prevent instant downwards velocity…

If you have collision properly implemented then you should just apply gravity the entire time, since the collision algorithm will resolve it quickly without notice anyway.

But yeah, tl;dr you need to apply gravity over time using forces to get a nice effect. Or you will get twitchy movement.

I haven’t looked at your project files, but I don’t think the gravity is the problem. How are you handling the collision with the “ground” in your game? What I generally do is check to see where the player WILL be and then adjust the position to place him directly on the ground. The shaking is probably due to checking for collision after movement. Below is a small excerpt from my Physics.class which checks for world collision BEFORE changing the position. Keep in mind this is used for a tile based game so X and Y collisions are checked separately but it should give you the idea.

First allow movement such as left, right, up, down, jump etc:


public void moveLeft()
	{
		o.velocity.x -= moveSpeed;
		if(o.velocity.x < -maxSpeed) o.velocity.x = -maxSpeed;
	}
	
	public void moveRight()
	{
		o.velocity.x += moveSpeed;
		if(o.velocity.x > maxSpeed) o.velocity.x = maxSpeed;
	}

Next we apply gravity as a constant force:


// Apply gravity if called for - note that o is a base class GameObject or whatever you want to call it.  
// GameObject has a Vector2 position, and another called velocity.  This allows us to attach the
// physics class to any GameObject.
		
		if(gravityEnabled)
		{
			o.velocity.y += gravity;
			if(o.velocity.y > maxGravity) o.velocity.y = maxGravity;
		}



Now we begin the checks for collision:


// Test X axis for collision where the player WILL be if we allow movement
		
		if(o.velocity.x != 0)
		{
			destination.set(o.position.x + o.velocity.x , o.position.y, o.getWidth(), o.getHeight());
			
			if(overlap(destination))
			{
				
				if(o.velocity.x > 0)
				{
					o.velocity.x = 0;
					o.position.x = blockRect.x - o.getWidth();
				}
				
				else
				{
					o.velocity.x = 0;
					o.position.x = blockRect.x + blockRect.width;
				}
				
			}
		}
		
		// Test Y axis for collision where the player WILL be if we allow movement
				
		if(o.velocity.y != 0)
		{
// Creates a rectangle representing where the player will be - used for collision check
			destination.set(o.position.x, o.position.y + o.velocity.y, o.getWidth(), o.getHeight());
			
			if(overlap(destination))
			{
				
				if(o.velocity.y > 0)
				{
					o.velocity.y = 0;
					o.position.y = blockRect.y - o.getHeight();
				}
				
				else
				{
					o.velocity.y = 0;
					o.position.y = blockRect.y + blockRect.height;
				}
			}
		}

Notice that if there is an overlap in either axis I set the velocity for that axis to zero. If no collision, then allow him to be positioned at the desired location. i.e.


               // Finally apply adjusted forces
		
		o.position.add(o.velocity);

Also, I have gravity applied as a constant force so it doesn’t depend on whether the player is falling, jumping or whatever. This code works flawlessly no matter what direction the player is moving because collision is checked before ANY movement is allowed. This prevents shaking behavior, getting stuck in walls etc. I hope this helps.

what are you using for collision detection? I know it’s overlap but what is overlap? I use .intersects from rectangle class for collision detection. BTW I solved it apparently the issue is when the gravity is applied in decimals. for some reason it shakes and it doesn like it but if i set the gravity at a constant 1. so the Y- velocity with be for example -10, -9 , -8 … 1-1, 0, 1, 2, 3. It won’t shake this way.

I am using a similar method called .overlaps() from the LibGDX Rectangle class. Works very similarly to the Java version. Glad you got it working.