We are about to switch to a new forum software. Until then we have removed the registration on this forum.
//Bounce
//How to play: Draw a line using your mouse at the bottom of the page to make white ball bounce off the line and hit the green one. Make sure you adjust your line to counteract the wind.
//initiating all my variables.
//lx1 - ly2 are the values for the line the user draws in the game
//As the program is small, instead of creating a Ball Class, I just use ballX and ballY ints because there's only one ball on the canvas at one time.
//I created the 'Line' class so that I could have at least one class in the program.
float lx1, ly1, lx2, ly2, ballX, ballY, targetX, targetY, lineMin, lineMax;
int currentLevel = 1;
int ballOriginX = 250;
int ballOriginY = 10;
int radius = 20;
int bounds = 250;
float gravity = 0.8;
float ballXV = 0;
float ballYV = 0;
float bounce = -1.1;
float wind = 0;
boolean released = false;
boolean belowBounds = false;
boolean finished = false;
Line myLine = new Line(0, 0, 0, 0);
int tries = 0;
//here I setup the inital view
void setup(){
size(500, 500);
background(255);
smooth();
frameRate(40);
PFont fontA = loadFont("Calibri-Light-24.vlw");
textFont(fontA, 15);
setTarget();
setText();
}
//Once a line has been created by the user, draw() is activated using the 'released' bool.
void draw(){
if(released){
background(255);
resetLine();
drawBounds();
drawBall();
redrawTarget();
checkTargetCollision();
setText();
}
}
//There is a bool ensuring the user to create a line at the bottom half of the page.
void mousePressed(){
if(mouseY > bounds){
belowBounds = true;
background(255);
ellipse(ballOriginX, ballOriginY, radius, radius);
redrawTarget();
drawBounds();
lx1 = mouseX;
ly1 = mouseY;
resetBall();
setText();
released = false;
}
}
//this resets the game once the user has made it to the end
void keyPressed(){
if(finished){
background(255);
currentLevel = 1;
tries = 0;
setTarget();
setText();
finished = false;
}
}
//to redraw the canvas while dragging
void mouseDragged(){
if(belowBounds){
background(255);
lx2 = mouseX;
ly2 = mouseY;
resetLine();
ellipse(ballOriginX, ballOriginY, radius, radius);
drawBounds();
redrawTarget();
setText();
}
}
//the second if statement is set up to feed the line coordinates properly to checkCollision(). Becuase of how the collision detection forumula is written,
//lx1 has to be less than lx2, or it breaks the forumla and the ball passes through the line. The switchX and switchY floats are just to store two of the line values while making the switch.
void mouseReleased(){
if(belowBounds && mouseY>bounds){
released = true;
tries ++;
belowBounds = false;
if(lx1<lx2){
lineMin = lx1;
lineMax = lx2;
}else{
float switchX = lx1;
float switchY = ly1;
lx1 = lx2;
ly1 = ly2;
lx2 = switchX;
ly2 = switchY;
lineMin = lx1;
lineMax = lx2;
}
}else if(mouseY<bounds){
background(255);
resetBall();
drawBounds();
fill(255, 0, 0);
noStroke();
ellipse(targetX, targetY, radius, radius);
fill(0);
noFill();
stroke(0);
setText();
}
}
//the usual physics
void drawBall(){
ballYV += gravity;
ballXV += wind;
ballX += ballXV;
ballY += ballYV;
ellipse(ballX, ballY, radius, radius);
checkCollision();
checkBounds();
}
//This is the only complicated part of the program. to check collisions between the ball
//and the diagonal line, this forumla rotates the cooridinates and velocities of the ball.
//though it's never visible to the user, essentially this rotates the whole stage so the
//line is sitting flat, then you calculate the collision detection that way you normally
//would if the ball were hitting the floor. Then everything is rotated back at the end.
//The if statement at the beginning just makes sure the ball is on a colliding course with the line
void checkCollision(){
if(ballX > lineMin && ballX < lineMax){
float angle = atan2(ly2-ly1, lx2-lx1);
float cosa = cos(angle);
float sina = sin(angle);
float thisX1 = ballX - myLine.lineX;
float thisY1 = ballY - myLine.lineY;
float xRotated = cosa * thisX1 + sina * thisY1;
float yRotated = cosa * thisY1 - sina * thisX1;
float ballXVR = cosa * ballXV + sina * ballYV;
float ballYVR = cosa * ballYV - sina * ballXV;
if(yRotated > 0 - radius/2){
yRotated = 0 - radius/2;
ballYVR *= bounce;
}
thisX1 = cosa * xRotated - sina * yRotated;
thisY1 = cosa * yRotated + sina * xRotated;
ballXV = cosa * ballXVR - sina * ballYVR;
ballYV = cosa * ballYVR + sina * ballXVR;
ballX = myLine.lineX + thisX1;
ballY = myLine.lineY + thisY1;
}
}
//this checks to see if the ball has gone out of the window and resets the ball.
void checkBounds(){
if(ballY > height + radius){
resetBall();
}
if(ballX < 0 - radius){
resetBall();
}
if(ballX > width + radius){
resetBall();
}
}
//this puts the ball back at the beginning point
void resetBall(){
ballYV = 0;
ballXV = 0;
ballX = ballOriginX;
ballY = ballOriginY;
released = false;
ellipse(ballOriginX, ballOriginY, radius, radius);
}
//this redraws the line
void resetLine(){
myLine.lineX =lx1;
myLine.lineY =ly1;
myLine.lineX2 =lx2;
myLine.lineY2 = ly2;
myLine.display();
}
//this sets the target at the beginning of the level, and changes the wind
void setTarget(){
background(255);
resetBall();
drawBounds();
fill(0, 255, 0);
noStroke();
targetX = random(10, 490);
targetY = random(20, bounds);
ellipse(targetX, targetY, radius, radius);
fill(0);
noFill();
stroke(0);
wind = random(-0.3, 0.3);
}
void redrawTarget(){
fill(255, 0, 0);
noStroke();
ellipse(targetX, targetY, radius, radius);
noFill();
stroke(0);
}
//this checks to see if the ball hits the target ball
void checkTargetCollision(){
float currentDist = getDist(ballX, ballY, targetX, targetY);
if(currentDist < radius){
setTarget();
currentLevel ++;
if(currentLevel == 11){
background(255);
currentLevel= 0;
finished = true;
if(tries > 20){
text("In 10 levels you used " + tries + " lines.\nNow try to beat it with 20 lines or less! \nPress any key on keyboard to try again.", 200, 200);
}else if(tries <21){
text("Yeah, you beat the game using only " + tries + "! \nGood for you. \nPress any key on keyboard to try again.", 200, 200);
}
}
}
}
//typical distance formula
float getDist(float x1, float y1, float x2, float y2){
float distX = x1 - x2;
float distY = y1 - y2;
float thisDist = sqrt(distX*distX + distY*distY);
return thisDist;
}
//draws the grey line down the middle
void drawBounds(){
stroke(155);
line(0, bounds, width, bounds);
stroke(0);
}
//setting the text
void setText(){
fill(0);
float newWind = wind * 20;
int thisWind = ceil(newWind);
text("LEVEL: " + currentLevel + "\nWIND: " + thisWind, 5, 15);
text("LINES: " + tries, 430, 15);
noFill();
if(thisWind > 0){
line(10, 40, 30, 40);
line(30, 40, 25, 35);
line(30, 40, 25, 45);
}else{
line(10, 40, 30, 40);
line(10, 40, 15, 35);
line(10, 40, 15, 45);
}
}
//class to create line
class Line {
float lineX, lineY, lineX2, lineY2;
Line(float ix, float iy, float ix1, float iy1) {
lineX = ix;
lineY = iy;
lineX2 = ix1;
lineY2 = iy1;
}
void display() {
line(lineX, lineY, lineX2, lineY2);
}
}
Answers
http://forum.Processing.org/two/discussion/8045/how-to-format-code-and-text
See if the article From several variables to arrays can help you.
definitely make a Ball class please since you have several methods and vars concerning the ball.