import java.applet.Applet;import java.awt.Image;import java.awt.Graphics;import java.awt.image.MemoryImageSource;import java.awt.Dimension;import java.awt.AWTEvent;public class Fairy extends Applet implements Runnable {	int width, height;	int[] pixels;	private Image image = null;	private MemoryImageSource imageSource = null;	public void init(){		Dimension size = getSize();		width = size.width;		height = size.height;		pixels = new int[ width*height ];		imageSource = new MemoryImageSource( width, height, pixels, 0, width );		imageSource.setAnimated( true );		imageSource.setFullBufferUpdates( true );		image = createImage( imageSource );	}	public void drawDust( float x, float y, float radius, float a, int r, int g, int b ){				int min_x = (int)Math.max( 0, x - radius),			min_y = (int)Math.max( 0, y - radius),			max_x = (int)Math.min( width-1, x + radius +1.0f),			max_y = (int)Math.min( height-1, y + radius +1.0f);		float radiusSq = radius*radius;		float halfARadiusSqInv = (0.75f*a)/radiusSq;		for ( int i = min_x; i <= max_x; i++ ){			float dx = i - x;			float dxSq = dx*dx;			for ( int j = min_y; j <= max_y; j++ ){				float dy = j - y;				float distSq = dxSq + dy*dy;				if ( radiusSq >= distSq ){					float alpha = (radiusSq - distSq)*halfARadiusSqInv;					float oneMinusAlpha = 1.0f - alpha;					int index = j*width + i;					int pixel = pixels[ index ];					int red = (pixel & 0x00FF0000) >> 16;					int green = (pixel & 0x0000FF00) >> 8;					int blue = (pixel & 0x000000FF);					red = (int)(red*oneMinusAlpha + r*alpha);					green = (int)(green*oneMinusAlpha + g*alpha);					blue = (int)(blue*oneMinusAlpha + b*alpha);										pixels[ index ] = 0xFF000000 | (red << 16 ) | (green << 8) | blue;									}			}		}	}	private int mouse_x, mouse_y;		public void processMouseMotionEvent( java.awt.event.MouseEvent me ) {		if ( me.getID() == me.MOUSE_MOVED || me.getID() == me.MOUSE_DRAGGED ) {			mouse_x = me.getX();			mouse_y = me.getY();			mouse_in = true;		}	}		private boolean mouse_in = false;		public void processMouseEvent( java.awt.event.MouseEvent me ) {		if ( me.getID() == me.MOUSE_ENTERED ) {			mouse_in = true;		} 		else if ( me.getID() == me.MOUSE_EXITED ) {			mouse_in = false;			mouse_x = (int)((width/2)/* + 0.5*width*(0.5-Math.random())*/);			mouse_y = (int)((height/2)/* + 0.5*height*(0.5-Math.random())*/);		}	}				private volatile boolean running = true;	public void start(){		running = true;		(new Thread( this )).start();	}	private long num = (long)(Integer.MAX_VALUE*Math.random());		private int randomInt(){		num = (num * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);        return (int)(num >>> (48 - 32));	}		private int n = 0;		private float random(){		return ((n = randomInt()) < 0?-n:n)/(float)(Integer.MAX_VALUE);	}	public void run(){		int num_particles = 70;		enableEvents( AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK );		mouse_x = width/2;		mouse_y = height/2;				Thread.currentThread().setPriority( Thread.MIN_PRIORITY );		float[] x = new float[ num_particles ];		float[] y = new float[ num_particles ];		float[] time = new float[ num_particles ];		int[] red = new int[ num_particles ];		int[] green = new int[ num_particles ];		int[] blue = new int[ num_particles ];		for ( int i = 0; i < num_particles; i++ ) {			x[ i ] = (float)(width/2 + 40*(0.5-random()));			y[ i ] = (float)(height/2 + 40*(0.5-random()));			time[ i ] = (float)random();			int r1 = 127 + (int)(128*random());			red[ i ] = r1;			green[ i ] = r1;			blue[ i ] = 127;		}		float xf = width/2;		float yf = height/2;			while ( running ) {						long start = System.currentTimeMillis();						for ( int i = pixels.length-1; i >= 0; --i ) {				 int pixel = pixels[ i ];				 int r = (0x00FF0000 & pixel) >> 16;				 r = 5*r/8;				 r = r < 0? 0 : r;				 int g = (0x0000FF00 & pixel) >> 8;				 g = 5*g/8;				 g = g < 0? 0 : g;				 int b = (0x000000FF & pixel);				 b = 5*b/8;				 b = b < 0? 0 : b;				 				 pixels[ i ] = 0xFF000000 | (r << 16) | (g << 8) | b;			}									for ( int i = 0; i < num_particles; i++ ) {				float t = time[ i ];				if ( t > 0.9f ) {					t = 9.0f*(1.0f - t);				}					drawDust( x[ i ], y[ i ], 5.0f*t + 2.0f, t, red[ i ], green[ i ], blue[ i ] );				x[ i ] += 3*(0.5 - random());				y[ i ] += 1 + 2*(random() -0.1);				time[ i ] -= 0.01;				if ( time[ i ] < 0.0f ) { 					x[ i ] = (float)(xf + 40*(0.5-random()));					y[ i ] = (float)(yf + 40*(0.5-random()));					time[ i ] = 1.0f;					int r1 = 127 + (int)(128*random());					red[ i ] = r1;					green[ i ] = mouse_in? r1/2 : r1;					blue[ i ] = 127;				}				}						float speed = mouse_in? 1.0f : 0.2f;						xf += speed*10.0f*(float)(0.5-random());			yf += speed*10.0f*(float)(0.5-random());						if ( !mouse_in ) {				mouse_x += (int)(7*random()) -3;				mouse_y += (int)(7*random()) -3;						}				float dx = 0.1f*speed;			xf = (1.0f-dx)*xf + mouse_x*dx;			yf = (1.0f-dx)*yf + mouse_y*dx;			  						drawDust( xf, yf, (float)(10 + speed*10*(0.5-random())), 0.8f, 255, 255, 255 );			if ( mouse_in ) {				drawDust( xf, yf, (float)(30 + 4*(0.5-random())), 0.7f, 250, 150, 128 );			}			else {					drawDust( xf, yf, (float)(30 + 2*(0.5-random())), 0.7f, 250, 250, 128 );			}							long stop = System.currentTimeMillis();				/*drawDust( xf -6, yf -5, 10, 1.0f, 255, 255, 255 );			drawDust( xf +6, yf -5, 10, 1.0f, 255, 255, 255 );			drawDust( xf -5, yf +6, 8, 1.0f, 255, 255, 255 );			drawDust( xf +5, yf +6, 8, 1.0f, 255, 255, 255 );*/						imageSource.newPixels();			image.flush();			repaint();			long spare = start + 40 - stop;			//System.out.print( spare );			//System.out.println();			spare = spare < 5? 5 : spare;			try {				Thread.sleep( spare );			}			catch( Exception e ) {}						}			}	public void stop(){		running = false;	}	public void update( Graphics g ){		g.drawImage( image, 0, 0, this );	}}