How to restart a game using keyPressed()

edited June 2017 in Questions about Code

So I am doing a project for my programming class that is a pong game. The problem I currently have is getting the game to restart after the score limit of 10 is reached by either player. I am trying something I read from another post which is to make a reset function, redraw the background, reset variables, etc. but I'm having trouble getting it to work properly even though I feel I did the right things, I've been trying different options but nothing is fixing it. So I'm wondering if any of you see any problem with my code?

Restart function inside Ball class (line 79):

    class Ball {

  float x = width/2; // variables for ball class x,y locations, radius, and x/y speeds
  float y = height/2;
  int r = 15;
  float xspeed;
  float yspeed;
  float ballAngle = random(-PI/4, PI/4);

  Ball() { // ball class constructor
    reset(); // reset function
  }

  void move() { // function to move ball
    x = x + xspeed;
    y = y + yspeed;
  }

  void display() { // function to display ball
    fill(170);
    stroke(0);
    strokeWeight(1);
    ellipse(x, y, r*2, r*2);
  }

  void checkEdges() { // function to check the top and bottom so ball doesn't go off the screen // also score function
    if (y < 0 + r || y > height - r) {
      yspeed = yspeed *-1;
    }
    if (x + r < 0) {
      cpuScore++;
      reset();
    }
    if (x - r > width) {
      userScore++;
      reset();
    }
  }

  void reset() { // reset the ball when it reaches the end of the right or left side of the screen
    xspeed = 8 * cos(ballAngle);
    yspeed = 8 * sin(ballAngle);

    if (x < 0 - r) { 
      x = width/2;
      y = random(0+r*2, 400-r*2);
    }
    if (x > width + r) {
      x = width/2;
      y = random(0+r*2, 400-r*2);
      xspeed *= -1;
    }
  }

  void isUserPHit(Paddle p) { // detect if user paddle is hit
    if (y < p.y + p.h/2 + r && y > p.y - p.h/2 - r && x - r < p.x + p.w/2) {
      if (xspeed < 0) {
        //paddlehit.play();
        float diff = y - (p.y - p.h/2);
        float rad = radians(45);
        float angle = map(diff, 0, p.h, -rad, rad);
        xspeed = 8 * cos(angle);
        yspeed = 8 * sin(angle);
      }
    }
  }
  void isCPUPHit(Paddle p) { // detect if cpu paddle is hit
    if (y < p.y + p.h/2 + r && y > p.y - p.h/2 - r && x + r > p.x - p.w/2) {     
      if (xspeed > 0) {
        //paddlehit.play();
        float diff = y - (p.y - p.h/2);
        float angle = map(diff, 0, p.h, radians(225), radians(135));
        xspeed = 8 * cos(angle);
        yspeed = 8 * sin(angle);
      }
    }
  }

  void restart() {
    xspeed = 8 * cos(ballAngle);
    yspeed = 8 * sin(ballAngle);
    userScore = 0;
    cpuScore = 0;
    background(255); 
    // line to divide the two sides
    strokeWeight(3);
    line(width/2, 0, width/2, height);
    fill(0);
    textSize(20);
    textAlign(CENTER);
    text("User Score:", 78, 25); // text for the scores
    text("CPU Score:", 493, 25);

    text(userScore, 147, 25); // text for the numbers, currently set at “0”, but will update later
    text(cpuScore, 558, 25);


    display(); // display the ball
    move(); // move the ball
    checkEdges(); // check if the ball is reaching the top or bottom so it bounces off rather than going off the screen

    userP.display(); // display the paddles
    cpuP.display();

    userP.moveY(mouseY); // move the user’s paddle vertically with the mouse’s y position 

    isUserPHit(userP); // detect if either paddle comes in contact with the ball
    isCPUPHit(cpuP);

    cpuP.cpuAI(ball); // initiate computer AI for the computer paddle
    scorelimit(ball); // check to see if either player reaches the score limit(10)
  }
}

Main tab (a lot of code I know, sorry):

int userScore = 0; // variables for both scores in order to update it as points are scored
int cpuScore = 0;
int state = 0; // state of the game
boolean startgame = false; // boolean to make it so a button works to start the game scene
boolean help = false; // boolean to make it so a button works to display the help scene
boolean back = false; // boolean to make it so a button works to go back to main scene
boolean endofgame = false;

Ball ball; // declare Ball object


Paddle userP; // declare Paddle objects
Paddle cpuP;

void setup() {
  // screen size
  size(600, 400);
  smooth();
  frameRate(60);

  //paddlehit = new SoundFile(this, "paddlehit.wav");

  ball = new Ball(); // initialize Ball object to create a new ball


  userP = new Paddle(15, 200); // initialize Paddle object to create two new paddles
  cpuP = new Paddle(585, 200);
}

void draw() { 
  if (state == 0) {
    mainScene();
  }
  if (state == 1) {
    gameScene();
  }
  if (state == 2) {
    helpScene();
  }

  if (startgame == true) {
    state = 1;
  }

  if (help == true) {
    state = 2;
  }

  if (back == true) {
    state = 0;
  }


  if (endofgame == true) {
    ball.restart();
  }

  // E - for (Ball2 b : ball2s) b.run(); // for loop to make all balls in arraylist to have functions located inside of run().
}

void scorelimit(Ball b) { // endgame for when someone reaches the score limit
  if (userScore >= 1) {
    b.x = width/2;
    b.y = height/2;
    b.xspeed = 0;
    b.yspeed = 0;
    fill(0, 75, 255);
    textSize(24);
    textAlign(CENTER);
    text("You win!", width/2-140, height/2);
    textSize(20);
    fill(0);
    text("Press ENTER to restart", width/2+150, height/2-100);
  } else if (cpuScore >= 1) {
    b.x = width/2;
    b.y = height/2;
    b.xspeed = 0;
    b.yspeed = 0;
    fill(255, 0, 75);
    textSize(24);
    text("CPU wins..", width/2+140, height/2);
    textSize(20);
    fill(0);
    text("Press ENTER to restart", width/2-150, height/2-100);
  }
}

void mainScene() {
  background(255);
  fill(0);  // border around main scene
  strokeWeight(3); 
  line(0, 0+1, width, 0+1); 
  line(0, height-2, width, height-2);
  line(0+1, 0, 0+1, height);
  line(width-2, 0, width-2, height);
  textSize(64); // title
  textAlign(CENTER);
  strokeWeight(1); 
  text("Pong", width/2, 70); 
  // buttons for start / how to play
  fill(175);
  stroke(0);
  rectMode(CENTER);
  rect(width/2, 130, 160, 50);
  rect(width/2, 210, 200, 50);
  // text for buttons
  fill(0);
  textSize(32);
  text("Start", width/2, 140);
  text("How to play", width/2, 220);
}

void gameScene() {
  background(255); 
  // line to divide the two sides
  strokeWeight(3);
  line(width/2, 0, width/2, height);
  fill(0);
  textSize(20);
  textAlign(CENTER);
  text("User Score:", 78, 25); // text for the scores
  text("CPU Score:", 493, 25);

  text(userScore, 147, 25); // text for the numbers, currently set at “0”, but will update later
  text(cpuScore, 558, 25);

  ball.move(); // move the ball
  ball.display(); // display the ball 
  ball.checkEdges(); // check if the ball is reaching the top or bottom so it bounces off rather than going off the screen

  userP.display(); // display the paddles
  cpuP.display();

  userP.moveY(mouseY); // move the user’s paddle vertically with the mouse’s y position 

  ball.isUserPHit(userP); // detect if either paddle comes in contact with the ball
  ball.isCPUPHit(cpuP);

  cpuP.cpuAI(ball); // initiate computer AI for the computer paddle
  scorelimit(ball); // check to see if either player reaches the score limit(10)
}

void helpScene() {
  rectMode(CENTER);
  background(255); // set background to white
  fill(175); // grey fill
  strokeWeight(1);
  stroke(0);
  rect(525, 35, 80, 30); // back button
  textSize(16);
  textAlign(CENTER);
  fill(0);
  text("BACK", 525, 40);

  fill(0); // border around edges
  strokeWeight(3); 
  line(0, 0+1, width, 0+1); 
  line(0, height-2, width, height-2);
  line(0+1, 0, 0+1, height);
  line(width-2, 0, width-2, height);

  textAlign(CENTER); // title
  textSize(48); 
  text("How to Play", width/2, 50); 
  textAlign(LEFT); 
  textSize(10); 
  // information on game and how to play
  text("- In Pong, you control one paddle and you typically play against another user or a computer controlled paddle.", 15, 90);
  text("- In this version there is a computer controlled paddle that you play against.", 15, 120);
  text("- You control your own paddle on the right side with your mouse's y position, mouse your mouse up/down to move it.", 15, 150);
  text("- Once you or the computer reach the score limit(10), it will end the game.", 15, 180);
  text("- The ball bounces off at different angles based off where it hits the paddle.", 15, 210);
  text("- Higher on paddle, bounces higher off paddle, lower on paddle, bounces lower off paddle.", 15, 240);
  text("- Make sure the ball doesn't go past your paddle, and try to get it by your opponents' paddle.", 15, 270);
  text("- P.S - as of now the computer can't lose so don't try too hard.", 15, 300);
  textSize(30);
  textAlign(CENTER);
  text("* Move the mouse to move the paddle *", width/2, 350);
  disPaddle(); // display the paddle
}

void disPaddle() { // function to display the paddle
  rectMode(CENTER);
  fill(0);
  rect(x, y, w, h);

  y = constrain(mouseY, 0 + h/2, height - h/2); // constrain the paddle so it doesn't go off the screen
}

/* E - void mousePressed() {
 ball2s.add(new Ball2(mouseX, mouseY)); // add balls to arraylist when the mouse is pressed at the mouseX/Y locations
 }
 */
void mouseClicked() { 
  if (state == 0) {
    if (mouseX >= 240 && mouseX <= 360 && mouseY >= 105 && mouseY <= 155) { // if the mouse is pressed within the button "Start" while the state is 0, change startgame to true
      startgame = true;
    } else if (state == 0) { 
      if (mouseX >= 200 && mouseX <= 400 && mouseY >= 185 && mouseY <= 235) { // if the mouse is pressed within the button "How to Play" while the state is 0, change help to true
        help = true;
      }
    }
  }
  if (state == 2) {
    if (mouseX >= 485 && mouseX <= 565 && mouseY >= 20 && mouseY <= 50) { // if the mouse is clicked within the button "BACK" while the state is 2, change back to true
      back = true;
    }
  }
}

void keyPressed() {
  if (state == 1) {
    if (key == ENTER || key == RETURN) {
      endofgame = true;
    }
  }
}
Tagged:

Answers

  • edited June 2017 Answer ✓

    Your code should look like this:

    /// Define classes.
    
    /// Declare global variables and objects.
    
    void setup(){
      size(width, height);
      // Load any external data here.
      restart();
    }
    
    void restart(){
      /// Assign initial values to all global variables and new instances to objects.
    }
    
    void draw(){
      background(0);
      /// Simulate everything.
      /// Draw everything.
    }
    
    /// Other interface functions like mousePressed(), keyPressed()...
    
    /// Any other functions you need at the global level.
    

    I don't know why you have your restart() function inside your Ball class. I don't know why your restart() function is checking the positions of paddles.

  • Answer ✓

    In restart you have to set also the state and

    Set endofgame to false etc.

    And the other variables

  • edited June 2017

    Appreciate the help, I also have a problem where the if command in the mousePressed() function where it is supposed to go back to the main scene if the mouse is pressed within the "back" button in scene 2. But when I press it, it goes back to the main scene but doesn't allow me to then click the other two buttons in the main scene, so I have to restart the sketch, I was wondering if there's just something I need to put in there to give the other buttons their functionality back after back is set to true.

    (EDITED) Fixed it, just set other booleans to false in other if statements

    void mouseClicked() { // function for the buttons to switch scenes when clicking the mouse in certain areas while states are set to a certain number
      if (state == 0) {
        if (mouseX >= 240 && mouseX <= 360 && mouseY >= 105 && mouseY <= 155) { // if the mouse is pressed within the button "Start" while the state is 0, change startgame to true
          back = false;
          help = false;
          startgame = true;
        } else if (state == 0) { 
          if (mouseX >= 200 && mouseX <= 400 && mouseY >= 185 && mouseY <= 235) { // if the mouse is pressed within the button "How to Play" while the state is 0, change help to true
            back = false;
            help = true;
          }
        }
      }
      if (state == 2) {
        if (mouseX >= 485 && mouseX <= 565 && mouseY >= 20 && mouseY <= 50) { // if the mouse is clicked within the button "BACK" while the state is 2, change back to true
          back = true;
        }
      }
    }
    
  • You have state architecture in your sketch which is good

    But you are using additional variables you could also cover by the variable state: startgame, help and back namely.

    You can also name your states

    final int normalGame = 0; 
    final int stateHelp = 1; 
    //.....
    

    and then use those as values of state

    also use switch in draw:

    switch(state) { 
    
        case normalGame : 
        //.....
        break; 
    
        //.....
    
    }
    
Sign In or Register to comment.