I'm working on making Pong and I have two paddles on each side of the screen. Originally, I was using Input.get_vector()
but that forced me to take in 4 arguments when I only need two. I also tried using Input.get_axis()
but I was having trouble getting that to work.
Now I've went back to basics and started using Input.is_action_pressed()
because it seemed less complicated and I ended the function with using move_and_collide()
as I'll need the ball in the middle to bounce off the paddle and I don't think move_and_slide()
would be best for that.
When I run the code it sort of works as intended but even with speed
set to 1
the paddle goes incredibly fast. Also, the gravity is kind of wonky as even if I tap the up
arrow just once, the paddle doesn't stop moving.
How can I fix my code so that the paddle doesn't zoom off screen and actually stops when I let go of the arrow key?
extends CharacterBody2D
var speed: int = 1
func _physics_process(delta):
if Input.is_action_pressed("p2_up"):
velocity.y -= speed
elif Input.is_action_pressed("p2_down"):
velocity.y += speed
move_and_collide(velocity)
First, the units Godot 4 uses are metres and seconds. So, an speed of 1
is one metre per second.
Second, _physics_process
will run once every physics frame, which by default is 60
times per second.
Third, Input.is_action_pressed
returns true
if the action is pressed, and false
otherwise.
Thus, here:
extends CharacterBody2D
var speed: int = 1
func _physics_process(delta):
if Input.is_action_pressed("p2_up"):
velocity.y -= speed
elif Input.is_action_pressed("p2_down"):
velocity.y += speed
move_and_collide(velocity)
You are incrementing/decrementing the velocity by one second per metre per second, 60 times per second as long as you have the action pressed.
So, in one second the character body goes from zero to 60 metres per second (134.2 miles per hour or 216 kilometers per hour).
And you never reset the velocity.
I believe you intended to set the velocity instead of incrementing/decrementing it:
extends CharacterBody2D
var speed: float = 1.0
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("p2_up"):
velocity.y = - speed
elif Input.is_action_pressed("p2_down"):
velocity.y = speed
else:
velocity.y = 0.0
move_and_collide(velocity)
If you wanted to support analog input you could use get_action_strength
... But it is easier to use get_axis
:
extends CharacterBody2D
var speed: float = 1.0
func _physics_process(delta:float) -> void:
velocity.y = Input.get_axis("p2_up", "p2_down")
move_and_collide(velocity)
Using get_vector
makes no sense here since it is only one axis.
You say the gravity is wonky, but the code in question does not have gravity.
You are responsible of the motion of the CharacterBody2D
, and that includes implementing gravity.
You can implement gravity and bounces yourself. However, if you want to create an object that other things can push, consider using RigidBody2D
instead. If you do, Godot will handle gravity and bounces for you, and you would have to control it by adding forces and impulses instead.