How to fix Pong Ball physics?

maybe try this?

	if collision:
		if collision.get_collider().name == "Paddle":
			movement = movement.bounce(collision.get_normal())
			if can_add_score == true:
				can_add_score = false
				score += 1
				label.text = str(score)
				%Timer.start()
				print(can_add_score)
		elif collision.get_collider().name == "Borders":
1 Like

I tried it, But now the ball doesn’t even move/change angles when hitting the paddle.
Any other solutions?

so the ball passes through the paddle? or it just stays in one place?

Just goes up and down with there being no way to change the direction

I made a pong game too, I am very familiar with this kind of code.
Basically in this code, only the Vector X is modified when the ball touches the paddle.
This is the line of code that needs to change:

var new_movement = Vector2(-diff * 5, speed)

the Y vector is constant, which means that the ball will always take the same time to go from the paddle to the top. The ball speeds up when it goes at an angle and slows down when it goes straight to the top, but ultimately both cases result in the ball arriving at the same time.
If you don’t want this behaviour and want a constant speed of the ball you should use Pythagoras:

the constant speed ^2 - Vector x ^2 = Vector y^2

Vector x is the little -diff *5 you have, the constant speed is a value of your choosing, and the final thing you want is Vector y which you obtain from the equation after use square root of speed^2 - VecX^2, you get

var new_movement = Vector2(-diff * 5, VecY)

Also you can change the ‘5’ and decrease it if you want the ball to go at a higher angle, or increase it for a lower one, experiment.

Finally, if you want the ball to continue on its path after hitting the paddle (if it was going left to right, it remains that way regardless of where it touches the paddle) you should get the old movement Vector X and keep its sign.
In other words if the VecX before hitting the paddle was negative, you keep the new VecX negative. I can give you some code for that if you wish.

1 Like

Yes, I would like the code for this. Thank you very much for giving me a little bit more insight on this (even though I don’t really understand how things like this work as of right now) :slight_smile:

Her is a picture to show how the new_movement vector is built visually

Let’s try this again but add an absolute function abs(). This will avoid the reversal of new_movement if speed is negative.

var new_movement = Vector2(-diff * 5, speed).normalized() * abs(speed)

I think there is an issue in the logic with:

I’m not sure when can_add_score becomes true but this is where you reverse the ball direction.

But the ball direction is only reversed if can_add_score is true.

The ball may move in the wrong direction for a frame.

I think you should reorder this part of the code with the if can_add_score first so that the speed can be reversed here in a single frame. And maybe make them all part of the same if statement if the ball I guess is missed the movement shouldn’t get updated? Maybe if this is the side of the paddle it should just reflect like a wall.

This check will only work if the paddle is not rotated.
collision.get_normal() != Vector2.UP

I also question if can_add_score is even needed anymore after this change.

The code with abs change made it work, but I feel like it could do better.
And yes, the can_add_score is still needed to change the score when the ball hits the paddle.
I’ll check out your code still and see if it will make a difference.

I tried using your code but now there’s an error from line 16 - 19. Is my formatting wrong?


Also I’m still pretty confused with all of this vector stuff, so could anyone ultimately explain to me or show me where I could finally master them (plus anything physics related)?

ngl at this point i kinda want to just recreate the project to test it myself

anyway you need to indent the red lines more. two indents should be what you need. there is also a doc page on vectors

okay while i try to recreate the project i think you can look at the code for this brick breaker project, since your game is more like brick breaker than pong

1 Like

Okay, I have the solution! Here is my code for the ball, it is all of it.

extends CharacterBody2D


@export var speed := 400.0


func _ready() -> void:
	velocity = Vector2.RIGHT.rotated(PI/4) * speed


func _physics_process(delta: float) -> void:
	var collision = move_and_collide(velocity * delta)
	
	if not collision:
		return
		
	if collision.get_collider().name == "DeathArea":
		queue_free()
	
	velocity = velocity.bounce(collision.get_normal())

Let me explain everything.

First off, CharacterBody2D has a velocity variable built-in. It’s used automatically in move_and_slide() but I decided to also use it in my code so I don’t have to make a new variable. But making your own variable is fine, since move_and_slide() is never called.

Second, the reason the ball does not change direction when using bounce() is that it only goes perpendicular to the thing it hits. But if you give the ball an angle when it first moves, it will bounce at something different than a 90 degree angle.

1 Like

Ok, now I’m REALLY getting into confusing territory. It’s to the point where this is one of the things that I’m probably weak in. As someone who comes from Scratch (A block based programming language), Stuff like vectors, normalize, if collision really tickle my head. At this point I probably need a tutorial introducing me to the ABSOLOUTE basics of this stuff, because I’m just confused right now.

@shatteredreality so I replace all my code with just this? seems too simple too work, but I might just be in doubt, I’ll check and see

1 Like

Just to be sure, Do I replace ALL of my code? or just add this in as an extra somewhere else in it?

All the code, here is proof that it works

Exactly what I need! I’ll update the code and see if it worked

1 Like

Also a question will this deal with the wall collision as well?

Yes, it bounces off the walls as same as the paddle. So there is no need to check which one it is bouncing off of.

1 Like

I’m trying to re-add the score function, but now I’m getting an error about the code expecting 'else after ternary operator condition, how do I fix this?