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:
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 positiondraw()
- 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