When I first started working on my midterm project, I really wanted to make a game about planting flowers. It sounded fun and I thought it would be something different. But as I kept working on it and thinking more about how it would work, it started to feel less like a game and more like a simulator for planting. It wasn’t as fun as I had hoped it would be, and that was really important to me. So, I decided to change it.
I switched my idea to “Back and Forth.” At first, I thought about making a volleyball game. It seemed like a good idea because it was about moving back and forth, which is what I wanted. But the more I thought about it, the more I realized that making it feel realistic and fun at the same time was going to be really hard. So, I started looking for something similar but a bit simpler, and that’s when I landed on a ping-pong game. Ping-pong still had that back and forth action which I liked, but it felt more doable and still really fun. That’s how I ended up with the idea for my project.
Challenges:
The tricky part was figuring out how to make the ball start from the center of the screen. But then I remembered the width /2 and height/2 that we used to center things and I used that to position the ball at the center whenever it went out of the screen:
reset() { // Reset the ball’s position and speed this.x = width / 2; this.y = height / 2; this.xSpeed = random([-5, 5]); // Increased speed this.ySpeed = random([-5, 5]); // Increased speed }
Overall, I’m quite happy with my game.
let leftPaddle; let rightPaddle; let ball; let leftScore = 0; let rightScore = 0; let gameState = "start"; let tableColor; let startScreenImage; let gameOverSound; let paddleHitSound; function preload() { startScreenImage = loadImage('background-image.jpg'); gameOverSound = loadSound('game over.mp3'); paddleHitSound = loadSound('paddle.mp3'); } function setup() { createCanvas(800, 400); textAlign(CENTER, CENTER); textSize(40); leftPaddle = new Paddle(true); rightPaddle = new Paddle(false); ball = new Ball(); tableColor = color(138, 43, 226); } function draw() { background(tableColor); drawNet(); if (gameState === "start") { showStartScreen(); } else if (gameState === "play") { leftPaddle.show(); rightPaddle.show(); ball.show(); leftPaddle.update(); rightPaddle.update(); ball.update(); ball.checkPaddleCollision(leftPaddle); ball.checkPaddleCollision(rightPaddle); ball.checkScore(); drawScore(); } else if (gameState === "gameover") { showGameOverScreen(); } } function keyPressed() { // Start the game when ENTER is pressed if (keyCode === ENTER && gameState === "start") { gameState = "play"; } // Reset the game when ENTER is pressed after game over else if (keyCode === ENTER && gameState === "gameover") { gameState = "start"; leftScore = 0; rightScore = 0; ball.reset(); } // Control the right paddle with arrow keys if (keyCode === UP_ARROW) { rightPaddle.ySpeed = -5; } else if (keyCode === DOWN_ARROW) { rightPaddle.ySpeed = 5; } // Control the left paddle with 'W' and 'S' keys if (key === 'w' || key === 'W') { leftPaddle.ySpeed = -5; } else if (key === 's' || key === 'S') { leftPaddle.ySpeed = 5; } } function keyReleased() { // Stop the left paddle when 'W' or 'S' key is released if (key === 'w' || key === 'W' || key === 's' || key === 'S') { leftPaddle.ySpeed = 0; } // Stop the right paddle when arrow keys are released if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) { rightPaddle.ySpeed = 0; } } function keyReleased() { // Stop the left paddle when 'W' or 'S' key is released if (key === 'W' || key === 'S') { leftPaddle.ySpeed = 0; } // Stop the right paddle when arrow keys are released if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) { rightPaddle.ySpeed = 0; } } function drawNet() { // Draw the net in the middle of the table stroke(255); strokeWeight(2); for (let i = 0; i < height; i += 20) { line(width / 2, i, width / 2, i + 10); } } function drawScore() { // Display the scores below the player names with text indicating it is the score fill(255); textSize(20); textFont("Courier New"); textAlign(CENTER, CENTER); // Player 1 score stroke(0) text("Player 1", width / 4, 90); text("Score: " + leftScore, width / 4, 110); // Player 2 score stroke(0) text("Player 2", (3 * width) / 4, 90); text("Score: " + rightScore, (3 * width) / 4, 110); } function showStartScreen() { // Display the start screen with instructions image(startScreenImage, 0, 0, width, height); fill(138, 43, 226); stroke(255); // Outline color strokeWeight(2); // Outline weight textFont("Courier New"); textStyle(BOLD); textSize(40); text("Back and Forth", width / 2, height / 2 - 100); textSize(20); text("Press ENTER to Start", width / 2, height / 2 + 50); textSize(15); text("Press 'W' to move the left paddle up and 'S' to move it down", width / 2, height / 2 + 125); textSize(15); text("Press Upward-Arrow to move the right paddle up and Down-Arrow to move it down", width / 2, height / 2 + 150); } function showGameOverScreen() { // Display the game over screen with the winning player's name let winner = leftScore > rightScore ? "Player 1" : "Player 2"; fill(255); stroke(0); // Outline color strokeWeight(5); // Outline weight textFont("Courier New"); textSize(40); text(winner + " Wins!", width / 2, height / 2 - 40); textSize(20); text("Press ENTER to Play Again", width / 2, height / 2 + 40); } class Paddle { constructor(isLeft) { this.w = 10; this.h = 80; this.y = height / 2 - this.h / 2; if (isLeft) { this.x = 20; } else { this.x = width - 30; } this.ySpeed = 0; } show() { // Draw the paddle fill(255); rect(this.x, this.y, this.w, this.h); } update() { // Update the paddle's position based on key inputs this.y += this.ySpeed; this.y = constrain(this.y, 0, height - this.h); } } class Ball { constructor() { this.reset(); } reset() { // Reset the ball's position and speed this.x = width / 2; this.y = height / 2; this.xSpeed = random([-5, 5]); // Increased speed this.ySpeed = random([-5, 5]); // Increased speed } show() { // Draw the ball fill(255); ellipse(this.x, this.y, 10, 10); } update() { // Update the ball's position this.x += this.xSpeed; this.y += this.ySpeed; if (this.y < 0 || this.y > height) { this.ySpeed *= -1; } } checkPaddleCollision(paddle) { // Check for collision with paddles and change direction if (this.x - 5 < paddle.x + paddle.w && this.x + 5 > paddle.x && this.y - 5 < paddle.y + paddle.h && this.y + 5 > paddle.y) { this.xSpeed *= -1; paddleHitSound.play(); } } checkScore() { // Check for scoring and end game condition if (this.x < 0) { rightScore++; this.reset(); gameOverSound.play(); } else if (this.x > width) { leftScore++; this.reset(); gameOverSound.play(); } if (leftScore >= 5 || rightScore >= 5) { gameState = "gameover"; } } }