//Michael Chang //Motion //my brain works in angles not PIs float mx = 00; //Controlling Variable float mx2=0; //inverse of controlling variable cell[] subject; //list of all cells float sinwave=0; int wrapBuffer=50; //determines how far out the world is which we can't see int numCells=25; //default number of cells float ambientEnergy=18000; //the life force which all cells recieve void setup() { size(600,600); cursor(CROSS); numCells=int(random(15,45)); generateCells(numCells); // noSmooth(); smooth(); // framerate(10); background(0); } void loop() { translate(0,0,-250); // background(0); mx2=width-mx; // drawBG(); colorMode(RGB,255,255,255); updateCells(numCells); sinwave+=0.01; ambientEnergy+=(10*(width-mx2/width))+0; //regenerate ambience every turn ambientEnergy=constrain(ambientEnergy,0,1000); //--------------------------------Display marker for mx /* colorMode(RGB,255,255,255); float dif = mouseX - mx; if(abs(dif) > 1.0) { mx = mx + dif/8.0; } mx = constrain(mx, 1, width-1); noStroke(); fill(255); rect(0, height-5, width, 5); // Draw bottom positional marker fill(204, 102, 0); rect(mx-2, height-5, 4, 5);*/ //--------------------------------End display code /* if(mousePressed) { g.depthTest=false; noStroke(); fill(0,5); rect(0,0,width,height); }*/ } void mouseReleased() { setup(); } void mousePressed() { } //drawBG draws a gradient as the background void drawBG() { colorMode(HSB,width,height,height); for(int y=height;y>0;y--) { stroke(240-(mx2/1.2),(y/3)+(mx2/4),(y)-50+(width-(mx2*1.5)));//(y+80)-(mx/1.1) line(0,400-y,width,400-y); } } //generate cells generates cells up to num inside subject[] list void generateCells(int num) { subject=new cell[num]; for(int i=0;i0) { subject[i].update(); subject[i].draw(); } else { subject[i].alive=false; } } } //normalizes any angle between 0 and 360 float normalizeHeading(float ang) { while(ang >= 360)ang -= 360; while(ang <= 0)ang += 360; return ang; } //gets the absolute angle between two points relative to the first float getHeading(position p1,position p2) { float angle=atan2(p2.y-p1.y,p2.x-p1.x); angle=-1*angle*180/PI; if(p2.y>=p1.y) angle=360-(angle*-1); return angle; } //gets the absolute angle between two points relative to the first float getHeading(float x1,float y1,float x2,float y2) { float angle=atan2(y2-y1,x2-x1); angle=-1*angle*180/PI; if(y2>=y1) angle=360-(angle*-1); return angle; } //position class used to quickly define coordinates in 2d space X and Y class position { float x,y; position(){} position(float tx,float ty) { x=(tx); y=(ty); } position(position p) { x=p.x; y=p.y; } //displace() quickly gives a displacement of a position by any angle and magnitude position displace(float angle,float magnitude) { position newP=new position(x,y); newP.x+=(cos(radians(angle))*magnitude); newP.y-=(sin(radians(angle))*magnitude); return newP; } void set(float tx,float ty) { x=(tx); y=(ty); } } //cell class that defines every cellular organism class cell { int id; //id number given to each cell float health; //health value of every cell to determine its life int neighbors; //number of immediate neighbors a cell has boolean alive; //boolean to see if a cell is alive or dead boolean selected; //boolean to see if a cell is selected position location; //cell's current location position selectionCenter; //cell's visible center of position int componentAmount; //the number of components the cell has int selectionSize; //the average area taken up by a cell, expressed as a radius float angle; //current bearing of the cell float heading; //current heading of the cell float speed; //current speed of the cell float desiredSpeed; //speed at which the cell will try to obtain float accel; //cell's rate of acceleration float colSize; //size used to determine collision detection component[] subcomponents; //list of all components in a cell //constructors cell() { id=0; defaultVal(); setupComponents(); } cell(int i,position loc) { id=i; location=new position(loc); defaultVal(); setupComponents(); } cell(int i,float x,float y) { id=i; location=new position(x,y); defaultVal(); setupComponents(); } //default values of all cells are given in defaultVal() void defaultVal() { health=int(random(30)); neighbors=0; if(random(100)>20) alive=true; else alive=false; // componentAmount=int(random(15,15)); componentAmount=int(random(5,7)); angle=random(0,360); // heading=random(0,360); heading=angle+random(-80,80); speed=random(0,4); selected=false; selectionCenter=new position(location); desiredSpeed=4; accel=.01; } //setupComponents() builds list of components for the cell to use void setupComponents() { //float ang=random(0,360/componentAmount); float ang=360/componentAmount; float totalAng=0; subcomponents=new component[componentAmount]; for(int i=0;i80) if(ambientEnergy>0) { ambientEnergy-=2+(.05*neighbors); health+=2+(3*neighbors); } } //eat() is supposed to determine if a cell will eat another cell for energy instead void eat(){} //reproduce() determines when and how a cell reproduces itself. Cells make copies of themselves. void reproduce() { if(random(100)>(98+(2*mx/width))) { boolean emptyFound=false; if(health>110) { int c=0; for(int i=0;i999) health-=100; health=constrain(health,0,120); } //setSpeed() updates the speed of a cell void setSpeed() { desiredSpeed=(mx2/20)+2; if(accel<.1) accel+=.005; // float speedMod=angle; if(speed180) // { // a+=abs(a-h)/25; // angle=a; // } // a+=(h-a)/25; // angle=a; if(random(100)<(5+(5*(width-mx2)/width))) heading+=random(-20-(50*mx2/width),20+(50*mx2/width)); angle+=(heading-angle)/22; // heading+=.5; /* if(abs(heading-angle)==180) { angle+=1; } else if(abs(heading-angle)<180) { angle-=1; } else if(abs(heading-angle)>180) { angle+=1; } */ /* float a=angle; float b=heading; if(a>b) { float temp=b; b=a; a=temp; } float dirA=abs(b-a); float dirB=abs(360-b+a); if(abs(a-b)>1) { if(dirA>dirB) angle-=1; else if(dirAwidth+wrapBuffer) { location.x=0-wrapBuffer; } if(location.x<0-wrapBuffer) { location.x=width+wrapBuffer; } if(location.y>height+wrapBuffer) { location.y=0-wrapBuffer; } if(location.y<0-wrapBuffer) { location.y=height+wrapBuffer; } } //collision() will determine collisions for a cell, count its neighbors, deccelerate a cell, and displace a cell if nessecary void collision() { neighbors=0; colSize=health/10; for(int i=0;ilocation.y) // collideAngle-=(180-getHeading(location,subject[cid].subcomponents[i].location))/10; // else // collideAngle+=(180-getHeading(location,subject[cid].subcomponents[i].location))/10; // location=location.displace(getHeading(location.x,location.y,subject[cid].subcomponents[i].location.x,subject[cid].subcomponents[i].location.y),-1*(5)); distance-=1; } // if(dist(subject[cid].location.x,subject[cid].location.y,location.x,location.y)