package robombs.game.view; import robombs.game.util.*; import robombs.clientserver.*; import com.threed.jpct.*; import java.awt.*; /** * A simple manager for particles. I wouldn't call it a "system" for now... */ public class ParticleManager { private Particle[] parts = null; private World level=null; private long lastCleanup=0; private int cnt=100; /** * Creates a new particle manager with a default number of particles (100). * @param level World the world */ public ParticleManager(World level) { this.level=level; init(); } /** * Creates a new particle manager for a number of particles. * @param level World the world * @param max int the number of particles */ public ParticleManager(World level, int max) { cnt=max; this.level=level; init(); } /** * Moves all particles manmaged by this manager. * @param ticks long the number of ticks passed since the last call */ public void move(long ticks) { for (int i = 0; i < cnt; i++) { Particle pp = parts[i]; if (pp!=null && pp.getVisibility()) { pp.move(ticks); } } doCleanup(); } public int getCount() { return cnt; } public Particle[] getParticles() { return parts; } /** * Adds a new particle to the manager. If the maximum number of active, visible particles have been reached, nothing happens. * This method is for adding a particle that it limited in y-direction but not in time. * @param pos SimpleVector the position * @param vel SimpleVector the velocity * @param limit float the y-limit * @param texture String the texture's name */ public void addParticle(SimpleVector pos, SimpleVector vel, float limit, String texture) { addParticle(pos, vel, limit, -1, texture, 0.8f, true, false, false, Color.WHITE); } /** * Adds a new particle to the manager. If the maximum number of active, visible particles have been reached, nothing happens. * This method is for adding a particle that it in time but not in y-direction. * @param pos SimpleVector the position * @param vel SimpleVector the velocity * @param time long the life time * @param texture String the texture's name */ public void addParticle(SimpleVector pos, SimpleVector vel, long time, String texture) { addParticle(pos, vel, 9999999999999999f, time, texture, 0.8f, true, false, false, Color.WHITE); } /** * Adds a new particle to the manager. If the maximum number of active, visible particles have been reached, nothing happens. * The particle will be limited in time and y-direction. * @param pos SimpleVector the position * @param vel SimpleVector the velocity * @param limit float the y-limit * @param time long the time-limit * @param texture String the texture's name */ public void addParticle(SimpleVector pos, SimpleVector vel, float limit, long time, String texture, float size, boolean add, boolean water, boolean remote, Color col) { Particle p = getParticle(); if (p!=null) { p.setOrigin(pos); p.setVelocity(vel); p.setLifeTime(time); p.setYLimit(limit); p.setTexture(texture); p.setWater(water); p.setAsRemote(remote); p.setColor(col); if (add) { p.setTransparencyMode(Object3D.TRANSPARENCY_MODE_ADD); } else { p.setTransparencyMode(Object3D.TRANSPARENCY_MODE_DEFAULT); } if (size!=1) { p.setScale(size); } p.reset(); } } /** * Initializes the manager */ private void init() { parts=new Particle[cnt]; lastCleanup=Ticker.getTime(); } /** * Every 30 secs, the managers checks for old particles that can be cleaned up. */ private void doCleanup() { if (Ticker.hasPassed(lastCleanup, 30000)) { int counter=0; for (int i=cnt-1; i>=0; i--) { Particle pp=parts[i]; if (pp!=null && pp.isOld()) { level.removeObject(pp); parts[i]=null; counter++; } } if (counter!=0) { NetLogger.log("Particle system cleanup performed: "+counter+" particles removed!"); } lastCleanup=Ticker.getTime(); } } /** * Gets a particle from the manager's pool. If the pool if full of particles, null will be returned. * @return Particle a fresh particle or null */ private Particle getParticle() { int np=-1; for (int i = 0; i < cnt; i++) { Particle pp = parts[i]; if (pp!=null && !pp.getVisibility()) { pp.setVisibility(Object3D.OBJ_VISIBLE); if (pp.getScale()!=0.8f) { pp.setScale(0.8f); } return pp; } if (pp==null && np==-1) { np=i; } } Particle p=null; int s=0; if (np!=-1) { s=np; } for (int i=s; i<cnt; i++) { if (parts[i]==null) { p=new Particle(); level.addObject(p); parts[i]=p; break; } } return p; } }