Scoring System - Tracking Points
Let's add scoring so players can compete properly! We'll track points and display them on screen.
Step 1: Add Score Variables
Add these variables at the top of your code:
// Ball
let ballX = 400;
let ballY = 200;
let ballSize = 15;
let ballSpeedX = 5;
let ballSpeedY = 3;
// Scores
let leftScore = 0;
let rightScore = 0;
Breaking it down
leftScore = 0- Points for left player (starts at 0)rightScore = 0- Points for right player (starts at 0)- These will increment when a player scores
Step 2: Award Points When Ball Goes Off Screen
Update the ball reset code to award points:
// Reset ball if it goes off left or right edge
if (ballX < 0 || ballX > width) {
// Award points
if (ballX < 0) {
rightScore++; // Right player scores!
} else {
leftScore++; // Left player scores!
}
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
}
Breaking it down
-
if (ballX < 0)- Ball went off left edge- Left player missed
- Right player gets a point
rightScore++increases right score by 1
-
else- Ball went off right edge (ballX > width)- Right player missed
- Left player gets a point
leftScore++increases left score by 1
Test it: Let the ball go off screen - the score variables change (but you can't see them yet!)
Step 3: Display Scores on Screen
Add this code after drawing the center line but before the paddle movement:
// 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(255);
textSize(48);
textAlign(CENTER);
text(leftScore, width / 4, 60);
text(rightScore, 3 * width / 4, 60);
// Left paddle movement
if (keyIsDown(87)) {
Breaking it down
fill(255)- White text colortextSize(48)- Large text (48 pixels high)textAlign(CENTER)- Center text on the X coordinatetext(leftScore, width / 4, 60)- Shows left player's score
width / 4= 800 / 4 = 200 (1/4 from left edge)60pixels from top
text(rightScore, 3 * width / 4, 60)- Shows right player's score
3 * width / 4= 600 (3/4 from left edge, or 1/4 from right)- Symmetrically positioned with left score
Test it: You should see "0 0" at the top! Let the ball go off screen and watch the scores increase!
Step 4: Make Scores More Visible
Let's add a subtle effect to make scores stand out:
// Display scores
fill(150);
textSize(96);
textAlign(CENTER);
text(leftScore, width / 4, 120);
text(rightScore, 3 * width / 4, 120);
Breaking it down
- First layer: Large gray (150) text behind
textSize(96)- Twice as largetext(leftScore, width / 4, 120)- Positioned lower- Creates a shadow/background effect
Complete Scoring Code
Here's the full game with scoring:
// 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;
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 with shadow effect
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);
// 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++;
}
ballX = width / 2;
ballY = height / 2;
ballSpeedX = random() > 0.5 ? 5 : -5;
ballSpeedY = random(-3, 3);
}
// Draw left paddle
fill(255);
rect(20, leftPaddleY, paddleWidth, paddleHeight);
// Draw right paddle
rect(770, rightPaddleY, paddleWidth, paddleHeight);
// Draw ball
circle(ballX, ballY, ballSize);
}
Understanding Score Display
Text Positioning
0 ────────── 800 (width)
↓
200 ← left score (width/4)
↓
400 ← center line (width/2)
↓
600 ← right score (3*width/4)
Why This Layout?
- Scores are symmetrical
- Easy to glance at while playing
- Clear which score belongs to which player
- Classic Pong aesthetic
What You Learned
In this step, you:
- ✅ Added score tracking for both players
- ✅ Awarded points when ball goes off screen
- ✅ Displayed scores prominently at the top
- ✅ Added visual depth with layered text
- ✅ Created a complete scoring system
What's Next?
We have a fully playable Pong game with scoring! Next, we'll add game over conditions, a win screen, and the ability to restart the game.
Coming up: Win conditions and game over screen!
Next Step: Game Over & Complete Code