//プログラム s8100032 神谷 //修正 //テトリスもどき ゲーム import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.event.KeyEvent; /* */ //スレッドとキー入力を利用する public class tetoris extends Applet implements Runnable,KeyListener { boolean isStandalone = false; //引数値の取得 public String getParameter(String key, String def) { return isStandalone ? System.getProperty(key, def) : (getParameter(key) != null ? getParameter(key) : def); } Thread w_clock = null; //スレッド Image image1;//ダブルバッファ Graphics offgraphics; int area[][] = new int [14][24]; //ピース記憶領域 int piece[][] = new int [5][5]; //ブロック生成領域 boolean start_check = false; boolean loop_check = false; boolean replay_check = true; boolean level_check = true; int bx,by; //落下中のピースの座標 int bp; //生成ピースの番号 int nline; //消したラインの総数 int nscore; //現在のスコア int nlevel; //現在のレヴェル int nfast=500; //アプレットの初期化 public void init() { ///キー入力大作戦 addKeyListener(this); try { jbInit(); } catch(Exception e) { e.printStackTrace(); } }//init //コンポーネントの初期化 private void jbInit() throws Exception { this.setBackground(Color.black);//背景色を黒に this.setForeground(Color.white); }//jbinit //関数の定義が必要 public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){} //キーが押されたらキーイベントで呼び出される public void keyPressed(KeyEvent e){ if(!start_check){ if(e.getKeyCode() == KeyEvent.VK_S){//'s'(開始(start)キー) start_check = true; Set_Init(); Game_Start(); }//if keyEvent s }//if start_check else if(!replay_check){ if(e.getKeyCode() == KeyEvent.VK_S){ replay_check = true; Set_Init(); loop_check = false; }//if keyEvent s }//if replay_check else /*if(level_check)*/{ switch(e.getKeyCode()) { case KeyEvent.VK_DOWN://方向キー Move_Down();//下移動 break; case KeyEvent.VK_RIGHT: Move_Right();//右移動 ?? break; case KeyEvent.VK_LEFT: Move_Left(); break; case KeyEvent.VK_SPACE://空白キー Roll_piece();//回転 ?? }//switch }//else repaint();//再描画; }//keypress ////////////////////////////////////////////////////////////////////////////// //////                 初期化              ////// ////////////////////////////////////////////////////////////////////////////// public void Set_Init(){//初期化 int i,j; bx = 7; by = 2; nline = 0; nscore = 0; nlevel = 1; nfast = 500; ///フィールドの初期化 /// 0 :ピースが存在しない、-1 :壁 for(i=2;i<12;i++) for(j=0;j<22;j++) area[i][j] = 0; for(i=1;i<13;i+=11)//左右の壁 for(j=0;j<22;j++) area[i][j] = -1; for(i=2;i<12;i++){//下の壁 area[i][22] = -1; area[i][23] = -1; } //最初のピースの生成 Create_piece(); }//set init /////////////////////////////////////////////////////////////////////////////// //////             ピースの描画               ////// ////////////////////////////////////////////////////////////////////////////// public void paint (Graphics g)//表示 { Graphics graphics = offgraphics; int i,j; //消去 graphics.clearRect(0,0, getWidth() , getHeight());//?? graphics.setColor(Color.darkGray); graphics.fillRect(99,19,151,301); //フィールドに落下したピースを表示 for(i=2;i<12;i++){ for(j=2;j<22;j++){ if(area[i][j] >= 1){ graphics.setColor(new Color(100+area[i][j]*22, 150+area[i][j]%2*70,80+(7-area[i][j])*25));//ピースの番号から色を作成 graphics.fillRect(100+(i-2)*15,20+(j-2)*15,14,14); } else if(area[i][j] == -5){//ゲーム終了時 graphics.setColor(Color.gray); graphics.fillRect(100+(i-2)*15,20+(j-2)*15,14,14); } else{ graphics.setColor(new Color(0,0,0));//黒を指定 graphics.fillRect(100+(i-2)*15,20+(j-2)*15,14,14); } } } //落下中のピースを表示 for(i=0;i<5;i++){ for(j=0;j<5;j++){ if(piece[i][j] >= 1){ graphics.setColor(new Color(100+piece[i][j]*22, 150+piece[i][j]%2*70,80+(7-piece[i][j])*25)); graphics.fillRect(100 + (i + bx - 4) * 15,20 + (j + by - 4) * 15,14,14); } } } //文字フォントを設定 graphics.setFont(new Font("MS Gothic",Font.PLAIN,12)); graphics.setColor(Color.white); graphics.drawString("Score",20,50); graphics.drawString(Integer.toString(nscore),40,89); graphics.drawString("Level",20,140); graphics.drawString(Integer.toString(nlevel),40,179); graphics.drawString("Line",25,230); graphics.drawString(Integer.toString(nline),40,269); if(!level_check){ level_check = true; graphics.drawString("Level up!!",110,165); }//if level_chck if(!start_check){ graphics.drawString("Press 'S' key !!",110,165); }//if if(!replay_check){ graphics.drawString("Game over",140,155); graphics.drawString("press 's'key.",90,171); }//if g.drawImage(image1,0,0,this); }//paint ////////////////////////////////////////////////////////////////////////////// //////              スレッド実働部                ////// //////          ゲームオーバーの判定など…              ////// ////////////////////////////////////////////////////////////////////////////// public void run() { int i,j,count; while (true) { if(!loop_check){ count = 0; //ピースをひとつ下に落下が可能かどうか? for(i=0;i<5;i++)//背景が0のダイスの数 for(j=0;j<5;j++) if(piece[i][j] >= 1 && area[bx + i - 2][by + j - 1] == 0)count++; if(count!=4){//ピースの落下は不可 //ピースをフィールドにおく for(i=0;i<5;i++) for(j=0;j<5;j++) if(piece[i][j] >= 1)area[bx + i - 2][by + j - 2] = piece[i][j];// CheckClear();//行が消せるかどうか判定/処理する関数を呼ぶ;?? if(area[7][2]>=1){//ゲームオーバー loop_check = true; Game_Over(); replay_check = false; }//if game over //次のピースを準備 bx=7; by=2; Create_piece(); //*ピースを生成する関数を呼ぶ; ?? }//if count not4 else by++; }//if loop_check ///再描画 repaint(); try { Thread.sleep(nfast);//nfast時間休止 }//try catch(Exception e) {}//catch }//while }//run ///////////////////////////////////////////////////// //////   ダブルバッファ           ////// ////////////////////////////////////////////////////// public void update(Graphics g) { //g.clipRect(5,5,95,95); paint(g); }//update ///////////////////////////////////////////////////////////// //////  ピースを生成する             ////// ///////////////////////////////////////////////////////////// public void Create_piece(){ int i,j; ///ピース生成領域の初期化 for(i=0;i<5;i++) for(j=0;j<5;j++) piece[i][j] = 0; ///乱数( bp )よりピースを生成 bp = (int)(Math.random() * 100000 ) % 7 + 1; switch(bp){ case 1: piece[1][1] = bp; piece[1][2] = bp; break; case 2: piece[3][1] = bp; piece[3][2] = bp; break; case 3: piece[1][2] = bp; piece[1][3] = bp; break; case 4: piece[2][1] = bp; piece[3][3] = bp; break; case 5: piece[2][1] = bp; piece[1][3] = bp; break; case 6: piece[1][3] = bp; piece[3][3] = bp; break; case 7://I 型ピース piece[2][1] = bp; piece[2][4] = bp;//?? break; }//switch piece[2][2] = bp; piece[2][3] = bp; }//create_piece /////////////////////////////////////////////////////////////////////// ////// ピースを下に移動する ////// /////////////////////////////////////////////////////////////////////// public void Move_Down(){ int i,j,count; count = 0; ///移動可能か判定 for(i=0;i<5;i++) for(j=0;j<5;j++) if(piece[i][j] >= 1 && area[bx + i - 2][by + j - 1] == 0)count++; if(count == 4){///移動可 by++; nscore += nlevel; }//if repaint(); }//movedown ///////////////////////////////////////////////////////////// ////// ピースを右に移動する ////// ///////////////////////////////////////////////////////////// public void Move_Right(){ int i,j,count; count = 0; ///移動可能か判定 for(i=0;i<5;i++) for(j=0;j<5;j++) if(piece[i][j] >= 1 && area[bx + i - 1][by + j - 2] == 0)count++; ///可能ならば移動 if(count == 4)bx++; repaint(); }//move right ///////////////////////////////////////////////////////////////// ////// ピースを左に移動する ////// ///////////////////////////////////////////////////////////////// public void Move_Left(){ int i,j,count; count = 0; ///移動可能か判定 for(i=0;i<5;i++) for(j=0;j<5;j++) if(piece[i][j] >= 1 && area[bx + i - 3][by + j - 2] == 0)count++; ///可能ならば移動 if(count == 4)bx--; repaint(); }//move left ////////////////////////////////////////////////////////////// ////// ピースを回転する ////// ///////////////////////////////////////////////////////////// public void Roll_piece(){ int i,j,count; int copy_piece[][] = new int[5][5];//*配列の領域を確保; ?? count = 0; ///仮回転体生成 for(i=0;i<5;i++) for(j=0;j<5;j++) //copy_piece[i][j] = piece[?? - j][i];//?? copy_piece[4-j][i] = piece[i][j]; ///仮回転体を使用して回転可能か判定 for(i=0;i<5;i++) for(j=0;j<5;j++) if(copy_piece[i][j] >= 1 && area[bx + i - 2][by + j - 2] == 0)count++; ///回転可能なら回転する if(count == 4){ ///生成したピースを回転後の形に更新 for(i=0;i<5;i++) for(j=0;j<5;j++) piece[i][j] = copy_piece[i][j]; repaint(); }//if }//roll piece //////////////////////////////////////////////////////////////////// //////   ラインが消せるかどうかを判定後クリア            ////// //////////////////////////////////////////////////////////////////// public void CheckClear(){ ///ピースが消えるかどうかを判定・ピースの消去 int i,j,s,k; int ld; //ラインが消せるかどうか判定する int flg=0; //ライン消したかどうか確認する int hline; int linecount=0; //一度に消した行数 int bonus=1; //スコア計算用 hline = nline/10; //ラインが消せるかどうか判定 for(i=21;i>0;i--){ ///ラインが消せるかどうか判定 ld=1; for(j=2;j<12;j++)ld = ld * area[j][i]; if(ld!=0){ //一列消した!! //ラインが消去可能ならば上からプレスする for(k=i-1;k>0;k--) for(s=2;s<12;s++)area[s][k+1]=area[s][k]; flg=1; i++; nline++;//累積行数 linecount++; }//if }//for //一列でも消していたら… if(flg==1){ ///スコアの計算 for(i=1;i10 ){//10段消すと nlevel++; //レベルアップ!! level_check = false; nfast-=40; //早く落ちます if(nfast<=70)nfast=120; //最小120 }//if repaint(); }//if flag1 }//checkclear //////////////////////////////////////////////////////////////// //////       [s]キーが押されたときの処理          ////// ///////////////////////////////////////////////////////////////// void Game_Start(){ w_clock = new Thread(this); w_clock.start(); }//game start public void start(){ ///ダブルバッファ image1 = createImage(this.getSize().width ,this.getSize().height); offgraphics = image1.getGraphics(); Set_Init(); }//start //////////////////////////////////////////////////////////////// //////           ゲームオーバー時の処理        ////// //////////////////////////////////////////////////////////////// void Game_Over(){ int i,j; for(j=22;j>1;j--){ for(i=2;i<12;i++) if(area[i][j] >= 1)area[i][j] = -5; repaint(); }//for }//game over }//tetoris