Paddle.java - Player Controls
The Paddle class handles player-controlled paddles with keyboard input, movement logic, and visual rendering. This demonstrates event handling, state management, and player differentiation.
Purpose: Manages player-controlled paddles including input handling, movement constraints, and visual representation.
Source Code
 1import java.awt.*;
 2import java.awt.event.*;
 3
 4public class Paddle extends Rectangle{
 5    int id;
 6    int yVelocity;
 7    int speed = 10;
 8    
 9    Paddle(int x, int y, int PADDLE_WIDTH, int PADDLE_HEIGHT, int id){
10        super(x,y,PADDLE_WIDTH,PADDLE_HEIGHT);
11        this.id = id;
12    }
13
14    public void keyPressed(KeyEvent e){
15        switch (id){
16            case 1:
17                if(e.getKeyCode()==KeyEvent.VK_W){
18                    setYDirection(-speed);
19                    move();
20                }
21                if(e.getKeyCode()==KeyEvent.VK_S){
22                    setYDirection(speed);
23                    move();
24                }
25                break;
26            case 2:
27                if(e.getKeyCode()==KeyEvent.VK_UP){
28                    setYDirection(-speed);
29                    move();
30                }
31                if(e.getKeyCode()==KeyEvent.VK_DOWN){
32                    setYDirection(speed);
33                    move();
34                }
35                break;
36        }
37    }
38    
39    public void keyReleased(KeyEvent e){
40        switch (id){
41            case 1:
42                if(e.getKeyCode()==KeyEvent.VK_W){
43                    setYDirection(0);
44                    move();
45                }
46                if(e.getKeyCode()==KeyEvent.VK_S){
47                    setYDirection(0);
48                    move();
49                }
50                break;
51            case 2:
52                if(e.getKeyCode()==KeyEvent.VK_UP){
53                    setYDirection(0);
54                    move();
55                }
56                if(e.getKeyCode()==KeyEvent.VK_DOWN){
57                    setYDirection(0);
58                    move();
59                }
60                break;
61        }
62    }
63    
64    public void setYDirection(int yDirection){
65        yVelocity = yDirection;
66    }
67    
68    public void move(){
69        y = y + yVelocity;
70    }
71    
72    public void draw(Graphics g){
73        if (id==1)
74            g.setColor(Color.BLUE);
75        else
76            g.setColor(Color.red);
77        g.fillRect(x, y, width, height);
78    }
79}Code Analysis
Object Design
Constructor and ID System
1Paddle(int x, int y, int PADDLE_WIDTH, int PADDLE_HEIGHT, int id){
2    super(x,y,PADDLE_WIDTH,PADDLE_HEIGHT);
3    this.id = id;
4}Player Identification:
- ID Field: Distinguishes between Player 1 (id=1) and Player 2 (id=2)
- Position Setup: Each paddle positioned at different x coordinates
- Size Consistency: Both paddles use same width/height constants
- Inheritance: Rectangle provides collision detection and position management
Usage in GamePanel:
1paddle1 = new Paddle(0, y_center, PADDLE_WIDTH, PADDLE_HEIGHT, 1);
2paddle2 = new Paddle(GAME_WIDTH-PADDLE_WIDTH, y_center, PADDLE_WIDTH, PADDLE_HEIGHT, 2);Input Handling System
Key Mapping Strategy
 1switch (id){
 2    case 1:  // Player 1 - WASD style
 3        if(e.getKeyCode()==KeyEvent.VK_W){
 4            setYDirection(-speed);  // Move up (negative Y)
 5        }
 6        if(e.getKeyCode()==KeyEvent.VK_S){
 7            setYDirection(speed);   // Move down (positive Y)
 8        }
 9        break;
10    case 2:  // Player 2 - Arrow keys
11        if(e.getKeyCode()==KeyEvent.VK_UP){
12            setYDirection(-speed);  // Move up
13        }
14        if(e.getKeyCode()==KeyEvent.VK_DOWN){
15            setYDirection(speed);   // Move down
16        }
17        break;
18}Key Control Scheme:
- Player 1: W(up) andS(down) - Left-hand placement
- Player 2: ↑(up) and↓(down) - Right-hand placement
- Coordinate System: Y=0 at top, positive Y goes down
- Speed: Constant movement speed when key is held
Press vs Release Handling
 1public void keyPressed(KeyEvent e){
 2    // Set velocity to move paddle
 3    setYDirection(speed);  // or -speed
 4    move();
 5}
 6
 7public void keyReleased(KeyEvent e){
 8    // Stop paddle movement
 9    setYDirection(0);
10    move();
11}State Management:
- Key Pressed: Set velocity, start movement
- Key Released: Zero velocity, stop movement
- Immediate Response: move()called on each event
- Smooth Movement: Continuous motion while key held down
Movement System
Velocity-Based Movement
 1int yVelocity;  // Current vertical speed
 2int speed = 10; // Movement speed constant
 3
 4public void setYDirection(int yDirection){
 5    yVelocity = yDirection;
 6}
 7
 8public void move(){
 9    y = y + yVelocity;
10}Movement Mechanics:
- Velocity Storage: yVelocitymaintains current movement state
- Direction Control: Positive/negative values control up/down
- Speed Constant: speed = 10pixels per frame
- Position Update: Simple addition to y coordinate
Visual Representation
Color-Coded Rendering
1public void draw(Graphics g){
2    if (id==1)
3        g.setColor(Color.BLUE);
4    else
5        g.setColor(Color.red);
6    g.fillRect(x, y, width, height);
7}Visual Design:
- Player 1: Blue paddle (left side)
- Player 2: Red paddle (right side)
- Shape: Rectangular using fillRect()
- Size: Uses inherited width/height from Rectangle
- Position: Uses inherited x/y coordinates
Event-Driven Programming Concepts
KeyEvent Handling
Event Object Analysis
1public void keyPressed(KeyEvent e){
2    int keyCode = e.getKeyCode();
3    // keyCode constants:
4    // KeyEvent.VK_W = 87
5    // KeyEvent.VK_S = 83  
6    // KeyEvent.VK_UP = 38
7    // KeyEvent.VK_DOWN = 40
8}KeyEvent Properties:
- Key Codes: Integer constants for each keyboard key
- Event Types: Pressed, Released, Typed (only using first two)
- Cross-Platform: Java handles different keyboard layouts
- Timing: Events fired automatically by input system
State Management Pattern
Movement State Machine
Paddle States:
├── IDLE (yVelocity = 0)
├── MOVING_UP (yVelocity = -speed)
└── MOVING_DOWN (yVelocity = +speed)
State Transitions:
Key Pressed → Set velocity → Start movement
Key Released → Zero velocity → Stop movementBenefits:
- Predictable Behavior: Clear state transitions
- Responsive Controls: Immediate reaction to input
- Clean Stop: Paddle stops exactly when key released
Design Patterns
Strategy Pattern (Implicit)
Each paddle has different key mappings but identical movement logic:
1// Same movement method, different input triggers
2paddle1.keyPressed(event); // Responds to W/S
3paddle2.keyPressed(event); // Responds to ↑/↓Template Method Pattern
All game objects follow the same interface:
- move()- Update position
- draw()- Render to screen
- Input handling specific to paddle objects
Performance Considerations
Input Efficiency
Event-Driven vs Polling:
- Current: Event-driven (efficient) - only processes when keys change
- Alternative: Polling (inefficient) - check key state every frame
Memory Usage:
- Lightweight Objects: Only essential fields stored
- No Animation: Static appearance reduces memory
- Shared Constants: Speed value could be static
Movement Optimization
1// Current approach:
2public void move(){
3    y = y + yVelocity;  // Simple but adequate
4}
5
6// Enhanced approach:
7public void move(double deltaTime){
8    y += yVelocity * deltaTime;  // Frame-rate independent
9}Enhancement Ideas
Control Improvements
 1// Acceleration-based movement
 2private double acceleration = 0.5;
 3private double maxSpeed = 15;
 4
 5public void updateMovement() {
 6    if(isMovingUp) {
 7        yVelocity = Math.max(-maxSpeed, yVelocity - acceleration);
 8    } else if(isMovingDown) {
 9        yVelocity = Math.min(maxSpeed, yVelocity + acceleration);
10    } else {
11        // Deceleration when no input
12        yVelocity *= 0.9;
13    }
14}Visual Enhancements
 1// Animated paddle
 2private boolean isMoving = false;
 3
 4public void draw(Graphics g) {
 5    // Change appearance when moving
 6    if(isMoving) {
 7        g.setColor(id == 1 ? Color.CYAN : Color.PINK);
 8    } else {
 9        g.setColor(id == 1 ? Color.BLUE : Color.RED);
10    }
11    
12    // Add border effect
13    g.fillRect(x, y, width, height);
14    g.setColor(Color.WHITE);
15    g.drawRect(x, y, width, height);
16}Study Questions
- Input Design: Why handle both keyPressed and keyReleased events?
- Architecture: How would you add AI control for single-player mode?
- Performance: What happens if move() is called multiple times per frame?
- Extensibility: How would you add different paddle sizes or speeds?
Next: See how game scoring works in Score.java