How can I implement loops and arrays into this code?

edited August 2015 in Questions about Code
//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

Sign In or Register to comment.