class ThingParticleSystem { ArrayList particles; // An arraylist for all the particles Vector3D ac = new Vector3D(0,0); Vector3D ve = new Vector3D(0,0); Vector3D lo = new Vector3D(0,0); float minMass = minMass_; int count =0; int mateCounter = 0; float mgX = width-width/6; float mgY = height/2; Vector3D mgV = new Vector3D(mgX, mgY); //Constructor ThingParticleSystem() { particles = new ArrayList(); // Initialize the arraylist for (int i = 0; i < maxThings; i++) { lo = new Vector3D(random(width),random(height)); DNA dna = new DNA(); particles.add(new Thing(ac,ve,lo,random(8,13), dna)); } } ArrayList getThings(){ return particles; } void run() { noStroke(); fill(random(230,255),random(10,200),random(10,50),random(5,15)); ellipseMode(CENTER); ellipse(mgX,mgY,random(height/6-10,height/6+10),random(height/6-10,height/6+10)); //Deal with death for (int i = particles.size()-1; i >= 0; i--) { Thing t = (Thing) particles.get(i); if (t.getMass() < minMass){ particles.remove(i); } //If just mated, add force to leave mating grond if (t.get_justMated()){ //println("Just mated - adding force"); if (t.getSex() == "male"){ Vector3D dir = new Vector3D (random(-100000,0),random(100000)); // Calculate direction of force t.add_force(dir); } else{ Vector3D dir = new Vector3D (random(-10000000,0),random(-10000000,0)); // Calculate direction of force dir.mult(10); t.add_force(dir); } if (mateCounter > 300){ t.set_justMated(false); mateCounter = 0; //println("Just mated period over"); } else{ mateCounter++; } t.go(); } else{ updateParticle(t); } } } void updateParticle(Thing t){ String attractionType; //Look at other particles for (int j = 0; j < particles.size(); j++) { Thing tj = (Thing) particles.get(j); // Make sure we are not calculating gravtional pull on oneself if (t.getX() != tj.getX() && t.getY() != tj.getY()) { //If they are close enough, they will mate if (t.getSex() == "male" && tj.getSex() == "female"){ attractionType = "straight"; } else if (t.getSex() == "female" && tj.getSex() == "male"){ attractionType = "straight"; } else{ attractionType = "gay"; } if (attractionType == "straight"){ if (abs(t.getX()-tj.getX()) < dMin && abs(t.getY() - tj.getY()) < dMin) { t.set_mating(true); tj.set_mating(true); } else{ t.set_mating(false); tj.set_mating(false); } } else{ if (abs(t.getX()-tj.getX()) < dMin && abs(t.getY() - tj.getY()) < dMin) { Vector3D f = t.calcRepForce(tj); // Use the function we wrote above t.add_force(f); // Add the force to the object to affect its acceleration } } if (attractionType == "straight" && t.get_mating() == false && tj.get_mating() == false){ Vector3D f = t.calcGravForce(tj,attractionType); // Use the function we wrote above t.add_force(f); // Add the force to the object to affect its acceleration } //Add mating ground force else if (t.get_mating() && tj.get_mating()){ //If within mating grounds, reproduce if (abs(t.getX()-mgV.x) < dMin && abs(t.getY() - mgV.y) < dMin) { Thing child = reproduce(t,tj); particles.add(child); Vector3D dir = Vector3D.sub(t.getLoc(), mgV); // Calculate direction of force float d = dir.magnitude(); dir.normalize(); dir.mult(d); // Get force vector --> magnitude * direction t.add_force(dir); tj.add_force(dir); } else { Vector3D dir = Vector3D.sub(mgV, t.getLoc()); // Calculate direction of force float d = dir.magnitude(); dir.normalize(); dir.mult(d); // Get force vector --> magnitude * direction t.add_force(dir); tj.add_force(dir); } } else{ Vector3D f = t.calcRepForce(tj); // Use the function we wrote above t.add_force(f); // Add the force to the object to affect its acceleration t.set_mating(false); tj.set_mating(false); } } //Add forces to contain objects within screen if (t.getY() < 0) t.add_force(new Vector3D(0,10)); else if (t.getY() > height) t.add_force(new Vector3D(0,-10)); if (t.getX() > width) t.add_force(new Vector3D(-10,0)); else if (t.getX() < 0) t.add_force(new Vector3D(10,0)); //Things follow mouse if (mousePressed) { Vector3D m = new Vector3D(mouseX,mouseY); Vector3D diff = Vector3D.sub(m,t.getLoc()); diff.normalize(); float factor = 1.0; // Magnitude of Acceleration (not increasing it right now) diff.mult(factor); t.setAcc(diff); } } //EATING for (int j = 0; j < fPs.total(); j++){ Food fj = fPs.getParticle(j); float nx = fPs.getX(j); float ny = fPs.getY(j); Vector3D dir = Vector3D.sub(fj.getLoc(), t.getLoc()); // Calculate direction of force float d = dir.magnitude(); // Distance between objects d = constrain(d,1,500); dir.normalize(); float force = (t.getHunger() * fj.getMass()) / (d * d); dir.mult(force); if (t.get_mating() == false){ t.add_force(dir); if(abs(nx - t.getX()) <= t.getMass()/2 && abs(ny - t.getY()) <= t.getMass()/2){ t.addMass(); fPs.remParticle(j); } } } t.go(); // Implement the rest of the object's functionality } void addParticle() { DNA dna = new DNA(); Vector3D location = new Vector3D(random(width),random(height)); particles.add(new Thing(ac,ve,location,random(8,13),dna)); } void remParticle(int i){ if (particles.size() > 1){ //particles.remove(i); Thing t = (Thing) particles.get(i); t.die(); } } void delParticle(int i){ if (particles.size() > 1){ particles.remove(i); } } void delAllParticles(int i){ particles.remove(i); } void addParticle(Thing t) { particles.add(t); } // A method to test if the particle system still has particles boolean dead() { if (particles.isEmpty()) { return true; } else { return false; } } int total(){ return particles.size(); } int numMales(){ int num = 0; for (int i=0;i