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 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:
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!!