import java.awt.*;
import javax.swing.*;
import java.applet.*;
import java.awt.image.*;

public class Starfield extends Applet implements Runnable{

Thread aThread=null;
private Image TargetImage=null;
private int TargetPixel[];
private MemoryImageSource idx_mis;
STAR[] stars;
class STAR{
	float x,y,z,z_start;
	int _2x,_2y;
	int direction_z,direction_x,direction_y;
	int colour;
}
private long msStart, msNow, msDiff, lFrames=0;
int h,w;
private ColorModel idx_cm=ColorModel.getRGBdefault();

public void start(){
		if (aThread == null){
			aThread = new Thread(this);
			aThread.start();
		}
}

public void stop(){
		if (aThread != null){
			aThread.stop();
			aThread = null;
		}
}

public void run(){
	while(true){
		repaint();
		try{
			aThread.sleep(1);
		}
		catch (InterruptedException e){
		}
	}
}

public void paint(Graphics g){
}

public void update(Graphics g) {
	for (int i=0; i<h*w; i++){
		TargetPixel[i]=0xff000000;
	}
	for (int i=0;i<stars.length;i++){
		if (stars[i].z<0) stars[i].z=200;
		if (stars[i].z>200) stars[i].z=0;
		stars[i].z+=stars[i].direction_z;
		//stars[i].x+=stars[i].direction_x;
		//stars[i].y+=stars[i].direction_y;
		stars[i]._2y=(int)((w>>1)+(stars[i].y*64)/stars[i].z);
		stars[i]._2x=(int)((h>>1)+(stars[i].x*64)/stars[i].z);
		int colour=(int)(255-stars[i].z);
		if (stars[i]._2x>1 && stars[i]._2x<w-1 
		 && stars[i]._2y>1 && stars[i]._2y<h-1){
			int index=(stars[i]._2y)*w+stars[i]._2x;
			TargetPixel[index] =0xff000000
			                      | colour<<16
			                        | colour<<8
			                          | colour;
		}
	}
	lFrames++;
	idx_mis.newPixels();
	g.drawImage(TargetImage,0,0,this);
        msNow = System.currentTimeMillis();
        msDiff = msNow - msStart;
        showStatus( "FPS: " + (lFrames  * 1000 / msDiff));
}

private float _RANDOM(float r){
     return ((float)Math.random()*r);
}

public void init() {
	w=size().width;
	h=size().height;
	TargetPixel=new int[w*h];
	idx_mis=new MemoryImageSource(w,h,idx_cm,TargetPixel,0,w);
	idx_mis.setAnimated(true);
	idx_mis.setFullBufferUpdates(true);
	TargetImage=createImage(idx_mis);
	stars=new STAR[100];

	for (int i=0;i<stars.length;i++){
		stars[i]=new STAR();
		stars[i].x=(_RANDOM(2.0f)-1.0f)*256.0f;
		stars[i].y=(_RANDOM(2.0f)-1.0f)*256.0f;
		stars[i].z_start=_RANDOM(1.0f)*200f;
		stars[i].z=stars[i].z_start;
		stars[i].direction_z=1;
		stars[i].direction_x=0;
		stars[i].direction_y=0;
	}
	msStart = System.currentTimeMillis();
}

}