Game using OOP

Initially, I wanted to create an art piece because that is what I feel more comfortable coding. However, I also wanted to try something new and outside of my comfort level, so I chose to re-create a game that I knew. I wanted to re-create Flappy Bird, however, I found it extremely challenging to implement logic into my code. Especially when it came to making the ball not go below or above the pillars if it touches the pillars. I wasn’t able to solve this problem on time, so I decided to make the ball bounce on the racket. In addition, in the instructions, I asked a friend to keep track of the score, which also allows for a friendlier, interactive match.

I didn’t have a solid understanding of classes or OOP. After talked to Aaron an hour before class started, I realized that I created my code using functions, and not classes.

Here is my code for the project, using functions:

int gameScreen = 0;
float ballX, ballY;
float ballSize = 20;
int ballColor = color(255,255,0);
float gravity = 1;
float ballSpeedVert = 0;
float airfriction = 0.0001; //air resistance andfriction is important, ball doesn't just bounce up and down at same level, it reduces height as it bounces more.
float friction = 0.1; //surface friction
color racketColor = color(255,105,180); //platform ball bounces on
float racketWidth = 100;
float racketHeight = 10;
int racketBounceRate = 20;
float ballSpeedHorizon = 10;

//wall
int wallSpeed = 5;
int wallInterval = 1000;
float lastAddTime = 0;
int minGapHeight = 200;
int maxGapHeight = 300;
int wallWidth = 80;
color wallColors = color(0);
ArrayList<int[]> walls = new ArrayList<int[]>(); //list to keep data for gap between two walls. contains gap wall X, gap wall Y, gap wall width, gap wall height)

void setup() {
  size(500, 500);
  ballX=width/4;
  ballY=height/5;
}

void draw() {
  if (gameScreen == 0) {
    initScreen();
  } else if (gameScreen == 1) {
    gameScreen();
  } else if (gameScreen == 2) {
    gameOverScreen();
  }
}

void initScreen() {
  background(0);
  textAlign(CENTER);
 text("Don't let the ball touch the pillars. Make a friend keep track of your score.", height/2, width/2);
}
void gameScreen() {
  background(0,255,255);
  drawBall();
  applyGravity();
  keepInScreen();
  drawRacket();
  watchRacketBounce();
  applyHorizontalSpeed(); //for horizontal movement of ball
  wallAdder(); //adds new walls in every wallInterval millisecond
  wallHandler();
}
  
void gameOverScreen() {
}

public void mousePressed() { //what does public void mean
  // if we are on the initial screen when clicked, start the game
  if (gameScreen==0) {
    startGame();
  }
}

void startGame() { //necessary variable to start the game
  gameScreen=1;
}

void drawBall() {
  fill(ballColor);
  ellipse(ballX, ballY, ballSize, ballSize);
}

void applyGravity() {
  ballSpeedVert += gravity; //ballSpeedVert is -1. adding gravity to ballSpeedVert = it starts to get close to 0, becomes 0, then will start increasing again.
  ballY += ballSpeedVert; //vertical speed of ball added to Y coordinate of ball
  ballSpeedVert -= (ballSpeedVert * airfriction);
}

void makeBounceBottom(float surface) { //why is surface incorporated here? what is surface?
  ballY = surface-(ballSize/2);
  ballSpeedVert*=-1; //to bounce ball we move the ball to exact location where it had to bounce and multiply vertical speed with use of -1
  ballSpeedVert -= (ballSpeedVert * friction);
}

void makeBounceTop(float surface) { //why is surface incorporated here?
  ballY = surface+(ballSize/2);
  ballSpeedVert*=-1;
  ballSpeedVert -= (ballSpeedVert * friction);
}

void makeBounceLeft(float surface) {
  ballX = surface+(ballSize/2);
  ballSpeedHorizon*=-1;
  ballSpeedHorizon -= (ballSpeedHorizon * friction);
}
void makeBounceRight(float surface) {
  ballX = surface-(ballSize/2);
  ballSpeedHorizon*=-1;
  ballSpeedHorizon -= (ballSpeedHorizon * friction);
}

// keep ball in the screen
void keepInScreen() {
  // ball hits floor
  if (ballY+(ballSize/2) > width) {  //checking if ballY+radius less than height
    makeBounceBottom(width);
  }
  // ball hits ceiling
  if (ballY-(ballSize/2) < 0) { //checking if ballY-radius is more than 0
    makeBounceTop(0);
}
    if (ballX-(ballSize/2) < 0) {
      makeBounceLeft(0);
    }
    if (ballX+(ballSize/2) > width) {
      makeBounceRight(width);     
    }
}

void drawRacket() {
  fill(racketColor);
  rectMode(CENTER);
  rect(mouseX, mouseY, racketWidth, racketHeight);
}

void watchRacketBounce() { //makes sure racket and ball collide LOOK AT TUTORIALA GAIN
  float overhead = mouseY - pmouseY;
  if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) { //x coord. of right side of ball is greater than x coord. of left side of racket and other way around
    if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) { //distance between ball and racket is smaller than or equal to radius of ball (hence colliding)
      makeBounceBottom(mouseY); //hence this bounce method is called
      // racket moving up
      if (overhead<0) { //stores coordinates of the mouse at the previous time frame. Sometimes ball moves so fast that distance between ball and racket cant be correctly calculated between frames. so we take overhead value in between frames to detect difference. overhead value also detects negative value --stimulates racket effect.
        ballY+=overhead; //less than 0 means mouse is below in previous frame and racket is moving up
        ballSpeedVert+=overhead; //adds extra speed to ball to stimulate effect of hitting ball w racket
        if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) {  //edges of rack should give ball a more horizontal speed & middle should have no effect
          if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) { 
            ballSpeedHorizon = (ballX - mouseX)/5;
          }
        }
      }
    }
  }
}

void applyHorizontalSpeed() {
  ballX += ballSpeedHorizon;
  ballSpeedHorizon -= (ballSpeedHorizon * airfriction);
}

void wallAdder() {
  if (millis()-lastAddTime > wallInterval) { //if millis minus last added millisecond is larger than interval value, it is time to add new wall
    int randHeight = round(random(minGapHeight, maxGapHeight));
    int randY = round(random(0, height-randHeight));
    // {gapWallX, gapWallY, gapWallWidth, gapWallHeight}
    int[] randWall = {width, randY, wallWidth, randHeight}; 
    walls.add(randWall);
    lastAddTime = millis();
  }
}

void wallHandler() { //loops though each item. it removes each wall
  for (int i = 0; i < walls.size(); i++) {
    wallRemover(i);
    wallMover(i);
    wallDrawer(i);
    watchWallCollision(i);
  }
}
void wallDrawer(int index) {
  int[] wall = walls.get(index);
  // get gap wall settings 
  int gapWallX = wall[0];
  int gapWallY = wall[1];
  int gapWallWidth = wall[2];
  int gapWallHeight = wall[3];
  // draw actual walls
  rectMode(CORNER);
  fill(wallColors);
  rect(gapWallX, 0, gapWallWidth, gapWallY);
  rect(gapWallX, gapWallY+gapWallHeight, gapWallWidth, height-(gapWallY+gapWallHeight));
}

void wallMover(int index) {
  int[] wall = walls.get(index);
  wall[0] -= wallSpeed;
}
void wallRemover(int index) {
  int[] wall = walls.get(index);
  if (wall[0]+wall[2] <= 0) {
    walls.remove(index);
  }
}

void watchWallCollision(int index) { //gets called for each wall on each loop. take coordinates of wall (top and bottom) and check if coordinates of balls collifes w walls
  int[] wall = walls.get(index);
  // get gap wall settings 
  int gapWallX = wall[0];
  int gapWallY = wall[1];
  int gapWallWidth = wall[2];
  int gapWallHeight = wall[3];
  int wallTopX = gapWallX;
  int wallTopY = 0;
  int wallTopWidth = gapWallWidth;
  int wallTopHeight = gapWallY;
  int wallBottomX = gapWallX;
  int wallBottomY = gapWallY+gapWallHeight;
  int wallBottomWidth = gapWallWidth;
  int wallBottomHeight = height-(gapWallY+gapWallHeight);

  if (
    (ballX+(ballSize/2)>wallTopX) &&
    (ballX-(ballSize/2)<wallTopX+wallTopWidth) &&
    (ballY+(ballSize/2)>wallTopY) &&
    (ballY-(ballSize/2)<wallTopY+wallTopHeight)
    ) {
    // collides with upper wall
  }
  
  if (
    (ballX+(ballSize/2)>wallBottomX) &&
    (ballX-(ballSize/2)<wallBottomX+wallBottomWidth) &&
    (ballY+(ballSize/2)>wallBottomY) &&
    (ballY-(ballSize/2)<wallBottomY+wallBottomHeight)
    ) {
    // collides with lower wall
  }
}

By the middle of this week, I will convert this code to be structured with OOP and paste it below.

Leave a Reply

Your email address will not be published. Required fields are marked *