/********************************/ /* ぷよぷよ(ゲーム全体の制御) */ /********************************/ import java.awt.*; import java.awt.event.*; import java.applet.*; import java.util.*; public class Game2 extends Applet implements Runnable { int p_x = 0, p_y = 0, rot = 0, row = 12, col = 5; boolean state = true, game = true, ok = true; Puyo py; int p[][] = new int [row][col]; Random rn; Thread th; /************/ /* 初期設定 */ /************/ public void init() { // 背景色 setBackground(new Color(238, 255, 238)); // ゲームパネルの配置 setLayout(null); py = new Puyo(this); add(py); py.setSize(30*col, 30*row); py.setLocation(10, 10); py.setBackground(Color.white); rn = new Random(); // ピースの選択 select(); // スレッドの生成 th = new Thread(this); th.start(); } /******************/ /* 左右上下の余裕 */ /******************/ public Insets getInsets() { return new Insets(10, 10, 10, 10); } /******************/ /* スレッドの停止 */ /******************/ public void stop() { state = false; } /******************/ /* スレッドの実行 */ /******************/ public void run() { int i1, i2, i3, i4, ct; int pp[][] = new int [row][col]; while (state) { try { th.sleep(500); } catch (InterruptedException e) {} // ピースの落下 ct = 0; if (rot == 0) { if (p_y < row-1) { if (ok) { if (p[p_y+1][p_x] == 0 && p[p_y+1][p_x+1] == 0) { ct = 1; p[p_y+1][p_x] = p[p_y][p_x]; p[p_y+1][p_x+1] = p[p_y][p_x+1]; p[p_y][p_x] = 0; p[p_y][p_x+1] = 0; p_y++; } else { ok = false; if (p[p_y+1][p_x] == 0) { ct = 1; p[p_y+1][p_x] = p[p_y][p_x]; p[p_y][p_x] = 0; p_y++; } else if (p[p_y+1][p_x+1] == 0) { ct = 1; p[p_y+1][p_x+1] = p[p_y][p_x+1]; p[p_y][p_x+1] = 0; p_x++; p_y++; } } } else { if (p[p_y+1][p_x] == 0) { ct = 1; p[p_y+1][p_x] = p[p_y][p_x]; p[p_y][p_x] = 0; p_y++; } } } } else { if (p_y < row-2 && p[p_y+2][p_x] == 0) { ct = 1; p[p_y+2][p_x] = p[p_y+1][p_x]; p[p_y+1][p_x] = p[p_y][p_x]; p[p_y][p_x] = 0; p_y++; } else ok = false; } // 消去と次のピース if (ct == 0) { ct = 4; while (ct >= 4) { ct = 0; for (i1 = row-1; i1 >= 0 && ct < 4; i1--) { for (i2 = 0; i2 < col && ct < 4; i2++) { for (i3 = 0; i3 < row; i3++) { for (i4 = 0; i4 < col; i4++) pp[i3][i4] = 0; } if (p[i1][i2] > 0) { pp[i1][i2] = 1; ct = search(pp, i1, i2, 1); } } } if (ct >= 4) delete(p, pp); } select(); } // 再描画 py.repaint(); } } /****************/ /* ピースの選択 */ /****************/ void select() { int color; ok = true; rot = 0; p_y = 0; p_x = (int)(rn.nextDouble() * (col - 1)); if (p_x > col-2) p_x = col - 2; if (p[0][p_x] == 0 && p[0][p_x+1] ==0 ) { color = (int)(rn.nextDouble() * 4) + 1; if (color > 4) color = 4; p[0][p_x] = color; color = (int)(rn.nextDouble() * 4) + 1; if (color > 4) color = 4; p[0][p_x+1] = color; } else game = false; } /*************************************/ /* 同じ色のピースを探す */ /* pp : 同じ色のピース位置 */ /* k1,k2 : 対象としているピース */ /* c1 : 同じ色のピースの数 */ /* return : 同じ色のピースの数 */ /*************************************/ int search(int pp[][], int k1, int k2, int c1) { int ct = c1; if (k1 > 0 && p[k1-1][k2] == p[k1][k2] && pp[k1-1][k2] == 0) { pp[k1-1][k2] = 1; ct = search(pp, k1-1, k2, ct+1); } if (k1 < row-1 && p[k1+1][k2] == p[k1][k2] && pp[k1+1][k2] == 0) { pp[k1+1][k2] = 1; ct = search(pp, k1+1, k2, ct+1); } if (k2 > 0 && p[k1][k2-1] == p[k1][k2] && pp[k1][k2-1] == 0) { pp[k1][k2-1] = 1; ct = search(pp, k1, k2-1, ct+1); } if (k2 < col-1 && p[k1][k2+1] == p[k1][k2] && pp[k1][k2+1] == 0) { pp[k1][k2+1] = 1; ct = search(pp, k1, k2+1, ct+1); } return ct; } /********************************/ /* 同じ色のピースを削除 */ /* p : ピース位置 */ /* pp : 同じ色のピース位置 */ /********************************/ void delete(int p[][], int pp[][]) { int i1, i2, i3, k1, k2, k3; // 削除 for (i1 = 0; i1 < row; i1++) { for (i2 = 0; i2 < col; i2++) { if (pp[i1][i2] > 0) p[i1][i2] = 0; } } // 詰める for (i1 = 0; i1 < col; i1++) { k1 = 1; for (i2 = row-1; i2 > 0 && k1 >= 0; i2--) { if (p[i2][i1] == 0) { k1 = -1; for (i3 = i2-1; i3 >= 0 && k1 < 0; i3--) { if (p[i3][i1] > 0) k1 = i3; } if (k1 >= 0) { k2 = i2; k3 = k2 - k1; while (k1 >= 0) { p[k2][i1] = p[k1][i1]; k1--; k2--; } k1++; for (i3 = 0; i3 < k3; i3++) p[i3][i1] = 0; } } } } } } /****************/ /* ゲームパネル */ /****************/ class Puyo extends Panel { Game2 gm; /******************/ /* コンストラクタ */ /******************/ Puyo (Game2 gm_t) { gm = gm_t; addKeyListener(new Key_e()); } /********/ /* 描画 */ /********/ public void paint (Graphics g) { int i1, i2; // ゲーム中 if (gm.game) { for (i1 = 0; i1 < gm.row; i1++) { for (i2 = 0; i2 < gm.col; i2++) { if (gm.p[i1][i2] > 0) { switch (gm.p[i1][i2]) { case 1: g.setColor(Color.red); break; case 2: g.setColor(Color.pink); break; case 3: g.setColor(Color.green); break; case 4: g.setColor(Color.blue); break; } g.fillRect(i2*30, i1*30, 30, 30); } } } } // ゲームオーバー else { Font f = new Font("TimesRoman", Font.BOLD, 40); g.setFont(f); g.drawString("Game", 20, 200); g.drawString("Over!", 25, 250); gm.state = false; } } /************************/ /* キーイベントの有効化 */ /************************/ public boolean isFocusable() { return true; } /**********************/ /* キーイベントの処理 */ /**********************/ class Key_e extends KeyAdapter { public void keyPressed(KeyEvent e) { int k; if (gm.ok) { if (e.getKeyCode() == KeyEvent.VK_LEFT) { // 左矢印(左移動) if (gm.p_x > 0) { if (gm.rot == 0 && gm.p[gm.p_y][gm.p_x-1] == 0) { gm.p[gm.p_y][gm.p_x-1] = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y][gm.p_x] = gm.p[gm.p_y][gm.p_x+1]; gm.p[gm.p_y][gm.p_x+1] = 0; gm.p_x--; repaint(); } else if (gm.p[gm.p_y][gm.p_x-1] == 0 && gm.p[gm.p_y+1][gm.p_x-1] == 0) { gm.p[gm.p_y][gm.p_x-1] = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y+1][gm.p_x-1] = gm.p[gm.p_y+1][gm.p_x]; gm.p[gm.p_y][gm.p_x] = 0; gm.p[gm.p_y+1][gm.p_x] = 0; gm.p_x--; repaint(); } } } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { // 右矢印(右移動) if (gm.rot == 0) { if (gm.p_x < gm.col-2 && gm.p[gm.p_y][gm.p_x+2] == 0) { gm.p[gm.p_y][gm.p_x+2] = gm.p[gm.p_y][gm.p_x+1]; gm.p[gm.p_y][gm.p_x+1] = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y][gm.p_x] = 0; gm.p_x++; repaint(); } } else { if (gm.p_x < gm.col-1 && gm.p[gm.p_y][gm.p_x+1] == 0 && gm.p[gm.p_y+1][gm.p_x+1] == 0) { gm.p[gm.p_y][gm.p_x+1] = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y+1][gm.p_x+1] = gm.p[gm.p_y+1][gm.p_x]; gm.p[gm.p_y][gm.p_x] = 0; gm.p[gm.p_y+1][gm.p_x] = 0; gm.p_x++; repaint(); } } } else if (e.getKeyCode() == KeyEvent.VK_UP) { // 上矢印(上下または左右入れ替え) if (gm.rot == 0) { k = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y][gm.p_x] = gm.p[gm.p_y][gm.p_x+1]; gm.p[gm.p_y][gm.p_x+1] = k; } else { k = gm.p[gm.p_y][gm.p_x]; gm.p[gm.p_y][gm.p_x] = gm.p[gm.p_y+1][gm.p_x]; gm.p[gm.p_y+1][gm.p_x] = k; } repaint(); } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { // 下矢印(90度または-90度回転) if (gm.rot == 0 && gm.p[gm.p_y+1][gm.p_x] == 0) { if (gm.p_y < gm.row-1) { gm.p[gm.p_y+1][gm.p_x] = gm.p[gm.p_y][gm.p_x+1]; gm.p[gm.p_y][gm.p_x+1] = 0; gm.rot = 1; repaint(); } } else { if (gm.p_x < gm.col-1 && gm.p[gm.p_y][gm.p_x+1] == 0) { gm.p[gm.p_y][gm.p_x+1] = gm.p[gm.p_y+1][gm.p_x]; gm.p[gm.p_y+1][gm.p_x] = 0; gm.rot = 0; repaint(); } } } } } } }