We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › bounce off rectangle
Page Index Toggle Pages: 1
bounce off rectangle (Read 1243 times)
bounce off rectangle
Mar 16th, 2010, 11:16pm
 
I'm trying to make a ball bounce off a rectangle in a game I'm creating. The rectangle is like an obstacle. I posted a topic earlier today in which I kind of explained the game: it's like billiards or pool but with obstacles. I don't know what I'm doing wrong that's making the ball go crazy. I'll post my code, and you can just jump down to void modeTwo because I think that's where the problem is. I'm posting the whole thing because the problem might be elsewhere:

float rectx = 100; //obstacle
float recty = 200;
float rectWidth = 190;
float rectHeight = 10;

int directionX = 1;
int directionY = -1;

int mode = 0;

float ballx = 320; //ball xaxis
float bally = 380;
float cuex = ballx; //cuestick xaxis
float cuey = bally;
float balld = 15; //ball radius
float ballangle = 0;
float ballspeedx = 8.0;
float ballspeedy = 8.0;
float angle;
boolean rotation = true;

float pocketx = 550; //hole
float pockety = 100;
float pocketr = 50;

int b1x = 210;   // Button 1 x-coordinate
int b1y = 215;  // Button 1 y-coordinate
int b1w = 220;  // Button 1 width
int b1h = 50;   // Button 1 height

PFont f;
PFont f48;

void setup() {
 size(640, 480);
 smooth();
 ellipseMode(RADIUS);
 f = loadFont("ZebrawoodStd-Fill-28.vlw");
 f48 = loadFont("ZebrawoodStd-Fill-48.vlw");
 textFont(f);
 textAlign(CENTER);
}

void draw() {
 background(204);
 strokeCap(ROUND);
 strokeWeight(2);
 fill(255);
 
 if (mode == 0) {
   modeZero();
 }
 else if (mode == 1) {
   modeOne();
 }
 else if (mode == 2) {
   modeTwo();
 }
 else if (mode == 3) {
   modeThree();
 }
 else if (mode == 4) {
   modeFour();
 }
 else if (mode == 5) {
   modeFive();
 }
}

void mousePressed() {
 if (mode == 1) {
   rotation = false;
 }
 if (mode == 3) {
   if (overButton(b1x, b1y, b1w, b1h) == true) {
   mode = 4;
   }
 }
}

void keyPressed() {
   if (mode == 0) {
   mode = 1;
 }
 if (mode == 1 && rotation == false) {
   mode = 2;
   ballangle = angle - PI;
 }
}

void modeZero() {
 textFont(f48);
 fill(0);
 text("Poolio", 320, 70);
 textFont(f);
 text("1. move mouse left and right", 320, 140);
 text("to rotate cuestick", 320, 170);
 text("2. click mouse to freeze aim", 320, 230);
 text("3. press the space bar to shoot", 320, 290);
 fill(#A71111);
 text("press any key to start playing!", 320, 350);
}

void modeOne() {
 pushMatrix();
 translate(cuex, cuey);
 rotate(angle);
 line(balld/2 + 13, 0, balld/2 + 200, 0);//cuestick
 popMatrix();
 
 fill(0);
 ellipse(pocketx, pockety, pocketr, pocketr); //pocket
 
 fill(255);
 ellipse(ballx, bally, balld, balld); //cueball
 if (rotation) {
   angle = map(mouseX, 20, 620, 0, PI*3);
 }
 
 fill(0);
 text("Level 1", 70, 465);
 
 rect(rectx, recty, rectWidth, rectHeight);
}

void modeTwo() {
 fill(0);
 ellipse(pocketx, pockety, pocketr, pocketr); //pocket
 // Draw the ball
 pushMatrix();
 fill(255);
 translate(ballx, bally);
 rotate(ballangle);
 ellipse(0, 0, balld, balld); //ball
 popMatrix();
 // Update position and bounce off walls
 ballx += cos(ballangle) * ballspeedx;
 bally += sin(ballangle) * ballspeedy;
 checkWalls();
 obstacle();
 
 if (circleIntersect(ballx, bally, balld, pocketx, pockety, pocketr) == true) {
  mode = 3;
 }
 
 ballx += ballspeedx * directionX;
 if (ballx > rectx-balld) {
   directionX = -directionX;
 }
 bally += ballspeedy * directionY;
 if (bally > recty-balld) {
   directionY = -directionY;
 }
 
 rect(rectx, recty, rectWidth, rectHeight);
 
 ballspeedx *= 0.99;
 ballspeedy *= 0.99;
 
 fill(0);
 text("Level 1", 70, 465);
}

void obstacle() {
 ballx += ballspeedx * directionX;
 if (ballx > rectx-balld) {
   directionX = -directionX;
 }
 bally += ballspeedy * directionY;
 if (bally > recty-balld) {
   directionY = -directionY;
 }
}
   
void checkWalls() {
 if (ballx > width-balld) {
   ballx = width-balld;
   ballspeedx *= -1;
 } else if (ballx < balld) {
   ballx = balld;
   ballspeedx *= -1;
 } else if (bally > height-balld) {
   bally = height-balld;
   ballspeedy *= -1;
 } else if (bally < balld) {
   bally = balld;
   ballspeedy *= -1;
 }
}

void modeThree() {
 fill(0);
 ellipse(pocketx, pockety, pocketr, pocketr);

 pushMatrix();
 translate(ballx, bally);
 rotate(ballangle);
 stroke(0, 0);
 fill(0, 0);
 ellipse(0, 0, balld, balld);
 popMatrix();
 
 if (overButton(b1x, b1y, b1w, b1h) == true) {
   stroke(0);
   fill(255);
 }
 else {
   stroke(0);
   fill(153);
 }
 rect(b1x, b1y, b1w, b1h);
 textAlign(CENTER);
 fill(0);
 text("Go to level 2", b1x + b1w/2, b1y + 32);
 
 fill(0);
 text("Level 1", 70, 465);
 stroke(0, 0);
}

void modeFour() {
 stroke(0);
 fill(0);
 ellipse(pocketx, pockety, pocketr, pocketr);
  // Draw the ball
 
 pushMatrix();
 translate(cuex, cuey);
 rotate(angle);
 line(balld/2 + 13, 0, balld/2 + 200, 0);
 popMatrix();
 
 fill(255);
 ellipse(ballx, bally, balld, balld);
 if (rotation) {
   angle = map(mouseX, 20, 620, 0, PI*3);
 }
}

void modeFive() {
}

boolean overButton(int x, int y, int w, int h) {
 if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) {
   return true;
 }
 else {
   return false;
 }
}

boolean circleIntersect(float bx, float by, float br, float px, float py, float pr) {
 if (dist(bx, by, px, py) < br-10 + pr-10) {
   return true;
 } else {
   return false;
 }
}

boolean rectCircle(float bx, float by, float br, float rx, float ry, float rw, float rh) {
 float circleDistanceX = abs(bx - rx - rw/2);
 float circleDistanceY = abs(by - ry - rh/2);
 
 if (circleDistanceX > (rw/2 + br)) {return false; }
 if (circleDistanceY > (rh/2 + br)) { return false; }
 if (circleDistanceX <= rw/2) { return true; }
 if (circleDistanceY <= rh/2) { return true; }

 float cornerDistance = pow(circleDistanceX - rw/2, 2) + pow(circleDistanceY - rh/2, 2);
 return cornerDistance <= pow(br, 2);
}
Re: bounce off rectangle
Reply #1 - Mar 17th, 2010, 12:41am
 
I haven't time to look more but indeed the behavior of the ball is sometime strange, eg. before bouncing on top wall.
The obstacle check isn't finished, I suppose...

Suggestion: perhaps get rid of either ballspeedx's sign or directionX. Both can change their sign, moving the ball in another direction, so perhaps there is a conflict between them.
Page Index Toggle Pages: 1