Midterm Project – Shaikha AlKaabi

 

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";
    }
  }
}

 

Leave a Reply