//
/* ---------------------------------------------------------------------------------------------- tracking.java CD のトラッキング制御 ver. 2.00 (JDK 1.02) ueyama@infonet.co.jp 2001.05.03 update: 2007.08.22 ---------------------------------------------------------------------------------------------- */ import java.applet.Applet; import java.awt.*; import java.util.*; public class tracking extends Applet implements Runnable { int Px=33, Lx=94; // ピットとレーザービームの X 座標値 int Py[][]=new int[3][4]; // ピットの Y 座標値 int Pl[][]=new int[3][4]; // ピットの長さ int Ps[]={0,40,56,72,88,104}; // ピットの長さ(ピクセル) int Gl[]={40,39,38,37,36,35,33,31,29,27,25,23}; // グラフの長さ int Wait=32; // 表示変更待機時間 (msec) int N=0,D=1; int Mf=-1; boolean F0=false, F1=false; boolean Run=false; Image Img; Image Buf; int Bgc; Random Rnd=new Random(); Graphics bf; Thread th; public void init() { int i,j,k,l; String bg=getParameter("bgcolor"); Bgc=Integer.valueOf(bg,16).intValue(); // html 背景色 setBackground(new Color(221,221,221)); // CD 鏡面色 Buf=createImage(250,380); MediaTracker mt=new MediaTracker(this); Img=getImage(getCodeBase(), getParameter("figure")); mt.addImage(Img, 0); try { mt.waitForID(0); } catch(InterruptedException e){}; for(i=0;i<3;i++) // ピットの位置と長さの設定 { for(j=0;j<4;j++) Pl[i][j]=Math.abs(Rnd.nextInt())%4+1; Py[i][0]=Rnd.nextInt()%40; for(j=1;j<4;j++) Py[i][j]=Py[i][j-1]+Ps[Pl[i][j-1]]+Ps[Math.abs(Rnd.nextInt())%4+1]; } } public void start() { th=new Thread(this); th.start(); } public void stop() { if(th!=null) { th.stop(); th=null; } } public void update(Graphics g) { paint(g); } public boolean inside(int x, int a, int b) { return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false; } public void dsp_p(int x, int y, int l) // ピットの表示 { int i; dsp_g(x,y,0,0,3); // ピットの上部を描く for(i=0;i戻る>, <<, |>, □) case 3: w= 25; h= 12; ox= 0; oy= 0; break; // ピット上部 case 4: w= 25; h= 16; ox= 0; oy= 12; break; // ピット中央 case 5: w= 25; h= 12; ox= 0; oy= 28; break; // ピット下部 case 6: w= 13; h= 13; ox= 66; oy= 92; break; // 矢印 } Graphics gx=bf.create(); gx.clipRect(x,y,w,h); gx.drawImage(Img,x-(ox+w*m),y-(oy+h*n),this); gx.dispose(); } public int btn(int n) // ボタンの表示条件 { int m=0; // 通常は白いボタン if((n==0 && Mf==0) || (n==2 && Mf==2)) m=1; // クリックされているときは緑のボタン if((n==0 && Wait==512) || (n==2 && Wait==8)) m=2; // 早すぎ、遅すぎは灰色に return m; } public void paint(Graphics g) { int i,j,l; bf=Buf.getGraphics(); bf.clearRect(0,0,250,350); for(i=0;i<3;i++) for(j=0;j<4;j++) dsp_p(Px+i*80,Py[i][j],Pl[i][j]); // ピットの表示 dsp_g(Lx,119,0,0,0); // レーザビーム(主)の表示 dsp_g(Lx+45,18,0,0,1); dsp_g(Lx-23,241,0,0,1); // レーザビーム(副)の表示 bf.setColor(new Color(Bgc)); bf.fillRect(0,300,250,80); dsp_g( 82,357, btn(0),1,2); // << ボタンの表示 dsp_g(112,357, (Mf==1)?1:0,(Run)?3:2,2); // |> & □ ボタンの表示 dsp_g(142,357, btn(2),0,2); // >> ボタンの表示 bf.setColor(new Color(255,156,156)); // グラフの表示色 l=(F0)? Gl[get_dup(-1)]:40; // 左のグラフの長さを求める bf.fillRect(80,310+(40-l),20,l); // グラフの表示 if(l<40) dsp_g(107,307, (N%20)/10*2,0,6); // グラフが短いときは矢印をウインクさせる l=(F1)? Gl[get_dup(1)]:40; // 右側のグラフも同様に bf.fillRect(150,310+(40-l),20,l); if(l<40) dsp_g(130,307, (N%20)/10*2+1,0,6); g.drawImage(Buf,0,0,this); // バッファの表示 bf.dispose(); } public void run() { int i,j,y0,y1,y2,x0,x1; while(true) { repaint(); try { Thread.sleep((Run)?Wait:128); } catch (InterruptedException e){}; if(Run) { for(i=0;i<3;i++) { for(j=0;j<4;j++) Py[i][j]--; // ピットを上方に移動 if(Py[i][0]+Ps[Pl[i][0]]==0) // 画面から消えた { for(j=0;j<3;j++) Py[i][j]=Py[i][j+1]; // 新規ピットデータの作成 for(j=0;j<3;j++) Pl[i][j]=Pl[i][j+1]; Py[i][j]=Py[i][j-1]+Ps[Pl[i][j-1]]+Ps[Math.abs(Rnd.nextInt())%4+1]; Pl[i][j]=Math.abs(Rnd.nextInt())%4+1; } } F0=false; F1=false; for(i=0;i<4;i++) // レーザーとピットの接触検出 { x1=Px+80+13; y1=Py[1][i]+13; y2=y1+Pl[1][i]*16; // ピットの中心座標 if(x1-Lx>32) {x0=Lx+45+21; y0= 18+21;} // レーザ副ビームの中心座標 else {x0=Lx-23+21; y0=241+21;} if(inside(y0,y1,y2) && x0-x1<33) // ピット直線部の接触 { if(i<2) F1=true; if(i>0) F0=true; } else // ピットの両端での接触 { if(y1 0) F0=true; } } } N++; if(N%100==0) { if((Lx-Px)!=61) Lx+=D; // レーザーをピットの方向に移動 else if(Px!=33) // ピットとレーザーを中央に戻す { i=33-Px; i/=Math.abs(i); Lx+=i; Px+=i; } } } } } public int get_dup(int m) // レーザーとピットの重なり幅 { int d=0; d=(m>0)? (Px+80+25)-(Lx+45): (Lx-23+41)-(Px+80); if(d>11) d=11; // 11 は配列 Gl[] の要素数 return (d<0)?0:d; } public boolean mouseDown(Event e, int x, int y) // マウスがクリックされたときの処理 { int m=(x-125)/63, g=get_dup(m); if(y<300) { if(g<11) Px+=m; // CD 部両端をクリック if(m==0) {Px=33; Lx=94;} // CD 部中央をクリック else D=m; } if(inside(x, 82,168) && y>357) // ボタンをクリック { Mf=(x-82)/30; // Mf: 0=<<, 1=|>, 2=>> if(inside(x, 82,108) && Wait<512) Wait*=2; // << ボタンをクリック if(inside(x,142,168) && Wait> 8) Wait/=2; // >> ボタンをクリック } return true; } public boolean mouseUp(Event e, int x, int y) // クリックを止めたときの処理 { if(Mf==1) Run=!Run; if(inside(x, 82,168) && y>357) Mf=-1; return true; } } //