Ball.java - Ball Physics

The Ball class represents the game ball with physics-based movement, collision handling, and rendering. This class demonstrates inheritance, random number generation, and basic game physics.

Purpose: Manages ball movement, direction changes, and visual representation in the Pong game.

Source Code

 1import java.awt.*;
 2import java.util.*;
 3
 4public class Ball extends Rectangle{
 5
 6    Random random;
 7    int xVelocity;
 8    int yVelocity;
 9    int initialSpeed = 4;
10
11    Ball(int x, int y, int width, int height){
12        super(x, y, width, height);
13        random = new Random();
14        int randomXDirection = random.nextInt(2);
15
16        if(randomXDirection==0)
17            randomXDirection--;
18        setXDirection(randomXDirection*initialSpeed);
19
20        int randomYDirection = random.nextInt(2);
21
22        if(randomYDirection==0)
23            randomYDirection--;
24        setXDirection(randomYDirection*initialSpeed);  // ⚠️ BUG: Should be setYDirection!
25    }
26
27    public void setXDirection(int randomXDirection){
28        xVelocity = randomXDirection;
29    }
30    
31    public void setYDirection(int randomYDirection){
32        yVelocity=randomYDirection;
33    }
34    
35    public void move(){
36        x+=xVelocity;
37        y+=yVelocity;
38    }
39    
40    public void draw(Graphics g){
41        g.setColor(Color.white);
42        g.fillOval(x, y, height, width);
43    }
44}

Code Analysis

Inheritance Structure

Extending Rectangle
1public class Ball extends Rectangle

Benefits of Inheritance:

  • Built-in Collision Detection: Rectangle.intersects() method
  • Position Management: x, y, width, height fields inherited
  • Geometric Operations: Area calculations, bounds checking
  • Standard Interface: Consistent with other game objects

Constructor Chain:

1Ball(int x, int y, int width, int height){
2    super(x, y, width, height);  // Call Rectangle constructor
3    // ... additional Ball-specific initialization
4}

Physics System

Velocity Components
1int xVelocity;  // Horizontal speed and direction
2int yVelocity;  // Vertical speed and direction
3int initialSpeed = 4;  // Base speed constant

Velocity System:

  • Signed Integers: Positive/negative values indicate direction
  • X Velocity: Left (negative) or Right (positive)
  • Y Velocity: Up (negative) or Down (positive)
  • Speed Control: Magnitude determines how fast ball moves
Movement Implementation
1public void move(){
2    x += xVelocity;
3    y += yVelocity;
4}

Simple Physics:

  • Position Update: Add velocity to current position each frame
  • Linear Movement: Constant velocity until collision
  • Frame-Rate Dependent: Movement tied to game loop frequency

Random Direction Generation

Initial Direction Logic
1int randomXDirection = random.nextInt(2);  // Returns 0 or 1
2if(randomXDirection==0)
3    randomXDirection--;  // Convert 0 to -1, keep 1 as 1
4setXDirection(randomXDirection*initialSpeed);

Randomization Process:

  1. random.nextInt(2): Generates 0 or 1
  2. Convert to Direction: 0 becomes -1 (left), 1 stays 1 (right)
  3. Apply Speed: Multiply by initialSpeed for velocity
  4. Result: Ball starts moving left or right randomly

Math Breakdown:

  • If randomXDirection = 0: After decrement becomes -1, velocity = -1 * 4 = -4
  • If randomXDirection = 1: Stays 1, velocity = 1 * 4 = 4

🐛 Bug Alert!

Line 27 Bug:

1setXDirection(randomYDirection*initialSpeed);  // Should be setYDirection!

Problem: The Y direction is being set using setXDirection() instead of setYDirection().

Impact: Ball Y velocity is not properly randomized at startup.

Fix:

1setYDirection(randomYDirection*initialSpeed);

Rendering System

Drawing Method
1public void draw(Graphics g){
2    g.setColor(Color.white);
3    g.fillOval(x, y, height, width);
4}

Rendering Details:

  • Color: White ball on black background for visibility
  • Shape: fillOval() creates a filled circle/ellipse
  • Position: Uses inherited x, y coordinates
  • Size: Uses height, width from Rectangle (should be equal for circle)

Note: height, width parameter order is unusual - typically width, height

Direction Control Methods

Velocity Setters
1public void setXDirection(int randomXDirection){
2    xVelocity = randomXDirection;
3}
4
5public void setYDirection(int randomYDirection){
6    yVelocity = randomYDirection;
7}

Design Purpose:

  • Encapsulation: Controlled access to velocity fields
  • Collision Response: Called by GamePanel when ball hits objects
  • Direction Reversal: Can pass negative values to reverse direction
  • Speed Changes: Can pass different magnitudes to change speed

Physics Concepts

Vector Movement

The ball uses a simple 2D vector system:

1// Vector representation: (xVelocity, yVelocity)
2// Example vectors:
3(4, 4)   // Moving right and down
4(-4, 4)  // Moving left and down  
5(4, -4)  // Moving right and up
6(-4, -4) // Moving left and up

Collision Response

When the ball hits objects, the GamePanel modifies its velocity:

1// Typical collision responses:
2ball.setXDirection(-ball.xVelocity);  // Reverse horizontal direction
3ball.setYDirection(-ball.yVelocity);  // Reverse vertical direction

Design Patterns

Component Pattern

  • Self-Contained: Ball manages its own state and behavior
  • Clear Interface: Simple methods for external control
  • Inheritance Hierarchy: Builds on Rectangle foundation

State Management

  • Position State: Inherited x, y coordinates
  • Velocity State: xVelocity, yVelocity for movement
  • Rendering State: Color and shape properties

Enhancement Ideas

Physics Improvements
 1// Add acceleration
 2double acceleration = 0.1;
 3xVelocity += acceleration;
 4
 5// Add maximum speed limits
 6private static final int MAX_SPEED = 10;
 7if(Math.abs(xVelocity) > MAX_SPEED) {
 8    xVelocity = MAX_SPEED * (xVelocity > 0 ? 1 : -1);
 9}
10
11// Add spin effects
12double spinFactor = 0.1;
13yVelocity += (int)(xVelocity * spinFactor);
Visual Enhancements
 1// Add trail effect
 2private List<Point> trail = new ArrayList<>();
 3public void draw(Graphics g) {
 4    // Draw trail
 5    for(int i = 0; i < trail.size(); i++) {
 6        int alpha = 255 - (i * 50); // Fade effect
 7        g.setColor(new Color(255, 255, 255, Math.max(0, alpha)));
 8        Point p = trail.get(i);
 9        g.fillOval(p.x, p.y, width/2, height/2);
10    }
11    
12    // Draw main ball
13    g.setColor(Color.white);
14    g.fillOval(x, y, width, height);
15}

Study Questions

  1. Bug Analysis: What happens to ball movement with the bug in line 27?
  2. Physics: How would you implement ball rotation or spin?
  3. Performance: Is creating a new Random object every ball creation efficient?
  4. Design: Why extend Rectangle instead of creating a separate Position class?

Next: Check out Paddle.java to see how player input controls game objects.