As an exercise, I decided to program my own version of the game Pop the Lock for the iPhone.  The look and functionality are essentially the same, though the controls are modified for playing on a computer.I am looking for any feedback or criticism on my program's layout or overall flow.  I also kind of hacked together the mechanism for checking collisions and rotating the paddle, so any advice on better ways to do that would also be appreciated.  And of course, general comments are more than welcome!I programmed this using Processing version 3.0.1, but I expect other versions should work just fine.I have uploaded the font files and PNG image I used to a folder on Google Drive, which can be found herestatic boolean UNLOCKED = true;static boolean LOCKED = false;boolean lvlFinished = false;boolean lvlFailed = false;boolean start = false;int lvl = 1;int nTargets = 1;color bg = color(90, 175, 255);        // Normal BG colorcolor cFail = color(255, 80, 80);      // Color on failcolor fontColor = color(220);          // Color of textcolor cTarget = color(255, 255, 70);   // Color of target ballcolor cPaddle = color(255, 0, 20);     // Color of paddle// theta for target + paddlefloat tTarget, tPaddle;// paddle velocityfloat vPaddle;PFont lblFont;PFont lvlFont;PFont textFont;PImage loop;void setup() {  size(250, 445);  rectMode(CENTER);  ellipseMode(CENTER);  imageMode(CENTER);  lblFont = loadFont(Arial-Black-56.vlw);  lvlFont = loadFont(Arial-Black-36.vlw);  textFont = loadFont(ArialMT-18.vlw);  textFont(lblFont);  loop = loadImage(loop.png);  loop.resize(loop.width/3,loop.height/3);  noStroke();  setAngles();}void draw() {  renderGame(lvlFinished, lvlFailed);  if (start) {    if (!lvlFinished && !lvlFailed) {      tPaddle += vPaddle;      if (vPaddle > 0) {        lvlFailed = (distTheta(tPaddle, tTarget) > 0.2);      } else {        lvlFailed = (distTheta(tPaddle, tTarget) < -0.2);      }    }  }  textFont(textFont);  if (lvlFinished)    text(Click anywhere to continue, width/2, 30);  else if (lvlFailed)    text(Click anywhere to try again, width/2, 50);  else if (!start)    text(Press [SPACE] to begin, width/2, 50);}void setAngles() {  float dir = random(-1, 1);  if (dir < 0) vPaddle = -PI/140;  else vPaddle = PI/140;  if (vPaddle < 0) tTarget = random(-PI, -TWO_PI/3);  else tTarget = random(-PI/3, 0);  tPaddle = -HALF_PI;}void mousePressed() {  if (lvlFinished ^ lvlFailed) {    if (lvlFinished) {      lvlFinished = false;      ++ lvl;    } else {      lvlFailed = false;    }    nTargets = lvl;    setAngles();    renderGame(lvlFinished, lvlFailed);    start = false;  }}void keyPressed() {  if (start && (nTargets > 0)) {    // We hit something!!    if (collision()) {      -- nTargets;      // when all the targets are gone, round is won      if (nTargets == 0) {        lvlFinished = true;      }      // hit the target, but there are more left      else {        // move the target and switch the velocity        if (vPaddle < 0) tTarget += random(PI/4, 5*PI/6);        if (vPaddle > 0) tTarget -= random(PI/4, 5*PI/6);        vPaddle *= -1;      }    }    // missed the target, round is lost    else {      lvlFailed = true;    }  }  // Round has not started yet, so let's go  else {    start = true;  }}void renderGame(boolean finished, boolean failed) {  if (failed)    drawLock(LOCKED, cFail);  else if (finished)    drawLock(UNLOCKED, bg);  else    drawLock(LOCKED, bg);  drawTarget();  drawPaddle();  drawText();}boolean collision() {  return (abs(distTheta(tTarget, tPaddle)) < .15);}/** * Returns the signed angular distance between angle * a and angle b. Returns a value between -PI and PI, * negative when a is left of b and positive when a * is right of b. *  * param a first angle value * param b second angle value * return float between -PI and PI. Negative if a <- b, positive if b <- a. */float distTheta(float a, float b) {  float diff = abs(a - b) % TWO_PI;  int sign = (a - b >= 0 && a - b <= PI) || (a - b <= -PI && a - b >= -TWO_PI) ? 1 : -1;  diff = (diff > PI) ? (TWO_PI - diff) : (diff);  diff *= sign;  return diff;}//**********************************************//************ DRAWING FUNCTIONS ***************//**********************************************void drawLock(boolean state, color background) {  background(background);  int dY = state ? 60 : 0;  image(loop, width/2, 160 - dY);  fill(0);  ellipse(width/2, 270, 180, 180);  fill(background);  ellipse(width/2, 270, 118, 118);}void drawTarget() {  if (tTarget > PI) tTarget -= TWO_PI;  else if (tTarget < -PI) tTarget += TWO_PI;  float x = width/2 + 75 * cos(tTarget);  float y = 270 + 75 * sin(tTarget);  fill(255, 255, 20);  ellipse(x, y, 20, 20);}void drawPaddle() {  if (tPaddle > PI) tPaddle -= TWO_PI;  else if (tPaddle < -PI) tPaddle += TWO_PI;  fill(255, 0, 20);  pushMatrix();  translate(width/2, 270);  rotate(tPaddle - HALF_PI);  rect(0, 75, 6, 20, 2);  popMatrix();}void drawText() {  textAlign(CENTER, CENTER);  fill(fontColor);  textFont(lblFont);  text(nTargets, width/2, 270);  textFont(lvlFont);  text(Level:  + lvl, width/2, 400);}
Clone of Pop the Lock iPhone Game
game;collision;processing