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) and S (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: yVelocity maintains current movement state
  • Direction Control: Positive/negative values control up/down
  • Speed Constant: speed = 10 pixels 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 movement

Benefits:

  • 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

  1. Input Design: Why handle both keyPressed and keyReleased events?
  2. Architecture: How would you add AI control for single-player mode?
  3. Performance: What happens if move() is called multiple times per frame?
  4. Extensibility: How would you add different paddle sizes or speeds?

Next: See how game scoring works in Score.java