とんねる



// ===================================================================
//	import
// ===================================================================
import java.applet.*;
import java.awt.*;
//import java.util.*;
import java.awt.image.*;

// ===================================================================
//	draw
// ===================================================================


class KcTunnel {

	Image 				w_img;
	MemoryImageSource	w_mi;
	
	int					w_width;
	int					w_hight;
	int					w_pixels[];
	
	int					w_org_pixels[];
	int					w_pic_width;
	int					w_pic_hight;
	
	int					w_tunnel_u[][];
	int					w_tunnel_v[][];
	int					w_tunnel_rot_spd;
	int					w_tunnel_go_spd;
		
	// --------------------------------- tunnel table
	void makeTunnelTbl()
	{
		w_tunnel_u = new int[w_width][w_hight];
		w_tunnel_v = new int[w_width][w_hight];
		
		int u, v;
		
		int depth = 255*4;
		int dist = 20;
		double len;
		
		for( int y = -w_hight/2; y < w_hight/2; y ++ ) {
			for( int x = -w_width/2; x < w_width/2; x ++ ) {
								
				// ------ u:x,yの角度				
				w_tunnel_u[x+w_width/2][y+w_hight/2] = (int) Math.round( ((Math.atan2(y,x)+Math.PI) * (w_pic_width-1))/(2*Math.PI) )  ;

				// ------ v:zの値				
				len = Math.sqrt(x*x + y*y);
				
				w_tunnel_v[x+w_width/2][y+w_hight/2] = ((int) ( (depth*dist*(w_width - len)) / (depth*len + dist*w_width) ))%w_pic_hight;

				
				/*
				if( len == 0 ) {
					w_tunnel_v[x+w_width/2][y+w_hight/2] = 0;
				}else {
					w_tunnel_v[x+w_width/2][y+w_hight/2] = (int) ((16*w_width)/len);
				}
				*/
				
				
			}
		}
	}
	
	

	// --------------------------------- コンストラクタ
	public KcTunnel(Applet oya, int width, int height, String s) {
		
					
		
		// --------- get pixels
		Image image = oya.getImage(oya.getDocumentBase() , s);
		PixelGrabber pg = new PixelGrabber(image , 0 , 0 , -1 , -1 , true);

		try { 
			pg.grabPixels(); 
		}
		catch (InterruptedException e) {
		}
		
		w_org_pixels = (int[])pg.getPixels();
		w_pic_width = pg.getWidth();
		w_pic_hight = pg.getHeight();


		// --------- buffer 
		w_width = width;
		w_hight = height;
		w_pixels = new int[w_width*w_hight];
		
		// ---- これやんないと、WinMeで、ちらつく、、、不思議だのう。(mac,xpはしなくともOK)
		for( int y = 0; y < w_hight; y++ ) {
			for( int x = 0; x < w_width; x ++ ) {
								
				w_pixels[x + (y * w_width)] = w_org_pixels[x + (y * w_pic_width)];
			}
		}

		// --------- offscreen  		
		w_mi = new MemoryImageSource(w_width , w_hight , w_pixels , 0 , w_width);
		w_mi.setAnimated( true );
		w_img = oya.createImage(w_mi);
		

		// --------- make tunnel table  		
		makeTunnelTbl();
		w_tunnel_rot_spd = 0;
		w_tunnel_go_spd =0;
	}
		
	// --------------------------------- 計算
	void calcTunnel() {
		w_tunnel_rot_spd++;
		if( w_tunnel_rot_spd >= w_pic_width ) {
			w_tunnel_rot_spd = 0;
		}
		
		w_tunnel_go_spd+=4;
		if( w_tunnel_go_spd >= w_pic_hight ) {
			w_tunnel_go_spd = 0;
		}
	}
	
	// --------------------------------- バッファ描画
	void drawTunnel() {
		

		int u, v;
		
		for( int y = 0; y < w_hight; y++ ) {
			for( int x = 0; x < w_width; x ++ ) {
				
				u = (w_tunnel_u[x][y]+w_tunnel_rot_spd)%w_pic_width;
				v = (w_tunnel_v[x][y]+w_tunnel_go_spd)%w_pic_hight;
								
				w_pixels[x + (y * w_width)] = w_org_pixels[u + v * w_pic_width];
				
			}
		}
	}
		
	// --------------------------------- ペイント
	public void paint() {
		
		calcTunnel();
		drawTunnel();

		// --------- ピクセルが変更されたでよ
		w_mi.newPixels();
		
					
  	}
	
	// --------------------------------- イメージ取得
	public Image getImage() {
		return	w_img;
	}
	
}


// ===================================================================
//	main
// ===================================================================
public class KcApp extends Applet implements Runnable {

	Thread 			w_thread = null;
	
	KcTunnel			w_draw;
	
	int				w_wave_height;
			

	// --------------------------------- アプレット起動時に実行
	public void init() {
	}

	// --------------------------------- アプレットがあるHTMLページに入ったときに実行
	public void start() {
		if (w_thread == null)
		{
			// スレッドの起動
			w_thread = new Thread(this);
			w_thread.start();
			
			String s = getParameter("file");
			Dimension dim = getSize();
			int width = dim.width; //getWidth();
			int height = dim.height; //getHeight();
			w_draw = new KcTunnel( this, width, height, s );
			
										
		}
	}

	// --------------------------------- アプレットがあるHTMLページから出たときに実行
	public void stop() {
		if (w_thread != null)
		{
			// スレッドの停止
			w_thread = null;
		}
	}
	
	// --------------------------------- アプレット終了時に実行
	public void destroy() {
	}

	// --------------------------------- 描画
	public void paint(Graphics g) {
      	
      	if( w_draw == null ) return;
              		
	    g.drawImage(w_draw.getImage() ,0,0,this);
		
	}

	// --------------------------------- 再描画
	public void update(Graphics g) {
		paint(g);
	}

	// --------------------------------- スレッドの実行
	public void run() {

        Thread thisThread = Thread.currentThread();

		while (w_thread == thisThread) {
			
						
			// 処理
			if( w_draw != null ) {
				w_draw.paint();
			}

			// 再描画
			repaint();
			

			try
			{
				// 0.01秒間の停止
				thisThread.sleep(10);
			}
			catch(Exception e) {
			}
			
			
		}
	}
}