Skip to main content

Overview

The ball physics system in Space Pong controls how the ball moves, accelerates, and responds to collisions. The ball is implemented as a CharacterBody2D node with custom velocity management and progressive speed increases.

Core Physics Properties

The ball physics are defined by three key variables in scenes/ball.gd:
var started = false
var start_speed = 500
var incremental_speed = 1.05
var angle = [-250, 250]

Initial Speed

The ball starts at 500 pixels per second when the game begins

Speed Multiplier

Each collision increases velocity by 5% (1.05x multiplier)

Angle Variation

Random horizontal velocity between -250 and 250 pixels/second

Game State

The started flag prevents movement until player initiates

Game Initialization

When the player presses the “Start” action, the start_game() function initializes the ball’s velocity:
func start_game():
	started = true
	velocity.y = -start_speed
	velocity.x = angle.pick_random()
1

Set Game State

The started flag is set to true, enabling physics processing
2

Initialize Vertical Velocity

The Y velocity is set to -start_speed (-500), launching the ball upward
3

Randomize Horizontal Velocity

The X velocity is randomly selected from the range [-250, 250], creating unpredictable launch angles
The negative Y velocity (-500) moves the ball upward because Godot’s coordinate system has Y increasing downward. A negative Y value moves objects toward the top of the screen.

Movement System

The ball’s movement is processed every physics frame using Godot’s _physics_process() callback:
func _physics_process(delta):
	if Input.is_action_pressed("Start") and started == false: 
		start_game()  
		
	if started:
		var collision = move_and_collide(velocity * delta)
		if collision != null:
			velocity = velocity.bounce(collision.get_normal()) * incremental_speed
			print(velocity)

Movement Breakdown

1

Check for Game Start

If the “Start” input is pressed and the game hasn’t started, initialize the game
2

Move with Collision Detection

move_and_collide(velocity * delta) moves the ball and returns collision information if a collision occurs
3

Handle Collisions

When a collision is detected, the velocity is bounced using the collision normal and multiplied by the speed increase factor

Velocity Calculations

Delta Time Scaling

The velocity is multiplied by delta (the time elapsed since the last frame) to ensure frame-rate independent movement:
var collision = move_and_collide(velocity * delta)
This means if the ball has a velocity of 500 pixels/second and delta is 0.016 (60 FPS), the ball moves 8 pixels that frame.

Progressive Speed Increase

After each collision, the ball’s velocity increases:
velocity = velocity.bounce(collision.get_normal()) * incremental_speed
The incremental_speed value of 1.05 means:
  • After 1st collision: velocity × 1.05
  • After 2nd collision: velocity × 1.05 × 1.05 = velocity × 1.1025
  • After 3rd collision: velocity × 1.157625
  • After 10 collisions: velocity × 1.629
The ball’s speed increases exponentially with each collision. After many collisions, the ball can become extremely fast, making the game progressively more challenging.

Physics Process Flow

Key Characteristics

Deterministic Launch

The ball always launches upward with vertical velocity of -500, ensuring consistent initial direction

Variable Angle

Horizontal velocity randomization creates unique trajectories each game

Difficulty Scaling

The 5% speed increase per collision naturally increases difficulty as gameplay progresses

State Management

The started boolean prevents premature movement and allows the player to control game initiation

Performance Considerations

  • Physics Processing: The ball uses _physics_process() which runs at a fixed rate (default 60 times per second), ensuring consistent physics behavior
  • Collision Detection: move_and_collide() is called every physics frame only when the game has started, minimizing unnecessary computations
  • Debug Output: The print(velocity) statement logs velocity after each collision, useful for debugging but should be removed in production builds

Build docs developers (and LLMs) love