Advertisement

[java] Particle System-Alpha blending

Started by August 11, 2000 03:21 PM
-1 comments, last by Wrathnut 24 years, 4 months ago
Here's a simple particle system for you Alexr, I'm sorry if it's a little sloppy, but I pretty much threw it together. I would of included some stuff on alpha blending but I'm still alittle stuck in that area.. Anyway this applet will simulate sparks, you can view a 3d and a 2d particle system, but there really isn't much different in the way they look. Although If I'd factored in gravity for the 3d there would have been a major visible difference. If someone has any ideas for doing alpha blending in jdk 1.1 I'd like to make the sparks glow. here's a link to the applet: http://www.grandnet.com/users/wrathnut/particleDemo I'll warn you the source is a little long but I commented the hell out of everything. You can toggle the 3d-2d back and forth with the parameter 3d. For value 1 it's on for zero it's in 2d mode. Anyway here's the source:
        
import java.awt.*;
import java.applet.*;

public class particleDemo extends java.applet.Applet implements Runnable{
	
	//Declare global variables

	Thread runner;
	Image offscreenImg;
	Graphics offscreenG;
	int xborder, yborder, delay, oldX[], oldY[], oldZ[], maxParticles
		, is3d, originX, originY, dist;
	particle p[];
	float Sinus[], Cosinus[];
		
	public void init(){
		
		int j;
		
		//Find out whether the particles are 2d, or 3d
		is3d = Integer.parseInt(getParameter("3d"));
		
		// Create Image & Graphic type variables for buffering animation.

		offscreenImg = createImage(size().width, size().height);
		offscreenG = offscreenImg.getGraphics();
		
		//Set border variables

		xborder = size().width;
		yborder = size().height;
		originX = 0;
		originY = 0;
		dist = 150;
		
		//Set delay, and maxParticles, other variables
		delay = Integer.parseInt(getParameter("delay"));
		maxParticles = Integer.parseInt(getParameter("maxParticles"));
		oldX = new int[maxParticles];
		oldY = new int[maxParticles];
		//If the particles are to be in 3d the initialize the oldZ array

		if(is3d == 1){
			oldZ = new int[maxParticles];
		}
		p = new particle[maxParticles];
		
		//Make some dead particles to initialize the array

		for(j =0; j < maxParticles; j++){
			if(is3d == 0){
				//If the particle is 2d, make a 2d particle array
				p[j] = new particle( 0, 0, 0, 0, 0);
			}
			else{
				//If the particle is 3d, make a 3d particle array
				p[j] = new particle(0,0,0,0,0,0,0);
			}
		}
						
		//Get ready for some trig

		float pi, deg2rad;
		pi = (float)3.1459265;
		deg2rad = pi/180;
		Sinus = new float[361];
		Cosinus = new float[361];
		
		//Precalculate Tables to speed up process.

		for(j=0; j< 361; j++){			Sinus[j]= (float)Math.sin(j * deg2rad);
			Cosinus[j] = (float)Math.cos(j * deg2rad);

		}
						
	}
	
	public void start (){
		if (runner == null){
			runner = new Thread(this);
			runner.start();
		}		
	}
	
	public void stop(){
		if (runner != null){
			runner.stop();
			runner = null;			
		}
		System.exit(0);
	}
	
	public void run(){
		while (true){
			repaint();
			age();
			movement();
			try {Thread.sleep(delay);}
			catch (InterruptedException e) {}
		}
				
	}
	
	public void paint(Graphics g){
		int denom, x2d, y2d, x2dOld, y2dOld;
		//Paint background

		offscreenG.setColor(Color.black);
		offscreenG.fillRect(0,0,xborder,yborder);
		//Draw Particles on the buffer

		offscreenG.setColor(Color.red);
		for(int j=0; j < maxParticles; j++){
			//Make sure particles are alive before drawing

			if(p[j].life > 0){
				//If the particles are 2d, draw as such
				if(is3d == 0){	
					offscreenG.drawLine( p[j].x, p[j].y, oldX[j], oldY[j]);
				}
				else{
					//Else draw as 3d

					// Used to avoid division by zero

					denom = p[j].z + dist;
					if(denom == 0){denom = 1;}
					// Transform 3d Coordinates into 2d

					x2d = (p[j].x * dist)/denom + originX;
					y2d = (p[j].y * dist)/denom + originY;
					
					// Used to avoid division by zero					denom = oldZ[j] + dist;

					if(denom == 0){denom = 1;}
					// Transform 3d Coordinates into 2d

					x2dOld = (oldX[j] * dist)/denom + originX;
					y2dOld = (oldY[j] * dist)/denom + originY;
					
					offscreenG.drawLine( x2d, y2d, x2dOld, y2dOld);
					
				}
			}
			
		}
		
		// Actually paint image onscreen.

		g.drawImage(offscreenImg, 0, 0, this);
		
	}
	
	// Override the update in the Graphics class to reduce flicker even more.

	public void update(Graphics g){paint(g);}
			
	public boolean mouseDown(Event evt, int x, int y){
		//Create a new set of particle values when the applet is clicked

		for(int j =0; j < maxParticles; j++){
			if(is3d == 0){
				//If it's a 2d particle make a 2d particle

				p[j] = new particle(x,y);
				oldX[j] = p[j].x;
				oldY[j] = p[j].y;
			}
			else{
				//If it's a 3d particle make a 3d particle

				p[j] = new particle(x,y,0);
				oldX[j] = p[j].x;
				oldY[j] = p[j].y;
				oldZ[j] = p[j].z;
			}
		}
		
		return true;
	}
	
	public void movement(){
		
		for(int j=0; j < maxParticles; j++){
			float alpha;
			
			//If the life span has not run out, then calculate the movement
			if(p[j].life > 0){
				oldX[j] = p[j].x;
				oldY[j] = p[j].y;
				if(is3d ==0){
					//If the particle is 2d do 2d calculations

					p[j].x = p[j].x + (int)(p[j].velocity * Cosinus[p[j].theta]);
					p[j].y = p[j].y - (int)(p[j].velocity * Sinus[p[j].theta]);
				}
				else{
					//If the particle is 3d do 3d calculations

					oldZ[j] = p[j].z;
					//Do 3d math

					alpha = p[j].velocity * Cosinus[p[j].phi];
					p[j].y = p[j].y - (int)(p[j].velocity * Sinus[p[j].phi]);
					p[j].x = p[j].x + (int)(alpha * Sinus[p[j].theta]);
					p[j].z = p[j].z + (int)(alpha * Cosinus[p[j].theta]);
				}
			
			}
		}
	}
	
	public void age(){
		//If the particles life span has not completed then

		//age the particle by another cycle.

		for(int j=0; j < maxParticles; j++){
			if(p[j].life > 0){p[j].life--;}
		}
	}
	
}

class particle{
	
	int x , y, z, life, velocity, theta, phi;
	
	particle(int x, int y){ //Default 2d constructor

				
		this.x = x;
		this.y = y;
		this.life = (int)(Math.random() * 20);
		this.velocity = (int)(Math.random() * 10);
		//Note this random angle generation will only produce angles

		//of a certain set of degrees.

		this.theta = (int)(Math.random() * 360);		
	}
	
	particle(int x,int y, int life, int velocity, int theta){ //2d Constructor

		
		this.x = x;
		this.y = y;
		this.life = life;
		this.velocity = velocity;
		this.theta = theta;				
	}
	
	particle(int x, int y, int z){ //Default 3d constructor

				
		this.x = x;
		this.y = y;
		this.z = z;
		this.life = (int)(Math.random() * 20);
		this.velocity = (int)(Math.random() * 10);
		//Note this random angle generation will only produce angles

		//of a certain set of degrees.

		this.theta = (int)(Math.random() * 360);
		this.phi = (int)(Math.random() * 360);
	}
	
	particle(int x, int y, int z, int life, int velocity, int theta, int phi){ //3d constructor

				
		this.x = x;
		this.y = y;
		this.z = z;
		this.life = life;
		this.velocity = velocity;
		this.theta = theta;
		this.phi = phi;
	}
}
        
War doesn't determine who is right, war determines who is left. Edited by - Wrathnut on 8/11/00 3:24:38 PM

This topic is closed to new replies.

Advertisement