# Catching Balls Game Collision Problem

**URL:** https://discourse.processing.org/t/catching-balls-game-collision-problem/7221
**Category:** Coding Questions
**Created:** [January 5, 2019, 4:25pm UTC](https://discourse.processing.org/t/catching-balls-game-collision-problem/7221 "2019-01-05T16:25:00Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![yamiyugi](https://avatars.discourse-cdn.com/v4/letter/y/df788c/32.png) [@yamiyugi](https://discourse.processing.org/u/yamiyugi)
#### Post date: [January 5, 2019, 4:25pm UTC](https://discourse.processing.org/t/catching-balls-game-collision-problem/7221/1 "2019-01-05T16:25:01Z")

</div>

Hello,

I’m trying to make a game with a stick figure with a basket that you can move with the right and left arrow key to catch balls falling from the top. So far I have the figure that moves and one ball falling and I want the ball to disappear when it hits the basket first before I add code to add new balls, but I can’t get it to work. I treated the basket as a straight line so I used [http://www.jeffreythompson.org/collision-detection/line-circle.php](http://www.jeffreythompson.org/collision-detection/line-circle.php) as reference because I really have no clue how to do it, but the ball just falls on the ground. I think there’s a boolean error but I’ve been working on this part for a day now and can’t get it right. I have 2 classes in different tabs and one main:

```auto
Figure f;
Ball ball;
int gamescreen = 0;

void setup() {
  size(800, 800);
  f = new Figure(width/2, 26, 70, height-143);
  ball = new Ball(random(0+15, width-15), 0-15, 30);
}

void draw() {
  if (gamescreen == 0) {
   startScreen(); 
  }
  else if (gamescreen == 1) {
    gamescreen();
    f.update();
    ball.ballObject();
    
  }
  else if (gamescreen == 2) {
    gameOverScreen();
  }
  
}

void keyPressed() {
  if (key == CODED) {
    if (keyCode == RIGHT)
    {
      f.right = true;
    }
    else if (keyCode == LEFT)
    { 
      f.left = true;
    }
  }
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == RIGHT)
    {
      f.right = false;
    }
    if (keyCode == LEFT)
    { 
      f.left = false;
    }
  }
}

void startScreen() {
  background(0);
  textSize(40);
  fill(255);
  textAlign(CENTER, CENTER);
  text("CLICK TO START GAME", width/2, height/2);
}

void gamescreen() {
  background(0);
}

void gameOverScreen() {
  background(0);
  textSize(40);
  fill(255);
  textAlign(CENTER, CENTER);
  text("GAME OVER", width/2, height/2);
}

void mousePressed() {
  if (gamescreen == 0) {
    startGame();
  }
}

void startGame() {
  gamescreen = 1;
  }
  
  // LINE/CIRCLE
boolean arcBall(float x, float yArc, float x2, float a, float b, float ballRadius) {

  // is either end INSIDE the circle?
  // if so, return true immediately
  boolean inside1 = pointCircle(f.x, f.yArc, a, b, ballRadius);
  boolean inside2 = pointCircle(f.x2, f.yArc, a, b , ballRadius);
  if (inside1 || inside2) return false;
  

  // get length of the line
  float distX = f.x - f.x2;
  float distY = f.yArc - f.yArc;
  float len = sqrt( (distX*distX) + (distY*distY) );

  // get dot product of the line and circle
  float dot = ( ((a-f.x)*(f.x2-f.x)) + ((b-f.yArc)*(f.yArc-f.yArc)) ) / pow(len,2);

  // find the closest point on the line
  float closestX = f.x + (dot * (f.x2-f.x));
  float closestY = f.yArc + (dot * (f.yArc-f.yArc));

  // is this point actually on the line segment?
  // if so keep going, but if not, return false
  boolean onSegment = linePoint(f.x, f.yArc, f.x2, closestX,closestY);
  if (!onSegment) return true;

  // get distance to closest point
  distX = closestX - a;
  distY = closestY - b;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  if (distance <= ballRadius) {
    return false;
  }
  return true;
}

// POINT/CIRCLE
boolean pointCircle(float px, float py, float a, float b, float ballRadius) {

  // get distance between the point and circle's center
  // using the Pythagorean Theorem
  float distX = px - a;
  float distY = py - b;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the circle's
  // radius the point is inside!
  if (distance <= ballRadius) {
    return false;
  }
  return true;
}

// LINE/POINT
boolean linePoint(float x, float yArc, float x2, float px, float py) {

  // get distance from the point to the two ends of the line
  float d1 = dist(px,py, f.x, f.yArc);
  float d2 = dist(px,py, f.x2, f.yArc);

  // get the length of the line
  float lineLen = dist(f.x, f.yArc, f.x2, f.yArc);

  // since floats are so minutely accurate, add
  // a little buffer zone that will give collision
  float buffer = 0.1; // higher # = less accurate

  // if the two distances are equal to the line's
  // length, the point is on the line!
  // note we use the buffer here to give a range,
  // rather than one #
  if (d1+d2 >= lineLen-buffer && d1+d2 <= lineLen+buffer) {
    return false;
  }
  return true;
}

class Ball {
  float a;
  float b;
  float ballSize;
  float ballRadius = ballSize/2;
  boolean falling = true;
  boolean collision = false;
  
  Ball(float tA, float tB, float tBallSize) {
    a = tA;
    b = tB;
    ballSize = tBallSize;
    ballRadius = tBallSize/2;
  }
  
  void ballObject() { 
    boolean collision = arcBall(f.x, f.yArc, f.x2, a, b, ballRadius);
    if (!collision) fill(255);
    noStroke();
    ellipse(a, b, ballRadius*2, ballRadius*2);
    if (falling) {
      b += 3;
    }
  }
}

class Figure {
 float x;
 boolean left, right;
 float headSize;
 float arcSize;
 float yArc;
 float x2 = x + arcSize;
 
 Figure(float tX, float tHeadSize, float tArcSize, float tYarc)
 {
   x = tX;
   headSize = tHeadSize;
   arcSize = tArcSize;
   yArc = tYarc;
 }

void update() {
  this.human();
  this.basket();
  this.moving();

}

void human() {
  fill(255);
  noStroke();
  ellipse(x, height-100, headSize, headSize); 
  strokeWeight(4);
  stroke(255);
  line(x, height-85, x, height-40); //Körper
  line(x, height-40, x-10, height-10); //Bein1
  line(x, height-40, x+10, height-10); //Bein2
  line(x, height-70, x-25, height-120); //Arm1
  line(x, height-70, x+25, height-120); //Arm2

}

void basket() {
  fill(255);
  arc(x, yArc, arcSize, 50, 0, PI);
}

void moving() {
 if (left) {
  x -= 4; 
 }
 if (right) {
   x += 4;
 }
}

}

```

Thanks!!

---

<div class="post-metadata">

### Author: ![Architector\_4](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/architector_4/32/813_2.png) [@Architector\_4](https://discourse.processing.org/u/Architector_4)
#### Post date: [January 5, 2019, 6:06pm UTC](https://discourse.processing.org/t/catching-balls-game-collision-problem/7221/2 "2019-01-05T18:06:16Z")

</div>

I didn’t check your previous collision code, to be honest, but I just went on and treated the basket as a rectangle and a ball as a point, and made a function that works just fine.

```auto
boolean collisionCheck(Ball ball){
  if(
    abs(x-ball.a) < arcSize/2 && //true if X position of the ball is not far enough from the basket's center
    ball.b > yArc && //true if ball is not above the basket
    ball.b < yArc+50 //true if ball is not below the basket
    ) return true;
  
  return false;
}

```

Put it inside of `Figure` class’s code, and then call inside `draw()` using something like:

```auto
if( f.collisionCheck(ball) ) gamescreen = 2;

```
