How to make a ball change its direction when colliding?

Godot Version

Godot V4.2

Question

I’m trying to make a ping pong game where the ball lands on a paddle and changes direction, I’m a newbie to Godot so I felt like this could help me learn the engine more, but I’ve ran into a problem where once the ball lands on the paddle, it still stays in a vertical movement and doesn’t change the direction it’s going to. Here’s my code, let me know what I am doing wrongly here.

extends CharacterBody2D

const SPEED = 200
var dir = Vector2.DOWN

func _physics_process(delta):
	velocity = dir * delta * SPEED
	rotation_degrees = randf_range(0, 360)
	var collision = move_and_collide(velocity * SPEED * delta)
	if collision:
		dir = dir.bounce(collision.get_normal())
		rotation_degrees = randf_range(0, 360)

I can provide any additional screenshots later, Thanks to anyone willing to help out :grinning:

Besides your odd rotation_degrees = randf_range(0, 360) it looks like it should be working (based on Godot Docs)

I would like to point out that your velocity computation is wrong.

# What you're doing
velocity = dir * delta * SPEED
move_and_collide(velocity * speed * delta)

# What you should be doing
velocity = dir * SPEED
move_and_collide(velocity * delta)

After this change, your SPEED likely needs to be lowered.

Curious question

What is the purpose of this line:

rotation_degrees = randf_range(0, 360)
2 Likes

Oh well, I want it so that the ball changes it’s degrees therefore changing the direction it’s facing to randomly.

Also I’ll try applying the correct velocity computation. But could you also explain to me how each velocity computation works so that I can know how to do it on my own?

…I want it so that the ball changes it’s degrees therefore changing the direction it’s facing to randomly.

Okay, but in every physics update?

Your question

…could you also explain to me how each velocity computation works…?

Sure thing.

Velocity:
As you may know from physics, velocity is a vector representing how fast an object is going. This velocity-vector can be described as being made up of two parts: a speed (a scalar) and a direction (a vector). As an example, your code has a direction, dir, which is your direction, and SPEED which is your scalar.

Physics Simulation:
When working with real-time physics simulations, just like you are right now, you write your code to work in what is called time steps (also known as ticks). Time steps are necessary to simulate a physical system on a computer for a variety of reasons (see Computer simulation - Wikipedia) and represent a fraction of time in the simulation in which you want to compute the next state of the system (i.e. where is my ball in the next frame?). In your case, this timestep (fraction of time) is delta.
This brings us to your question.

What does the velocity computations in the code snippet I provided achieve?

Velocity computation explanation

velocity = dir * SPEED

In this line I am computing the desired velocity of the ball (which is a Vector2: a two-dimensional vector) and storing it in your velocity-variable.

move_and_collide(velocity * delta)

Here, we are calling move_and_collide() to move the ball. The amount that the ball is moved is given by the parameter that we give the function. In this case, we want to move the ball by velocity * delta amount.
The reason we don’t just move by velocity alone is because we want to move the ball delta time into the future (timesteps, remember). To explain further:

Remember that velocity is in metres … per … second. If we want to move the ball by delta seconds into the future, we have to multiply the velocity of the ball by those delta seconds to achieve the correct distance that the ball would move in that timeframe.

Summary

  • Velocity is a vector representing direction and speed
    • Its unit (m/s) describes how far, in metres, an object moves in one second
  • Physics simulations run in timesteps (In Godot, the standard is 60 steps per second)
    • Seconds for one timestep: 1 / 60 ≈ 0,0166… seconds

Additional resources

If you have some questions about any of this, let me know.

2 Likes

Oh, I see, So I’m supposed to focus on delta with collisions, And focus on direction and speed when making the velocity variable, This makes lots of sense now :smiley:

Also for what my error is I’ll have to give an example of what the problem is, so I have to give a video, but it says new users can’t upload attachments, what should I do :slightly_frowning_face:?

You can just upload it to Google Drive and attach a link to the file in here.

Or I can put a link for the video using a video hosting website.
Could you list me any options for any of these websites? Or if that isn’t possible, could you show me how to upload it to google drive and get the link?

I just uploaded the file to my google drive, So now how do I attach a link to the file?

Right click file → Share → Copy link

Ok, so here is the video

As you can see (I hope you do see it there), the ball stays in a vertical line and never changes direction, It should work just like a pong game, But I’m not sure how to achieve it.

I’m also still very new to the language and I’m still working on how to write Code on my own, so could you also explain how it works and what I could do to get better at GDscript?

Hi, with rotation_degrees the ball rotates around its own axis, which is why the ball does not change its direction in the field.
This is okay for a programmed animation without AnimationPlayer but not for changing the direction of the ball.

This is translated using Google Translate because I can barely speak English.
Just in case something is translated incorrectly.

1 Like

If you like I can send you a link with my ball script and also a short video so you can see the physics.
I’m still a beginner in programming myself and can’t explain various things in detail.

Oh, I see, Silly me. I thought the ball would change its direction based on the Vector2 axis but it’s just going on its own axis and isn’t global, so could you show me the video and link with the ball script please?

Also you can just click the </> button and copy the code from there, Your Welcome :smiley:

1 Like

Yes, the rotation with rotation_degrees is present in the inspector and is therefore used that way. At least as far as I understand the engine.

https://drive.google.com/drive/folders/1XfOh7VAWvUBwNjNZLkWTC1gDBrl6GbLB?usp=drive_link

Ahh cool thank you. :slight_smile:

signal position_changed(y)

var speed = 1350
var movement = Vector2(speed, 0)
var can_move = true


func _physics_process(delta):
	if can_move == true:
		var collision_info = move_and_collide(movement * delta)
		emit_signal("position_changed", position.y)
		
		if collision_info:
			if collision_info.get_collider().name == "Spieler" or collision_info.get_collider().name == "Spieler2" or collision_info.get_collider().name == "Gegner":
				speed = -speed
				$Treffer.play()
				
				var diff = collision_info.get_collider().position.y - position.y
				var new_movement = Vector2(speed, -diff * 8)
				movement = new_movement
					
			elif collision_info.get_collider().name == "Wand" or collision_info.get_collider().name == "Wand2":
				movement = movement.bounce(collision_info.get_normal())
				$Treffer.play()
1 Like

The code is a lot and there a lot of things that I don’t need in my script, so if possible could you show me the code that deals with the ball collision and making it change direction?

Also, just wondering, are there any other places where I could further improve my knowledge of GDScript?

Yes, that’s right, it can be a little confusing, I’ve now removed everything that isn’t important.

extends CharacterBody2D

var speed = 1350
var movement = Vector2(-speed, 0)

func _physics_process(delta):

	var collision = move_and_collide(movement * delta)
		
	if collision:
		if collision.get_collider().name == "Player":
			speed = -speed
				
				
			var diff = collision.get_collider().position.y - position.y
				
			var new_movement = Vector2(speed, -diff * 8)
				
			movement = new_movement
		
		elif collision.get_collider().name == "Wall":
			movement = movement.bounce(collision.get_normal())
				

And to address your last question.
I use YouTube and the documentation on the Godot website.
And I’m trying to get in touch with people who are already better at programming here in the forum, but only recently.

I hope Google Translate isn’t so confusing.

The Code is easier to understand now, but (sorry if I’m asking for too much), I still need the code to be more specific, I already have everything else, so I only need the collision code that deals with the ball changing direction and recognizing collisions. also if possible, could you also explain the code to me?

Also, my pong game has the ball going vertically and not horizontally, so maybe also change anything that uses the X position to the Y position?

What I’m referring to btw:

Just realized I can now send photos, so I was able to add this

Oh and no, the Google translate isn’t confusing, I can understand what you’re saying very clearly.
So, if I’m trying to do anything GDscript related and it doesn’t work, I should refer to the Godot documentation?

1 Like