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:
random.nextInt(2)
: Generates 0 or 1- Convert to Direction: 0 becomes -1 (left), 1 stays 1 (right)
- Apply Speed: Multiply by initialSpeed for velocity
- Result: Ball starts moving left or right randomly
Math Breakdown:
- If
randomXDirection = 0
: After decrement becomes-1
, velocity =-1 * 4 = -4
- If
randomXDirection = 1
: Stays1
, 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
- Bug Analysis: What happens to ball movement with the bug in line 27?
- Physics: How would you implement ball rotation or spin?
- Performance: Is creating a new Random object every ball creation efficient?
- Design: Why extend Rectangle instead of creating a separate Position class?
Next: Check out Paddle.java to see how player input controls game objects.