I'm currently working on my Pong game project using Godot.
Everything is working well but there's only one problem.
After one side gets scored, the ball is stuck in the middle and not working.
What should I add? Here is my code:
# Declare member variables here.
var ball
var player
var computer
var player_score = 0
var computer_score = 0
var winning_score = 5
var initial_velocity_x = 250
var initial_velocity_y = 10
# Called when the node enters the scene tree for the first time.
func _ready():
player = get_node('player')
computer = get_node('computer')
ball = get_node('ball')
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
player.position.y = get_viewport().get_mouse_position().y
computer.position.y = ball.position.y
if ball.position.x > 1024:
reset_position()
ball.linear_velocity.x = initial_velocity_x
ball.linear_velocity.y = initial_velocity_y
computer_score += 1
if ball.position.x < 0:
reset_position()
ball.linear_velocity.x = -initial_velocity_x
ball.linear_velocity.y = initial_velocity_y
player_score += 1
if player_score >= winning_score or computer_score >= winning_score:
player_score = 0
computer_score = 0
func reset_position():
ball.position.x = 512
ball.position.y = 300
I'm guessing the ball is a RigidBody2D
.
They are intended to be moved by the physics engine, and moving them directly (e.g. setting position
) can cause problems. This one of the reason I often recommend beginners to use KinematicBody
(2D
), so they are not "fighting" the physics engine.
Anyway, that is a cop-out answer. You want to teleport a RigidBody2D
, let us see how to do it.
The following is - in my opinion - the elusive proper way to teleport a RigidBody2D
:
func reset_position():
Physics2DServer.body_set_state(
ball.get_rid(),
Physics2DServer.BODY_STATE_TRANSFORM,
Transform2D.IDENTITY.translated(Vector2(512, 300))
)
You are basically saying: "Hey, Physics Engine! Yes, you. I want you to place the body at this position." And the Physics Engines goes: "OK".
The Physics2DServer
API is intended for advanced use, when using nodes won't do. And as such, not beginner friendly.
Instead, the most common solution to teleport a RigidBody2D
involves adding an script to it. It looks like this:
extends RigidBody2D
var _teleport_target:Vector2
var _teleporting:bool
func _integrate_forces(state: Physics2DDirectBodyState) -> void:
if _teleporting:
state.transform.origin = _teleport_target
_teleporting = false
func teleport(position:Vector2) -> void:
_teleporting = true
_teleport_target = position
And then you use it like this:
func reset_position():
ball.teleport(Vector2(512, 300))
Here you have told the Physics Engine to ask you every time if you want to change something (it will call _integrate_forces
if you define it). And occasionally you answer by telling it to move the body.