Code

//The objective of the game is to avoid letting the "Player" particle, 
//which follows the movement of the mouse cursor, from crashing into any of the "enemy" particles
//This game was completely inspired by the amount of versitilty in the particle systems code
//that we learned in class, so a large part of that code was copied and edited in this code

//There is a slight issue, where, there is a small chance that the player particle
//and an enemy particle spawn at or near the same point and it ends the game.
//I still haven't figured out how to properly spawn particles 
//that are not immediately created at the beginning i.e. created after certain intervals of time

//The program may throw an error (possibly a null pointer exception)
//somewhere since I'm confusing some of my variables

//My vision of the game was to have different kinds of enemy particles that spawn after
//certain amounts of time have passed that behave differently,
//for example after a short time they would break up/multiply like amoeba or something similar,
//to make the game more challenging

//Power-ups with different effects would also be randomly placed after certain amounts of time,
//for example a "bomb" power-up which would give the player a "bomb" in the upper left corner in
//which the player can then press the 'b' key to activate the bomb and remove all the current
//enemy particles

//Another idea I had was to use a camera and use the video feed, and have the program
//detect the brightest/most red pixel, which could be a laser pointer, and then instead of the 
//Player particle following the mouse, it would follow the laser pointer
//I know I can use the BrightnessTracking example but I didn't remember exactly
//how to extract color data and how to import video in the first place (also I did not have a 
//projector with a good camera)

//Other ideas of mine include different "levels" with different objectives. This specific "level" 
//was to survive for the longest amount of time, but I could have instead had it be survive for X
//amount of time. The next level might be to try to "lure" the particles into a box in order
//to catch them, be a kind of Shepherd particle and the other particles would be sheep particles
//that would run away from the player who would have to corral the sheep into a pen,
//or even made this game more like Geometry Wars (http://www.youtube.com/watch?v=y-_qlaywKBs)
//except then this wouldn't be as original

//There's also a cheat I included which on mouse press or holding either mouse button,
//the enemy particles will avoid the mouse cursor

boolean start = false;
PFont font1;
float transparency;
Particle parray[]; 
Particle player;
int nStartParticles;
int nMaxParticles;
int nCurrentParticles;
float timer = 0; 
float sec = 0; 
int tmin = 0; 
String smin; 
String tsec; 
String tmili;
boolean lose = false;
boolean wait = false;
int startcounter = 0;
int pUpCondition;
boolean hasBomb = false, hasRF = false, hasBH = false;

void setup(){
  size (700, 700);
  font1 = loadFont ("AgencyFB-Bold-48.vlw");
  transparency = 255;
  nStartParticles = 30; 
  nCurrentParticles = nStartParticles;
  nMaxParticles = 100;
  parray = new Particle[nMaxParticles];
  player = new Particle(mouseX, mouseY);
  player.setColor(color(255,0,0));
  particleCreation();

}

void draw(){
  runGame();
  lose();
}

//------------------------------
void runGame(){

  if (lose == false){
    background (0);
    stroke(255);
    for (int i = 0; i < 100; i++){
      point (random(width), random(height));
    }
    //stroke(0);
    if (start == true) {
      particleSetup();
      timer();
      if (((int)(timer/60)%3 == 0) && (nCurrentParticles < nMaxParticles)){
        nCurrentParticles+=4;
      }
      if (!(transparency < 0)){
        transparency-= 5;
        //println(transparency);
      }
    }
  }
  else {
    fill (255, 0, 0);
    rect (0, 0, width, height);
    fill (0);
    text((smin + ":" + tsec + ":" + tmili), width/2+150, 50);
    text ("Press space to reset", width/2-150, height/2);
  }

  fill (255, transparency);
  rect (0, 0, width, height);
  fill (0, transparency);
  textFont (font1, 48);
  text("Click inside this box to begin", width/2-225, height/2);
}

//--------------------------------
void lose(){
  float kx = player.getpx();
  float ky = player.getpy();
  for (int i=0; i<nStartParticles; i++){
    float ix = parray[i].getpx();
    float iy = parray[i].getpy();
    if ((kx <= ix+6) && (ky >= iy-6) && (ky <= iy+6) && (kx >= ix-6)){
      lose = true;
    }
  }
}

//----------------------------
void reset(){
  lose = false;
  timer = 0;
  tmin = 0;
  particleCreation();
}

//--------------------------------
void particleCreation(){
  for (int i=0; i<nStartParticles; i++){
    parray[i] = new Particle(random(width),random(height));
  }
  /*
  for (int i=nStartParticles; i<nCurrentParticles; i++){
   parray[i] = new Particle(50, 50);
   }
   */
}

//--------------------------------
void timer (){

  timer++;
  //println(timer);
  sec = (timer/60)%60;
  String ssec = nf (sec, 2, 2);
  //println(ssec + " " + min);
  if (ssec.equals("00.00")){
    tmin++;
  }
  smin = nf (tmin, 2, 0);
  tsec = ssec.substring(0, 2);
  tmili = ssec.substring (3, 5);
  fill (255);
  text((smin + ":" + tsec + ":" + tmili), width/2+150, 50);
  //println(smin + " " + tsec + " " + tmili);
}
//---------------------------------
void particleSetup(){

  player.render();
  player.update();
  // accumulate a force towards the cursor
  player.accumulateInverseLinearForceTowardsPos (mouseX, mouseY, .8);
  float kx = player.getpx();
  float ky = player.getpy();
  for (int i=0; i<nStartParticles; i++){
    parray[i].accumulateInverseLinearForceTowardsPos (kx,ky, .2); 
    // accumulate a repulsion force if particle j is too close for comfort
    for (int j=0; j<nStartParticles; j++){
      if (j != i){
        float jx = parray[j].getpx();
        float jy = parray[j].getpy();
        parray[i].accumulateSquareDiscomfortForce (jx, jy, -5.0);
        //player.accumulateSquareDiscomfortForce (jx, jy, -1.0); //Player discomfort
      }
    }

    //Repulsion force if mouse is pressed
    if (mousePressed == true){
      parray[i].accumulateInverseLinearForceTowardsPos (mouseX,mouseY, -1);
    }
    if (wait == true){
      startcounter++;
      if (startcounter >= 2000){
        parray[i].update();
      }
      parray[i].render();

    }
  }
}

//------------------
/*
void createPowerUp(){ //creates powerups based on the pUpCondition (random int from 0 to 2)
 switch (pUpCondition){
 case 0: 
 createBombPowerUp();
 break;
 case 1:
 createRepulsionField();
 break;
 case 2:
 createBlackHolePowerUp();
 break;
   }
 }
 
 //------------------
 void createBombPowerUp(){ //creates the bomb powerup
 int bx = random(width);
 int by = random(height);
 fill (0, 0, 255);
 ellipse (bx, by, 20, 20);
 }
 
 void createRepulsionField(){ //creates the 1-time repulsion field powerup
 int rfx = random(width);
 int rfy = random(height);
 fill (0, 255, 0);
 ellipse (rfx, rfy, 20, 20);
 }
 
 void createBlackHolePowerUp(){ //creates the black hole powerup
 int bhx = random(width);
 int bhy = random(height);
 fill (0);
 ellipse (bhx, bhy, 20, 20);
 }
 
 //------------------
 void activateRepulsionField(){ //creates a field of repulsion around the player for a limited duration
 if (hasRF == true){
 float kx = player.getpx();
 float ky = player.getpy();
 for (int i = 0; i < nCurrentParticles; i++){
 parray[i].accumulateInverseLinearForceTowardsPos (kx,ky, -1);
 }
 hasRF = false;
 }
 }
 
 void createBlackHole(int bhx, int bhy){ //creates a "Black Hole" particle that sucks all other particles towards it
 //and destroys them
 if (hasBH == true){
 accumulateInverseSquareForceTowardsPos (bhx, bhy, 1);
 hasBH = false;
 }
 }
 
 void setUpUsTheBomb(){ //destroys all enemy particles if player has a bomb powerup
 if (hasBomb == true){
 nBombs--;  
 }
 if (nBombs == 0){
 hasBomb = false;
 }
 */
//-----------------------------------------
void mousePressed(){
  if (start == false){
    start = true;
  }
  wait = true;

}

//-----------------------------------------
void keyPressed(){
  switch (key){
  case 'b':
    //setUpUsTheBomb(); //activates the function that destroys all enemy particles
    break;
  case ' ':
    reset();
    break;
  }
}
//===========================================
class Particle {
  float fx; // force accumulator
  float fy; 
  float px; // Position
  float py;
  float vx; // Velocity
  float vy;

  float M    = 1.00;  // Mass
  float drag = 0.93;
  float comfortZoneRadius = 30;
  color col = color (255, 255, 255);

  //-------------
  float getpx(){ // accessors
    return px;
  }
  float getpy(){
    return py;
  }

  //-------------
  Particle (){ 
    px = width+10;
    py = height+10;
    vx = 0;
    vy = 0;
    col = color (255, 255, 255);
  }

  Particle (float px, float py){
    this.px = px;
    this.py = py;
    vx = 0;
    vy = 0;
    col = color (255, 255, 255);
  }

  //-------------
  void render(){
    fill (col);
    ellipse(px,py,15,15);
    float orientation = atan2 (vy,vx);
    pushMatrix();
    translate(px,py);
    rotate(orientation);
    triangle(10,0, 0,-3, 0,3);
    popMatrix(); 
  }
  //--------------
  void setColor (color icol){
    col = color(icol);
  }
  //-------------
  //Even though this is not used I left it in, in the event that in the future
  //I wanted to add new particle enemy types
  void accumulateLinearDiscomfortForce (float x, float y, float C){
    float dx = x - px;
    float dy = y - py;
    float dh = sqrt(dx*dx + dy*dy);
    if (dh < comfortZoneRadius){
      dh = max(1, dh);
      float mx = dx/dh * C;
      float my = dy/dh * C;
      accumulateForce (mx,my);
    }
  }

  //-------------
  void accumulateSquareDiscomfortForce (float x, float y, float C){
    float dx = x - px;
    float dy = y - py;
    float dh = sqrt(dx*dx + dy*dy);
    if (dh < comfortZoneRadius){
      dh = max(1, dh);
      float mx = dx/(dh*dh) * C;
      float my = dy/(dh*dh) * C;
      accumulateForce (mx,my);
    }
  }

  //------------- 
  //Even though this is not used I left it in, in the event that in the future
  //I wanted to add new particle enemy types
  void accumulateInverseSquareForceTowardsPos (float x, float y, float C){
    float dx = x - px;
    float dy = y - py;
    float dh = sqrt(dx*dx + dy*dy);
    dh = max(2, dh);
    float mx = dx/(dh*dh) * C;
    float my = dy/(dh*dh) * C;
    accumulateForce (mx,my);
  }

  //-------------
  void accumulateInverseLinearForceTowardsPos (float x, float y, float C){
    float dx = x - px;
    float dy = y - py;
    float dh = sqrt(dx*dx + dy*dy);
    dh = max(1, dh);
    float mx = dx/dh * C;
    float my = dy/dh * C;
    accumulateForce (mx,my);
  }

  //-------------
  void accumulateForce (float fx, float fy){
    this.fx += fx;
    this.fy += fy;
  }

  //-------------
  void update(){
    float ax = fx/M; //acceleration = force/Mass
    float ay = fy/M;
    vx *= drag;
    vy *= drag;
    vx += ax;
    vy += ay;
    px += vx;
    py += vy;
    fx = 0;
    fy = 0;
    conform();
  }

  //-------------
  void conform(){
    if (px > width){
      px -= width;
    }
    if (px < 0){
      px += height;
    }
    if (py > height){
      py -= height;
    }
    if (py < 0){
      py += height;
    }
  }
}

1000 - Your final experiment: Upload it here!

Statement:This is the place where you can upload your personal investigation. Good luck!

hide statement