/** you can change these if you wanna **/ // the lower the number, the more erratic the monster movement int WIGGLE_FACTOR = 10; // maximum monster speed in x and y direction int MAX_SPEED = 2; // The lower the number, the faster balls are spawned int SPAWN_SPEED = 10; // Maximum number of balls int TOTAL_BALLS = 100; // Maximum Ball Size int MAX_BALL_SIZE = 25; // Minimum Ball Size int MIN_BALL_SIZE = 5; // Max ball speed int MAX_BALL_SPEED = 3; // Gravity float GRAVITY = .4; /** Don't mess with these though **/ // x, y, diameter, x speed, y speed float[][] numbers = new float[TOTAL_BALLS][5]; // x, y, diameter, timer, xspeed float[][] deadballs = new float[TOTAL_BALLS][5]; // center x, center y, diameter, x speed, y speed float[] monsterstats = new float[5]; //x,y,diameter float[][] monstereyes = new float[3][2]; int monsterMoveTimer; int ballSpawnTimer; void setup() { // sets the size of the window size(400, 400); // duh frameRate(30); // smooths shapes smooth(); // initialize the monster monsterstats[0] = (width/2); monsterstats[1] = (height/2); monsterstats[2] = 50; monsterstats[3] = 0; monsterstats[4] = 0; // initialize the ball array for( int i = 0; i < TOTAL_BALLS; i++ ) { for( int j = 0; j < 5; j++ ) { numbers[i][j] = 0; } } monsterMoveTimer = 0; ballSpawnTimer = 0; } void draw() { background(255, 255, 255); fill(255, 255, 255); stroke(0,0,0); // whent the monster move timer runs out, we adjust monster's speed if( monsterMoveTimer == 0 ) { setMonsterSpeed(); monsterMoveTimer = WIGGLE_FACTOR; } // set the position based on speed and last position setMonsterPosition(); // set the monster's size based on the # of balls in him setMonsterArea(); // Deal with edge cases where he wants to venture into forbidden territory dealWithMonsterOnEdge(); // draw the monster location //ellipse(monsterstats[0],monsterstats[1],monsterstats[2],monsterstats[2]); // Draw all the balls inside the monster drawTheBalls(); // Draw the balls that were clicked on and killed drawDeadBalls(); // Draw the eyeball drawTheEyeball(); // Every once in a while, spawn a ball. if( ballSpawnTimer == 0 ) { spawnABall(); ballSpawnTimer = SPAWN_SPEED; } ballSpawnTimer--; monsterMoveTimer--; } void setMonsterSpeed() { float xUpperLimit, xLowerLimit, yUpperLimit, yLowerLimit; if( monsterstats[3] >= (MAX_SPEED - 2) ) { xUpperLimit = MAX_SPEED; xLowerLimit = MAX_SPEED - 4; } else if( monsterstats[3] <= (-1 * (MAX_SPEED - 2) ) ) { xUpperLimit = ((MAX_SPEED - 4) * -1); xLowerLimit = (-1 * MAX_SPEED); } else { xUpperLimit = monsterstats[3]+2; xLowerLimit = monsterstats[3]-2; } if( monsterstats[4] >= (MAX_SPEED - 2) ) { yUpperLimit = MAX_SPEED; yLowerLimit = MAX_SPEED - 4; } else if( monsterstats[4] <= (-1 * (MAX_SPEED - 2)) ) { yUpperLimit = ((MAX_SPEED - 4) * -1); yLowerLimit = (-1 * MAX_SPEED); } else { yUpperLimit = monsterstats[4]+1; yLowerLimit = monsterstats[4]-1; } // Random movement // generate a new x speed monsterstats[3] = random(xLowerLimit,xUpperLimit); // generate a new y speed monsterstats[4] = random(yLowerLimit,yUpperLimit); return; } void setMonsterPosition() { // position = position + speed. standard position equation monsterstats[0] = monsterstats[0] + monsterstats[3]; monsterstats[1] = monsterstats[1] + monsterstats[4]; return; } void setMonsterArea() { // Calculate the monster's diameter but adding the area of all balls in it // and then calculating the monster's radius with the total area. float monsterArea = 0; for( int i = 0; i < TOTAL_BALLS; i++ ) { if( numbers[i][2] > 0 ) { // pi * r^2 monsterArea = monsterArea + ( 3.14159 * numbers[i][2] * numbers[i][2] ); } } monsterstats[2] = (sqrt( monsterArea / 3.14195 ) /2 ); return; } void dealWithMonsterOnEdge() { // If the monster is on the edge and is moving off the screen, change its direction if((( monsterstats[0] < (monsterstats[2]/2) ) && ( monsterstats[3] < 0 )) || (( monsterstats[0] > (width-(monsterstats[2]/2)) ) && ( monsterstats[3] > 0 )) ) { monsterstats[3] = ( monsterstats[3] * -1 ); } if((( monsterstats[1] < (monsterstats[2]/2) ) && ( monsterstats[4] < 0 )) || (( monsterstats[1] > (height-(monsterstats[2]/2)) ) && ( monsterstats[4] > 0 )) ) { monsterstats[4] = ( monsterstats[4] * -1 ); } return; } void drawTheBalls() { // draw monster balls // disables drawing shape outlines noStroke(); fill(0,0,0); for(int i = 0; i < TOTAL_BALLS; i++ ) { if( numbers[i][2] > 0 ) { // position = position + speed. standard position equation numbers[i][0] = numbers[i][0] + numbers[i][3]; numbers[i][1] = numbers[i][1] + numbers[i][4]; float distaceFromMonster = sqrt((numbers[i][0] - monsterstats[0]) * (numbers[i][0] - monsterstats[0]) + (numbers[i][1] - monsterstats[1]) * (numbers[i][1] - monsterstats[1])); // See if we're too far away if( distaceFromMonster > (monsterstats[2]/2) ) { // if it's further away in the x direction if( abs( numbers[i][0] - monsterstats[0] ) > abs( numbers[i][1] - monsterstats[1] ) ) { // and we're to the right if( numbers[i][0] > monsterstats[0] ) { if( numbers[i][3] > 0 ) // and moving right { // flip it's direction numbers[i][3] = numbers[i][3] * -1; } // expedite it's trip back numbers[i][0] = numbers[i][0] - (.25*MAX_SPEED); } else if( numbers[i][0] < monsterstats[0] ) // or we're to the left { if( numbers[i][3] < 0 ) // and moving left { // flip it's direction numbers[i][3] = numbers[i][3] * -1; } // expedite it's trip back numbers[i][0] = numbers[i][0] + (.25*MAX_SPEED); } } else { // if we're above if( numbers[i][1] > monsterstats[1] ) { if( numbers[i][4] > 0 ) // and moving up { // flip its direction numbers[i][4] = numbers[i][4] * -1; } // expedite its trip back numbers[i][1] = numbers[i][1] - (.25*MAX_SPEED); } else if( numbers[i][1] < monsterstats[1] ) // if we're below { if( numbers[i][4] < 0 ) // and moving down { // flip its direction numbers[i][4] = numbers[i][4] * -1; } // expedite its trip back numbers[i][1] = numbers[i][1] + (.25*MAX_SPEED); } } } ellipse(numbers[i][0],numbers[i][1],numbers[i][2],numbers[i][2]); } } return; } void spawnABall() { int j = 0; while( j < TOTAL_BALLS ) { if( numbers[j][2] == 0 ) { break; } j++; } if( j < TOTAL_BALLS ) { // generate a new diameter float newdiameter = random(MIN_BALL_SIZE,MAX_BALL_SIZE); // generate a new x speed float xspeed = random((-1*MAX_BALL_SPEED),MAX_BALL_SPEED); // generate a new y speed float yspeed = random((-1*MAX_BALL_SPEED),MAX_BALL_SPEED); // new ball is in the middle of the monster numbers[j][0] = monsterstats[0]; numbers[j][1] = monsterstats[1]; // and our randomly generated diameter numbers[j][2] = newdiameter; numbers[j][3] = xspeed; numbers[j][4] = yspeed; } return; } void drawTheEyeball() { fill(255, 255, 255); stroke(0,0,0); //left eye monstereyes[0][0] = monsterstats[0]-(monsterstats[2]/5); monstereyes[1][0] = monsterstats[1]; monstereyes[2][0] = (monsterstats[2]/3); // right eye monstereyes[0][1] = monsterstats[0]+(monsterstats[2]/5); monstereyes[1][1] = monsterstats[1]; monstereyes[2][1] = (monsterstats[2]/3); // draw the whites ellipse(monstereyes[0][0],monstereyes[1][0],monstereyes[2][0],monstereyes[2][0]); ellipse(monstereyes[0][1],monstereyes[1][1],monstereyes[2][1],monstereyes[2][1]); fill(0,0,0); noStroke(); float mouseXlocation = mouseX; float mouseYlocation = mouseY; float XdistanceFromLeft = monstereyes[0][0] - mouseXlocation; float YdistanceFromLeft = monstereyes[1][0] - mouseYlocation; float XdistanceFromRight = monstereyes[0][1] - mouseXlocation; float YdistanceFromRight = monstereyes[1][1] - mouseYlocation; float distanceFromLeftEye = sqrt((XdistanceFromLeft*XdistanceFromLeft) + (YdistanceFromLeft*YdistanceFromLeft)); float distanceFromRightEye = sqrt((XdistanceFromRight*XdistanceFromRight) + (YdistanceFromRight*YdistanceFromRight)); float pupilLeftX, pupilLeftY; float pupilRightX, pupilRightY; if( distanceFromLeftEye < (monstereyes[2][0]/3) ) { pupilLeftX = mouseXlocation; pupilLeftY = mouseYlocation; } else { pupilLeftX = monstereyes[0][0] - (XdistanceFromLeft * (monstereyes[2][0]/3))/distanceFromLeftEye; pupilLeftY = monstereyes[1][0] - (YdistanceFromLeft * (monstereyes[2][0]/3))/distanceFromLeftEye; } if( distanceFromRightEye < (monstereyes[2][0]/3) ) { pupilRightX = mouseXlocation; pupilRightY = mouseYlocation; } else { pupilRightX = monstereyes[0][1] - (XdistanceFromRight * (monstereyes[2][0]/3))/distanceFromRightEye; pupilRightY = monstereyes[1][1] - (YdistanceFromRight * (monstereyes[2][0]/3))/distanceFromRightEye; } // draw the pupils ellipse(pupilLeftX,pupilLeftY,(monstereyes[2][0]/3),(monstereyes[2][0]/3)); ellipse(pupilRightX,pupilRightY,(monstereyes[2][0]/3),(monstereyes[2][0]/3)); } void mousePressed() { print(mouseX + " " + mouseY + "\n"); float distanceFromMouse; float mouseXLocation = mouseX; float mouseYLocation = mouseY; for(int i = 0; i < TOTAL_BALLS; i++ ) { if( numbers[i][2] > 0 ) { distanceFromMouse = sqrt( ((numbers[i][0]-mouseXLocation) * (numbers[i][0] - mouseXLocation)) + ((numbers[i][1]-mouseYLocation) * (numbers[i][1] - mouseYLocation)) ); if( distanceFromMouse < numbers[i][2] ) { for( int j = 0; j < TOTAL_BALLS; j++ ) { if( deadballs[j][2] == 0 ) { // Move the ball to the dead balls array deadballs[j][0] = numbers[i][0]; deadballs[j][1] = numbers[i][1]; deadballs[j][2] = numbers[i][2]; deadballs[j][3] = 0; deadballs[j][4] = random((-1*MAX_BALL_SPEED),MAX_BALL_SPEED); // remove the ball from the good ball array numbers[i][2] = 0; break; } } break; } } } return; } void drawDeadBalls() { fill(0,0,0); noStroke(); float yposition = 0; float xposition = 0; for(int i = 0; i < TOTAL_BALLS; i++ ) { if( deadballs[i][2] > 0 ) { // standard position equation // x = x0 + v0 t + 1/2 a t^2 yposition = deadballs[i][1] + .5 * GRAVITY * deadballs[i][3] * deadballs[i][3]; xposition = deadballs[i][0] + deadballs[i][4] * deadballs[i][3]; // fell off the screen, delete the ball. if((yposition - (deadballs[i][2])) > height) { deadballs[i][2] = 0; } else // else draw it { // draw and increment the counter. ellipse(xposition,yposition,deadballs[i][2],deadballs[i][2]); deadballs[i][3] = deadballs[i][3]+1; } } } return; }