Game Over & Complete Code
Let's finish the game by adding win conditions, a game over screen, and restart functionality!
Step 1: Add Game State Variables
Add these variables at the top:
// Scores
let leftScore = 0;
let rightScore = 0;
let winningScore = 5; // NEW: First to 5 wins
let gameOver = false; // NEW: Is the game over?
let winner = ""; // NEW: Who won?
Breaking it down
winningScore = 5- First player to reach 5 points winsgameOver = false- Tracks if game has endedwinner = ""- Stores name of winning player ("LEFT" or "RIGHT")
Step 2: Check for Win Condition
Add this code right after awarding points:
// Reset ball and award points
if (ballX < 0 || ballX > width) {
if (ballX < 0) {
rightScore++;
} else {
leftScore++;
}
// Check if someone won
if (leftScore >= winningScore) {
gameOver = true;
winner = "LEFT";
} else if (rightScore >= winningScore) {
gameOver = true;
winner = "RIGHT";
}
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
}
Breaking it down
if (leftScore >= winningScore)- Left player reached 5 points- Set
gameOver = trueto stop the game - Set
winner = "LEFT"to show who won
- Set
- Same check for right player
- Only one can win, so we use
else if
Step 3: Stop Game When Someone Wins
Wrap the game logic in a condition so it only runs while playing:
function draw() {
background(0);
// Draw center line
stroke(255);
strokeWeight(2);
for (let i = 0; i < height; i += 20) {
line(width / 2, i, width / 2, i + 10);
}
noStroke();
// Display scores
fill(150);
textSize(96);
textAlign(CENTER);
text(leftScore, width / 4, 120);
text(rightScore, 3 * width / 4, 120);
// Only run game logic if game is not over
if (!gameOver) {
// Left paddle movement
if (keyIsDown(87)) {
leftPaddleY -= paddleSpeed;
}
// ... all the paddle movement, ball movement, collision code ...
}
// Always draw paddles and ball (even when game over)
fill(255);
rect(20, leftPaddleY, paddleWidth, paddleHeight);
rect(770, rightPaddleY, paddleWidth, paddleHeight);
circle(ballX, ballY, ballSize);
}
Breaking it down
if (!gameOver)- Only runs when game is NOT over!means "not" - flips true/false- While playing, gameOver is false, so !false = true
- When game ends, gameOver is true, so !true = false
- Movement and physics stop when someone wins
- Paddles and ball still draw (show final positions)
Step 4: Display Win Screen
Add this code at the very end of draw(), after drawing the ball:
// Draw ball
circle(ballX, ballY, ballSize);
// Display game over screen
if (gameOver) {
// Semi-transparent overlay
fill(0, 0, 0, 200);
rect(0, 0, width, height);
// Winner text
fill(255);
textSize(64);
textAlign(CENTER, CENTER);
text(winner + " PLAYER WINS!", width / 2, height / 2 - 40);
// Restart instruction
textSize(24);
text("Press SPACE to play again", width / 2, height / 2 + 40);
}
}
Breaking it down
-
fill(0, 0, 0, 200)- Black with 200 alpha (semi-transparent) -
rect(0, 0, width, height)- Covers entire screen- Creates darkened overlay effect
- Game is still visible underneath
-
text(winner + " PLAYER WINS!", ...)- Shows winnerwinneris either "LEFT" or "RIGHT"+combines strings: "LEFT" + " PLAYER WINS!" = "LEFT PLAYER WINS!"
-
textAlign(CENTER, CENTER)- Centers text both ways -
width / 2, height / 2- Exact center of screen
Test it: Play until someone reaches 5 points - you should see the win screen!
Step 5: Add Restart Functionality
Add a keyPressed() function at the bottom of your code:
function keyPressed() {
// Restart game when SPACE is pressed
if (key === ' ' && gameOver) {
// Reset scores
leftScore = 0;
rightScore = 0;
// Reset game state
gameOver = false;
winner = "";
// Reset ball position
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
// Reset paddle positions
leftPaddleY = 200;
rightPaddleY = 200;
}
}
Breaking it down
keyPressed()- Special function that runs once when any key is pressedkey === ' '- Checks if spacebar was pressed&& gameOver- Only works when game is over (prevents accidental restart)- Resets everything to starting values:
- Scores back to 0
- Game state back to playing
- Ball back to center with random direction
- Paddles back to middle position
Test it: Win a game, then press SPACE - everything should reset!
Complete Final Code
Here's the complete, fully functional Pong game:
// Left paddle
let leftPaddleY = 200;
let paddleWidth = 10;
let paddleHeight = 80;
let paddleSpeed = 5;
// Right paddle
let rightPaddleY = 200;
// Ball
let ballX = 400;
let ballY = 200;
let ballSize = 15;
let ballSpeedX = 5;
let ballSpeedY = 3;
// Scores
let leftScore = 0;
let rightScore = 0;
let winningScore = 5;
let gameOver = false;
let winner = "";
function setup() {
createCanvas(800, 400);
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
}
function draw() {
background(0);
// Draw center line
stroke(255);
strokeWeight(2);
for (let i = 0; i < height; i += 20) {
line(width / 2, i, width / 2, i + 10);
}
noStroke();
// Display scores
fill(150);
textSize(96);
textAlign(CENTER);
text(leftScore, width / 4, 120);
text(rightScore, 3 * width / 4, 120);
fill(255);
textSize(48);
text(leftScore, width / 4, 60);
text(rightScore, 3 * width / 4, 60);
// Only run game logic if game is not over
if (!gameOver) {
// Left paddle movement
if (keyIsDown(87)) {
leftPaddleY -= paddleSpeed;
}
if (keyIsDown(83)) {
leftPaddleY += paddleSpeed;
}
leftPaddleY = constrain(leftPaddleY, 0, height - paddleHeight);
// Right paddle movement
if (keyIsDown(UP_ARROW)) {
rightPaddleY -= paddleSpeed;
}
if (keyIsDown(DOWN_ARROW)) {
rightPaddleY += paddleSpeed;
}
rightPaddleY = constrain(rightPaddleY, 0, height - paddleHeight);
// Move the ball
ballX += ballSpeedX;
ballY += ballSpeedY;
// Bounce off top and bottom walls
if (ballY <= ballSize / 2 || ballY >= height - ballSize / 2) {
ballSpeedY = ballSpeedY * -1;
}
// Check collision with left paddle
if (ballX - ballSize / 2 <= 20 + paddleWidth) {
if (ballY >= leftPaddleY && ballY <= leftPaddleY + paddleHeight) {
ballSpeedX = abs(ballSpeedX) * 1.05;
ballX = 20 + paddleWidth + ballSize / 2;
let hitPos = (ballY - leftPaddleY) / paddleHeight;
ballSpeedY = (hitPos - 0.5) * 10;
}
}
// Check collision with right paddle
if (ballX + ballSize / 2 >= 770) {
if (ballY >= rightPaddleY && ballY <= rightPaddleY + paddleHeight) {
ballSpeedX = -abs(ballSpeedX) * 1.05;
ballX = 770 - ballSize / 2;
let hitPos = (ballY - rightPaddleY) / paddleHeight;
ballSpeedY = (hitPos - 0.5) * 10;
}
}
// Reset ball and award points
if (ballX < 0 || ballX > width) {
if (ballX < 0) {
rightScore++;
} else {
leftScore++;
}
// Check if someone won
if (leftScore >= winningScore) {
gameOver = true;
winner = "LEFT";
} else if (rightScore >= winningScore) {
gameOver = true;
winner = "RIGHT";
}
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
}
}
// Always draw paddles and ball
fill(255);
rect(20, leftPaddleY, paddleWidth, paddleHeight);
rect(770, rightPaddleY, paddleWidth, paddleHeight);
circle(ballX, ballY, ballSize);
// Display game over screen
if (gameOver) {
fill(0, 0, 0, 200);
rect(0, 0, width, height);
fill(255);
textSize(64);
textAlign(CENTER, CENTER);
text(winner + " PLAYER WINS!", width / 2, height / 2 - 40);
textSize(24);
text("Press SPACE to play again", width / 2, height / 2 + 40);
}
}
function keyPressed() {
if (key === ' ' && gameOver) {
leftScore = 0;
rightScore = 0;
gameOver = false;
winner = "";
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
leftPaddleY = 200;
rightPaddleY = 200;
}
}
Play Your Game!
🎮 Controls:
- Left Player: W (up) and S (down)
- Right Player: Arrow keys (up/down)
- Restart: SPACE (after game over)
Try to beat your friend to 5 points!
What You Built
Congratulations! You've created a complete Pong game with:
- ✅ Two-player paddle controls
- ✅ Realistic ball physics
- ✅ Collision detection
- ✅ Progressive difficulty (ball speeds up)
- ✅ Score tracking
- ✅ Win conditions
- ✅ Game over screen
- ✅ Restart functionality
Ideas to Expand
Want to make your Pong even better? Try adding:
Easy Additions
- Change colors (make paddles or ball different colors)
- Adjust winning score (
winningScore = 10) - Change paddle speed or ball speed
- Make the canvas bigger or smaller
Medium Difficulty
- Add sound effects (see Sound guide)
- Create a "Ready? Set! Go!" countdown
- Add particle effects when ball hits paddle
- Display "GOAL!" text briefly when someone scores
- Add a pause button
Advanced Features
- AI opponent - Make computer control one paddle
- Power-ups - Ball speed boost, bigger paddle, etc.
- Different game modes - First to 10, timed matches
- Ball trail effect - Leave fading trail behind ball
- Custom angles - More control over ball direction
- Save high scores - Use localStorage (see Saving Data guide)
What You Learned
Through building Pong, you learned:
- Game loops and state management
- Physics and velocity
- Collision detection
- Two-player input handling
- Game over conditions
- Score systems
- Restart functionality
These skills apply to almost every game you'll make!
Share Your Creation
Made something cool? Share it with friends:
- Click "File" → "Share" in the p5.js editor
- Send the link to your friends
- Challenge them to beat your high score!
Next Steps
Ready for more? Check out:
- Cookie Clicker Tutorial - Learn about upgrade systems
- Worm Game Tutorial - Create a Snake-like game
- Common Elements - Reference for sounds, images, and more
Congratulations on completing the Pong tutorial! 🎉
You've mastered one of gaming's most iconic classics and learned fundamental game development skills in the process. Keep experimenting and building!