• 2D
  • How to make a ball bounce up to a specific height?

I've been attempting to make a clone of Pang, an old arcade game where you shoot balls with harpoons, and the way the balls behave is they always bounce up to a predefined height. I'm gonna call it target_y. That value is defined when the level starts, and it's the position at which the ball starts the level. While a ball bounces off platforms (and not the ground), it will always bounce all the way up to target_y (1-3 in the picture). When the ball touches the ground, target_y is changed to a height that is specific to the ball's size (4). From that point on, even if the ball bounces off a platform, it will only reach that new target_y.

To achieve this, I think I must give the ball a jump force, much like you would in a platformer. But this force has to be relative the height of the floor.

So, knowing the floor height and the target height, how can I calculate exactly how much jump force the ball needs?


My current code looks like this (and isn't even close to the desired effect):

extends KinematicBody2D

# [...]

func _physics_process(delta):
	velocity.y += GRAVITY  # gravity is 5

	move_and_slide(velocity, Vector2.UP)

	if is_on_wall():  velocity.x *= -1    # x movement is constant

	# y velocity calculation goes here (-155 is arbitrary placeholder)
	if is_on_floor(): velocity.y = -155  

This is a kinematic problem. :)

The equation you're looking for is the fourth one, rearranged to find starting velocity needed for the ball to reach target_y (with a final velocity of zero at that point):

# If...
# 0 = start_velocity^2 + 2 * acceleration * delta_y
# then...
# start_velocity = sqrt(2 * acceleration * delta_y)
# so something like...
if is_on_floor():
    velocity.y = -sqrt(2 * GRAVITY * target_y)

The ball should also bounce to its starting height if you negate its Y velocity whenever it collides with the topside or underside of the platforms, making it like a perfectly elastic bounce.

Thank you. Also for the formulas. I had no idea that was even a thing.

I also had to multiply gravity by delta on line 6 above, btw. It wasn't quite working without that. :)