// Experimental Interaction Assignment 02: Mutiplicity Theme. // Requirements: Minimum two classes, minimum 20 instances (objects) of one of the classes, greyscale // Kill the Cancer cells by Jakob Fischer Jørgensen // Move the mouse around the sketch, and (try to) kill off all the cancer cells // by making the small t-killer-cell that follows you, touch the cancer cells // If the cancer cells touch eachother, their growth will invert and they will change direction // Unfortunately though, these cancer cells are tough buggers, so they'll keep coming back // Declare global object myAvatar, make a Cells array // Declare four booleans to use in spawning cells Avatar myAvatar; Cells[] ce = new Cells[0]; boolean spawn1 = true; boolean spawn2 = true; boolean spawn3 = true; boolean spawn4 = true; void setup() { // THE GREAT SETUP size(1024,576); // Sketch x and y size frameRate(60); // Sketch framerate myAvatar = new Avatar(); // Initialise Avatar by calling constructor } // SETUP OVER void draw() { // THE GREAT DRAW background(0,0,0); // Set black background cursor(CROSS); // Replace the normal cursor with a cross // Draw and update the Avatar and check for collision with cells avatarcollision(); myAvatar.update(); myAvatar.display(); // Check for cell against cell collision and check for boundary collision collision(); boundary(); // Grow, display and move each cell in the Cells array with for-loop for (int i = 0; i < ce.length; i++) { ce[i].grow(); ce[i].display(); ce[i].move(); } // Integer for number of cells to spawn each spawn cycle // Float for speed and direction of cells int numberOfCells = 30; float maxVelocity = 0.25; // Spawn cells after 1, 8 and 15 seconds, if corresponding boolean is true // Boolean neccessary to avoid program lag, set boolean to false when spawning if ( millis() > 1000 && spawn1 == true){ spawn1 = false; for (int i = 0; i < numberOfCells; i++){ Cells newCells = new Cells(random(5,width-5),random(5,height-5),0.01,0.01, color(random(50,200)),random(-maxVelocity,maxVelocity),random(-maxVelocity,maxVelocity)); ce = (Cells[]) append(ce,newCells); } } if ( millis() > 8000 && spawn2 == true){ spawn2 = false; for (int i = 0; i < numberOfCells; i++){ Cells newCells = new Cells(random(5,width-5),random(5,height-5),0.01,0.01, color(random(50,200)),random(-maxVelocity,maxVelocity),random(-maxVelocity,maxVelocity)); ce = (Cells[]) append(ce,newCells); } } if ( millis() > 15000 && spawn3 == true){ spawn3 = false; for (int i = 0; i < numberOfCells; i++){ Cells newCells = new Cells(random(5,width-5),random(5,height-5),0.01,0.01, color(random(50,200)),random(-maxVelocity,maxVelocity),random(-maxVelocity,maxVelocity)); ce = (Cells[]) append(ce,newCells); } } } // DRAW OVER // THE GREAT COLLISION CHECK // Double for-loop to check cells in the array against eachother // We check the distance between the center of the cells and get the // outer distance by subtracting the growth of both divided by two // from the center distance. If this is less than zero, we have collision // If we have collision, we invert the growth of both cells to make them shrink // If growth is a negative number, we have to invert it in order to subract void collision(){ for (int i = 0; i < ce.length; i++){ for (int j = i; j < ce.length; j++){ float centerDistance = dist (ce[i].xpos, ce[i].ypos, ce[j].xpos, ce[j].ypos); float iradius = ce[i].xgrowth/2; if (iradius < 0){ iradius *= -1; } float jradius = ce[j].xgrowth/2; if (jradius < 0){ jradius *= -1; } float outerDistance = centerDistance - iradius - jradius; if (outerDistance < 0){ ce[i].xgrowth = - ce[i].xgrowth; ce[i].ygrowth = - ce[i].ygrowth; ce[j].xgrowth = - ce[j].xgrowth; ce[j].ygrowth = - ce[j].ygrowth; ce[i].directionX *= -1; ce[i].directionY *= -1; ce[j].directionX *= -1; ce[j].directionY *= -1; } } } } // Collision check between the Avatar and the cells // If we have collision, reset cell size to 1 and make them grow again // Again, if growth is negative we have to invert it before the actual check void avatarcollision(){ for (int i = 0; i < ce.length; i++){ float centerDistance = dist (ce[i].xpos, ce[i].ypos, myAvatar.loc.x, myAvatar.loc.y); float radius = ce[i].xgrowth/2; if (radius < 0) { radius *= -1; } float outerDistance = centerDistance - radius; if (outerDistance < 5){ ce[i].xgrowth = 1; ce[i].ygrowth = 1; ce[i].xgrowth = ce[i].xgrowth +0.05; ce[i].ygrowth = ce[i].ygrowth +0.05; } } } // Boundary collision check for the cells void boundary(){ for (int i = 0; i < ce.length; i++){ // Right side of sketch if (ce[i].xpos > width-ce[i].xgrowth / 2){ if (ce[i].directionX > 0){ ce[i].directionX *= -1; } } // Left side of sketch if (ce[i].xpos < ce[i].xgrowth / 2){ if (ce[i].directionX < 0){ ce[i].directionX *= -1; } } // Bottom of sketch if (ce[i].ypos > height-ce[i].ygrowth / 2){ if (ce[i].directionY > 0){ ce[i].directionY *= -1; } } // Top of sketch if (ce[i].ypos < ce[i].ygrowth / 2){ if (ce[i].directionY < 0){ ce[i].directionY *= -1; } } } }