// Simple Particle System // Daniel Shiffman // A class to describe a group of Particles // An ArrayList is used to manage the list of Particles class ParticleSystem { ArrayList particles; // An arraylist for all the particles Vector3D ac = new Vector3D(0.0,0.0); Vector3D ve = new Vector3D(0.0,0.0); Vector3D lo = new Vector3D(random(width),random(height/2,height)); float maxMass = 50; float minMass = 8; ParticleSystem() { particles = new ArrayList(); // Initialize the arraylist for (int i = 0; i < maxThings; i++) { lo = new Vector3D(random(width),random(height/2,height)); particles.add(new Thing(ac,ve,lo,random(8,13))); } } void run() { numDead = 0; // Cycle through the ArrayList backwards b/c we are deleting for (int i = particles.size()-1; i >= 0; i--) { Thing t = (Thing) particles.get(i); //println(t.getMass()); if (t.getMass() < minMass){ remParticle(i); } if (t.dead()){ numDead++; } updateParticle(t); } } void updateParticle(Thing t){ //Attraction between things for (int j = 0; j < particles.size(); j++) { // For every Thing t[j] Thing tj = (Thing) particles.get(j); if(tj.dead()){ tj.stop(); } else{ if (t.getX() != nx && t.getY() != ny) { // Make sure we are not calculating gravtional pull on oneself Vector3D f = t.calcGravForce(tj); // Use the function we wrote above t.add_force(f); // Add the force to the object to affect its acceleration } } } //Add forces to contain objects within screen if (t.getY() <= height/2){ t.add_force(new Vector3D(0,1)); } else if (t.getY() < height/2 + 50 && t.getY() > height/2){ t.add_force(new Vector3D(0,-0.5)); } else if (t.getY() > height) t.add_force(new Vector3D(0,-10)); else { t.add_force(new Vector3D(random(-5,5),random(-1,1))); } 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 < psF.total(); j++){ Food fj = psF.getParticle(j); float nx = psF.getX(j); float ny = psF.getY(j); Vector3D dir = Vector3D.sub(fj.getLoc(), t.getLoc()); // Calculate direction of force float d = dir.magnitude(); // Distance between objects d = constrain(d,200.0f,100.0f); // Limiting the distance to eliminate "extreme" results for very close or very far objects dir.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) float force = (G * 0.05 * fj.getMass() * t.getMass()) / (d * d); // Calculate gravitional force magnitude dir.mult(force); // Get force vector --> magnitude * direction t.add_force(dir); // Add the force to the object to affect its acceleration if(abs(nx - t.getX()) < t.getW()/2 && abs(ny - t.getY()) < t.getH()/2){ if (t.getMass() < maxMass){ if(t.dead()){ } else{ t.addMass(foodInc); t.add_force(new Vector3D(random(-5,5),random(-1,1))); t.eating(); //println(t.getW() + " " + t.getH()); } } psF.remParticle(j); } else{ t.addMass(foodDec); } } t.go(); // Implement the rest of the object's functionality } void addParticle() { particles.add(new Thing(ac,ve,lo,random(8,13))); } 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(); } }