Skip to main content

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 wins
  • gameOver = false - Tracks if game has ended
  • winner = "" - 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 = true to stop the game
    • Set winner = "LEFT" to show who won
  • 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 winner

    • winner is 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 pressed
  • key === ' ' - 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:

  1. Click "File" → "Share" in the p5.js editor
  2. Send the link to your friends
  3. Challenge them to beat your high score!

Next Steps

Ready for more? Check out:


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!