Ball sprite won't bounce off rectangles. Need to know how to make rectangles disappear

42 Views Asked by At

I have a ball sprite that is generated via generateSprite(); and also a platform sprite that is generated the same way. I need to make the ball bounce off the platform. This is a breakout style game so I have rectangles that are NOT sprites that the ball needs to hit, bounce off of and make them disappear. How would I do this?

To make the ball bounce off the platform this is what I tried

 ballvx = 2;
    ballvy = 2;
    ballx += ballvx;
    bally += ballvy;
   if (ballx > platformx && ballx < platformx + 200 && bally > platformy) {
    if (bally < platformy + 20) {
      ballvy *= -1;
    } else {
      ballvx *= -1;
    }
  }
    if (ballx < 0 || ballx > width) {
      ballvx *= -1;
    }
    if (bally < 0 || bally > height) {
      state=LOSE;
    }

The problem here is that the ball simply goes straight through the platform instead of bouncing off of it.

For the rectangles I have no idea how to make them both disappear and have the ball bounce off them at the same time. Here is the code for the rectangles:

 fill(r, g, b);
    rect(width*.01, height/28, w, h);
    fill(r, g, b);
    rect(width*.128, height/28, w, h);
    fill(r, g, b);
    rect(width*.25, height/28, w, h);
    fill(r, g, b);
    rect(width*.35, height/28, w, h);
    fill(r, g, b);
    rect(width*.45, height/28, w, h);
    fill(r, g, b);
    rect(width*.55, height/28, w, h);
    fill(r, g, b);
    rect(width*.65, height/28, w, h);
    fill(r, g, b);
    rect(width*.75, height/28, w, h);
    fill(r, g, b);
    rect(width*.85, height/28, w, h);
    fill(r, g, b);
    rect(width*.95, height/28, w, h);
    fill(r, g, b);
    rect(width*.01, height/4, w, h);
    fill(r, g, b);
    rect(width*.128, height/4, w, h);
    fill(r, g, b);
    rect(width*.25, height/4, w, h);
    fill(r, g, b);
    rect(width*.35, height/4, w, h);
    fill(r, g, b);
    rect(width*.45, height/4, w, h);
    fill(r, g, b);
    rect(width*.55, height/4, w, h);
    fill(r, g, b);
    rect(width*.65, height/4, w, h);
    fill(r, g, b);
    rect(width*.75, height/4, w, h);
    fill(r, g, b);
    rect(width*.85, height/4, w, h);
    fill(r, g, b);
    rect(width*.95, height/4, w, h);
1

There are 1 best solutions below

0
On

The following demo uses classes for a paddle, ball, and brick to illustrate circle/rectangle collisions. Collision detection was taken from this reference: https://www.jeffreythompson.org/collision-detection/circle-rect.php. A rectangle array with a 'show' parameter is used to display the rectangles which are hidden following a collision (brick[id].show = false;). Only rectangles still being shown are tested for future collisions. Paddle movement is controlled by the four arrow keyboard keys. The demo has lots of room for improvement but does illustrate making rectangles disappear following a collision.

color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);

Brick[] brick;
Paddle paddle;
Ball ball;

float paddleSpeed = 40;
float ballXSpeed = 1;
float ballYSpeed = 3.3;

void brickGrid(int left, int top, int w, int h, int vg, int hg) {
  int cols = 7;
  int rows = 7;
  int x,y;
  int id = 0;

  brick = new Brick[rows*cols]; // creates brick array

  for (int k = 0; k < cols; k++) {
    for (int j = 0; j < rows; j++) {
      x = left + k*(w + vg);
      y = top + j*(h + hg);
      brick[id] = new Brick(x, y, w, h, RED);
      brick[id].show = true;
      id++;
    }
  }
}

void setup() {
  size(740, 600);
  brickGrid(30, 30, 90, 30, 10, 10);
  paddle = new Paddle(20, 500, 120, 20, WHITE);
  ball = new Ball(width/2, height - 150, 20, LTGRAY);
}

void draw() {
  background(0);
  ball.display();
  paddle.display();
  for (int i = 0; i < brick.length; i++) {
    brick[i].display(i);
  }
  
  // Add the current speed to the location.
  ball.x = ball.x + ballXSpeed;
  ball.y = ball.y + ballYSpeed;

  // Check for bouncing
  if ((ball.x > width) || (ball.x < 0)) {
    ballXSpeed = ballXSpeed * -1;
  }
  if ((ball.y > height) || (ball.y < 0)) {
    ballYSpeed = ballYSpeed * -1;
  }

  boolean ballHit = circRectCollision(ball.x, ball.y, 16, paddle.x, paddle.y, paddle.w, paddle.h);  
  if (ballHit) {
   // println("ball hit by paddle.");
    ballXSpeed = random(3,5) * -1;
    ballYSpeed = random(3,5) * -1;
  }
 
  for (int i = 0; i < brick.length; i++) {
    if(brick[i].show == true){
    boolean brickHit = circRectCollision(ball.x, ball.y, 16, brick[i].x, brick[i].y, brick[i].w, brick[i].h);
    if(brickHit){
    brick[i].show = false;
    ballXSpeed = ballXSpeed * -1;
    ballYSpeed = ballYSpeed * -1;
    } 
  }
  }
}

void keyPressed() {
  if (key == CODED) {
    
    if (keyCode == RIGHT) {
      paddle.x += paddleSpeed;
      if (paddle.x > width - paddle.w) {
        paddle.x = width - paddle.w;
      }
    }
    if (keyCode == LEFT) {
      paddle.x -= paddleSpeed;
      if (paddle.x < 0) {
        paddle.x = 0;
      }
    }

    if (keyCode == UP) {
      paddle.y -= paddleSpeed;
      if (paddle.y < height - 250) {
        paddle.y = height - 250;
      }
    }

    if (keyCode == DOWN) {
      paddle.y += paddleSpeed;
      if (paddle.y > height - paddle.h) {
        paddle.y = height - paddle.h;
      }
    }
  }
}

// https://www.jeffreythompson.org/collision-detection/circle-rect.php
// CIRCLE/RECTANGLE COLLISION
boolean circRectCollision(float cx, float cy, float radius, float rx, float ry, float rw, float rh) {

  // temporary variables to set edges for testing
  float testX = cx;
  float testY = cy;

  // which edge is closest?
  if (cx < rx)         testX = rx;      // test left edge
  else if (cx > rx+rw) testX = rx+rw;   // right edge
  if (cy < ry)         testY = ry;      // top edge
  else if (cy > ry+rh) testY = ry+rh;   // bottom edge

  // get distance from closest edges
  float distX = cx-testX;
  float distY = cy-testY;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the radius, collision!
  if (distance <= radius) {
    return true;
  }
  return false;
}

Ball class(separate tab):

class Ball {
  float x, y, diam;
  color ballColor;
  
  // Constructor
  Ball(int xpos, int ypos, int diameter, color ball) {
    x = xpos;
    y = ypos;
    diam = diameter;
    ballColor = ball;
  }

  void display() {
    stroke(0);
    fill(ballColor);
    circle(x, y, diam);
  }
}

Brick class(separate tab):

class Brick {
  float x, y, w, h;
  color brickColor;
  boolean show;

  // Constructor
  Brick(int xpos, int ypos, float wt, float ht, color brick) {
    x = xpos;
    y = ypos;
    w = wt;
    h = ht;
    brickColor = brick;
  }

  void display(int id) {
    if (brick[id].show) {
      fill(brickColor);
      rect(x, y, w, h);
    }
  }
}

Paddle class(separate tab):

class Paddle {
  float x, y, w, h;
  color paddleColor;
  
  // Constructor
  Paddle(int xpos, int ypos, int wide, int ht, color paddle) {
    x = xpos;
    y = ypos;
    w = wide;
    h = ht;
    paddleColor = paddle;
  }

  void display() {
    fill(paddleColor);
    rect(x, y, w, h);
  }
}