html,
body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
// Ball parameters
let ballx = 300;
let bally = 300;
let xspeed = 0;
let yspeed = 0;

// Player and computer bat positions
let ai_y = 100;
let hum_y = 100;

// Stores the midpoint in the canvas
let djt = 0;
let jrb = 0;

let ai_yinc;

let score = 0;
let lives = 5;
let endless = 0;

let gameMode = "Start";
let hashtaghits = 0;
let backendboi = 0;

// variables
function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
  background("black");
  colorMode(HSB, 255);

  cancelyou();
  u2pointoh();
}

function draw() {
  backendboi += 0.2;
  if (backendboi > 255) {
    backendboi = 0;
  }
  background(backendboi, 200, 255);

  switch (gameMode) {
    case "Start":
      textAlign(CENTER);
      fill("black");
      text(
        "Hello! If you want to play normal press SPACE",
        window.innerWidth / 2,
        window.innerHeight / 2
      );

      text(
        "If you want to play endless, press the DOWN ARROW KEY",
        window.innerWidth / 2,
        window.innerHeight / 2 + 25
      );

      // Start mode state transitions
      if (keyIsPressed == true && keyCode == 32) {
        gameMode = "Playing";
        u2pointoh();
      }
      if (keyIsPressed == true && keyCode == 40) {
        gameMode = "Endless";
        endlessMode = true;
      }

      break;

    case "Playing":
      // code for playing mode here
      // draw ball
      ai_yinc = -0.11125 * (ai_y + 35 - bally);
      //background("black")
      stroke("#1F1F1F");
      fill("#1F1F1F");
      circle(ballx, bally, 25);

      // draw ai paddle
      fill("#1F1F1F");
      stroke("#1F1F1F");
      rect(window.innerWidth - 35, ai_y, 15, 70, 5);

      ai_y += ai_yinc;

      // draw human paddle
      hum_y = mouseY;
      if (mouseY >= window.innerHeight - 70) {
        hum_y = window.innerHeight - 70;
      }

      fill("#1F1F1F");
      stroke("#1F1F1F");
      rect(20, mouseY, 15, 70, 5);

      // Move the ball

      ballx += xspeed;
      bally += yspeed;

      // boundary collision detection
      if (ballx >= window.innerWidth) {
        score += 1;
        cancelyou();
        // reset game! and add a point
      }

      if (ballx <= 0) {
        cancelyou();
        lives -= 1;
        //reset game and take away a life!
      }

      fill("#1F1F1F");
      stroke("#1F1F1F");

      text("Score: " + score + " Points", window.innerWidth - 250, 25);

      text(
        "You have " + lives + " live(s) remaining",
        window.innerWidth - 250,
        50
      );

      text("To pause or quit, press ESCAPE", window.innerWidth - 250, 75);

      if (bally >= window.innerHeight) {
        yspeed = -yspeed;
      }

      if (lives <= 0) {
        gameMode = "adios";
      }

      if (bally <= 0) {
        yspeed = -yspeed;
      }

      // ball-bat collision detection
      if (
        ballx <= 47.5 &&
        ballx >= 20 &&
        bally >= mouseY &&
        bally <= mouseY + 70
      ) {
        xspeed = -xspeed;
        hashtaghits += 1;

        xspeed *= 1 + hashtaghits / 20;
        yspeed *= 1 + hashtaghits / 20;
      }

      if (keyIsPressed == true && keyCode == 27) {
        gameMode = "NormalPause";
      }
      // For next lesson:
      // paddle-ball collisions // check
      if (
        ballx >= window.innerWidth - 47.5 &&
        ballx <= window.innerWidth - 20 &&
        bally >= ai_y &&
        bally <= ai_y + 70
      ) {
        xspeed = -xspeed;
      }
      break;

    case "adios":
      textAlign(CENTER);
      fill("#1F1F1F");
      //background("#1F1F1F");
      textAlign();
      text(
        "You lose. If you want to play again, press ENTER",
        window.innerWidth / 2,
        window.innerHeight / 2
      );

      if (keyIsPressed == true && keyCode == 13) {
        gameMode = "Start";
      }

      break;

    case "Endless":
      textAlign(CENTER);

      // Endless code here

      // draw ball
      ai_yinc = -0.125 * (ai_y + 35 - bally);
      stroke("#1F1F1F");
      fill("#1F1F1F");
      circle(ballx, bally, 25);

      // draw ai paddle
      fill("#1F1F1F");
      stroke("#1F1F1F");
      rect(window.innerWidth - 35, ai_y, 15, 70, 5);

      ai_y += ai_yinc;

      // draw human paddle
      hum_y = mouseY;
      if (mouseY >= window.innerHeight - 70) {
        hum_y = window.innerHeight - 70;
      }

      fill("#1F1F1F");
      stroke("#1F1F1F");
      rect(20, mouseY, 15, 70, 5);

      // Move the ball
      ballx += xspeed;
      bally += yspeed;

      // boundary collision detection
      if (ballx >= window.innerWidth) {
        score += 1;
        cancelyou();
        // reset game! and add a point
      }

      if (ballx <= 0) {
        cancelyou();
        lives = 0;
      }

      fill("#1F1F1F");
      stroke("#1F1F1F");

      text("Score: " + score + " Points", window.innerWidth - 250, 25);

      text("To pause or quit, press ESCAPE", window.innerWidth - 250, 50);

      if (keyIsPressed == true && keyCode == 27) {
        gameMode = "EndlessPause";
      }

      if (bally >= window.innerHeight) {
        yspeed = -yspeed;
      }

      if (bally <= 0) {
        yspeed = -yspeed;
      }

      if (
        ballx <= 47.5 &&
        ballx >= 20 &&
        bally >= mouseY &&
        bally <= mouseY + 70
      ) {
        xspeed = -xspeed;
        hashtaghits += 1;
        xspeed *= 1 + hashtaghits / 20;
      }

      if (keyIsPressed == true && keyCode == 27) {
        gameMode = "NormalPause";
      }
      // For next lesson:
      // paddle-ball collisions // check
      if (
        ballx >= window.innerWidth - 47.5 &&
        ballx <= window.innerWidth - 20 &&
        bally >= ai_y &&
        bally <= ai_y + 70
      ) {
        xspeed = -xspeed;
      }

      if (keyIsPressed == true && keyCode == 27) {
        gameMode = "EndlessPause";
      }

      break;

    case "EndlessPause":
      textAlign(CENTER);
      text(
        "To return to your game, press the DOWN ARROW KEY. To quit, press Q",
        window.innerWidth / 2,
        window.innerHeight / 2
      );

      if (keyIsPressed == true && keyCode == 40) {
        gameMode = "Endless";
      }
      if (keyIsPressed == true && keyCode == 81) {
        gameMode = "adios";
      }

      break;

    case "NormalPause":
      textAlign(CENTER);
      //background("white")
      fill("#1F1F1F");
      text(
        "PAUSED. To return, press SPACE. To quit, press Q",
        window.innerWidth / 2,
        window.innerHeight / 2
      );

      if (keyIsPressed == true && keyCode == 32) {
        gameMode = "Playing";
      }
      if (keyIsPressed == true && keyCode == 81) {
        gameMode = "adios";
      }
    // do nothing

    // Start mode state transitions
  } // END OF SWITCH
  // go here when the switch sees a break;
}

function cancelyou() {
  djt = window.innerWidth / 2;
  jrb = window.innerHeight / 2;

  ballx = djt;
  bally = jrb;

  hashtaghits = 0;

  // randomly assign x and y speed
  xspeed = random([-4, -3, 3, 4]);
  yspeed = random([-4, -3, 3, 4]);
}

function u2pointoh() {
  score = 0;
  lives = 5;
  cancelyou();
}

/*MODES:
- Start (press space)
- Normal
- Pause
- Endless (no lives lost)
- Adios! (you lose)*/
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js
  2. https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js
  3. https://cdn.jsdelivr.net/gh/StriveMath/p5-teach/dist/Strive.iife.js