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