import java.lang.*; import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; public class Sg extends Applet implements Runnable, MouseListener { Thread cycleExec = null; // thread private int sleepTime = 16; // threadスリープ時間 // 仮想画面関連変数 static final int bgCellSize = 16; // BG画面基本セルサイズ static final int bgCellXNum = 24; // BG画面横方向個数 static final int bgCellYNum = 18; // BG画面縦方向個数 private int bgWidth; // BG画面幅 private int bgHeight; // BG画面高さ private Image bgBuff; // BGバッファ private Graphics bg; // BGバッファGraphics // フィールド関連変数 static final int fldWidth = 22; // フィールド幅 static final int fldHeight = 15; // フィールド高さ static final int fldPosX = 1; // フィールド左上x座標 static final int fldPosY = 1; // フィールド左上y座標 private int field[][] = new int[fldWidth+2][fldHeight+2]; // フィールド変数 private int fieldChecked[][] = new int[fldWidth+2][fldHeight+2]; // ブロック消去判定用 private int fieldErased[][] = new int[fldWidth+2][fldHeight+2]; // ブロック消去処理用 private Image chrSet; // キャラクタセット private Image chr[] = new Image[256]; // キャラクタパターン static final int initColNum = 2; // 色数初期値 private int colorNum = initColNum; // 色数 static final int col1 = 0x80; // 色番号1 static final int col2 = 0x90; // 色番号2 static final int col3 = 0xa0; // 色番号3 static final int col4 = 0xb0; // 色番号4 static final int col5 = 0xc0; // 色番号5 private int score = 0; // スコア private int phase = 1; // 面 private int eraseCnt; // 消去回数 private int maxEraseNum; // 最大消去数 private int totalEraseNum; // 平均消去数 private boolean isClear = false; // クリア判定フラグ private boolean isGameOver = false; // ゲームオーバー判定フラグ private boolean isDown = false; // ブロック落下中判定フラグ private boolean isNextPhase = false; // 場面切り替え中判定フラグ private boolean isStart = false; // 処理開始判定フラグ private int bgMaskCnt = 0; // 場面切り替え処理カウンタ private MediaTracker mTracker; // メディアトラッカー // 仮想GRAM変数 private int gram[][] = new int[bgCellXNum][bgCellYNum]; // 差分判定用仮想GRAM変数 private int gramOld[][] = new int[bgCellXNum][bgCellYNum]; // コンストラクタ public Sg() { } public void init() { // スクリーンサイズ計算 bgWidth = bgCellXNum * bgCellSize; bgHeight = bgCellYNum * bgCellSize; // オフスクリーン作成 try { bgBuff = createImage(bgWidth, bgHeight); } catch (Exception e) {} // イベントリスナ登録 this.addMouseListener(this); // BG画面作成 bg = bgBuff.getGraphics(); // 仮想GRAM初期化 for(int y=0; y=1; y--) { for(int x=1; x<=fldWidth; x++) { // 落下処理 if(field[x][y] != 0 && field[x][y+1] == 0) { field[x][y+1] = field[x][y]; field[x][y] = 0; isDown = true; } } } for(int x=1; x<=fldWidth; x++) { int chk = 0; // 縦1列チェック for(int y=1; y<=fldHeight; y++) { if(field[x][y] != 0) { chk = 1; } } // 左詰め処理 if(chk == 0) { for(int y=1; y<=fldHeight; y++) { if(field[x+1][y] != 0) { field[x][y] = field[x+1][y]; field[x+1][y] = 0; isDown = true; } } } } } // Field上クリック時処理 void clickField(int clX, int clY) { int eraseNum = 0; for(int y=1; y<=fldHeight; y++) { for(int x=1; x<=fldWidth; x++) { fieldChecked[x][y] = 0; fieldErased[x][y] = 0; } } chkField(clX, clY); // 消去済みfield情報をfieldに反映 for(int y=1; y<=fldHeight; y++) { for(int x=1; x<=fldWidth; x++) { if(fieldErased[x][y] == 1) { field[x][y] = 0; eraseNum++; } } } score += eraseNum * eraseNum * colorNum / 8; drawScore(); if(eraseNum > maxEraseNum) { maxEraseNum = eraseNum; } if(eraseNum > 0) { totalEraseNum += eraseNum; eraseCnt++; } } // ブロック消去判定 void chkField(int x, int y) { int col; int colU, colD, colR, colL; int chkU, chkD, chkR, chkL; // チェック対象のカラーコード取得 col = field[x][y]; // チェック対象がブロック以外ならreturn if(col == 0) { return; } // チェック済みフラグセット fieldChecked[x][y] = 1; // チェック対象周辺カラーコード取得 colU = field[x][y-1]; colD = field[x][y+1]; colR = field[x+1][y]; colL = field[x-1][y]; // 周りが全て他の色ならばreturn if(col != colU && col != colD && col != colR && col != colL) { return; } // 消去可能フラグセット fieldErased[x][y] = 1; // 周辺のチェック済みフラグ取得 chkU = fieldChecked[x][y-1]; chkD = fieldChecked[x][y+1]; chkR = fieldChecked[x+1][y]; chkL = fieldChecked[x-1][y]; // 上下左右のチェック実施 if(chkU == 0 && col == colU) { chkField(x, y-1); } if(chkD == 0 && col == colD) { chkField(x, y+1); } if(chkR == 0 && col == colR) { chkField(x+1, y); } if(chkL == 0 && col == colL) { chkField(x-1, y); } } // スコア表示 void drawScore() { drawStr(0, fldPosY+fldHeight+1, "Score:"); String str = Integer.toString(score); str = "00000"+str; String str2 = str.substring(str.length() - 5); drawStr(6, fldPosY+fldHeight+1, str2); } // Phase表示 void drawPhase() { drawStr(12, fldPosY+fldHeight+1, "Phase:"); String str = Integer.toString(phase); str = "00"+str; String str2 = str.substring(str.length() - 2); drawStr(18, fldPosY+fldHeight+1, str2); } // ギブアップボタン表示 void drawGiveUp() { gram[bgCellXNum-3][bgCellYNum-1] = 0xf8; gram[bgCellXNum-2][bgCellYNum-1] = 0xf9; gram[bgCellXNum-1][bgCellYNum-1] = 0xfa; } // 枠表示 void drawFrame(int posX, int posY, int wd, int ht) { gram[posX][posY] = 0xf0; // 左上角表示 gram[posX+wd-1][posY] = 0xf1; // 右上角表示 gram[posX][posY+ht-1] = 0xf2; // 左下角表示 gram[posX+wd-1][posY+ht-1] = 0xf3; // 右下角表示 for(int x=posX+1; x<(posX+wd-1); x++) { gram[x][posY] = 0xf4; // 上ライン表示 gram[x][posY+ht-1] = 0xf4; // 下ライン表示 } for(int y=posY+1; y<(posY+ht-1); y++) { gram[posX][y] = 0xf5; // 左ライン表示 gram[posX+wd-1][y] = 0xf5; // 右ライン表示 } } // 枠塗りつぶし表示 void fillFrame(int posX, int posY, int wd, int ht) { drawFrame(posX, posY, wd, ht); // 枠表示 for(int y=posY+1; y<(posY+ht-1); y++) { for(int x=posX+1; x<(posX+wd-1); x++) { gram[x][y] = 0x20; // 塗りつぶし表示 } } } // メッセージ枠表示 void drawMsgFrame(int posX, int posY, int wd, int ht) { for(int x=posX; x<(posX+wd); x++) { if((x & 1) == 0) { gram[x][posY] = 0xf6; // 上ライン表示 gram[x][posY+ht-1] = 0xf6; // 下ライン表示 } else { gram[x][posY] = 0xf7; // 上ライン表示 gram[x][posY+ht-1] = 0xf7; // 下ライン表示 } } for(int y=posY+1; y<(posY+ht-1); y++) { for(int x=posX; x<(posX+wd); x++) { gram[x][y] = 0x20; // 塗りつぶし表示 } } } // 画面指定位置文字列描画 void drawStr(int x, int y, String str) { for(int i=0; i=1 && fldX<=fldWidth && fldY>=1 && fldY<=fldHeight) { clickField(fldX, fldY); } // GiveUpボタンのクリック if((cellY == bgCellYNum-1) && (cellX >= bgCellXNum-3) && (cellX <= bgCellXNum-1)) { score = 0; phase = 1; colorNum = initColNum; isNextPhase = true; } } // クリア時クリック処理 if(isClear) { colorNum++; phase++; if(colorNum > 5) { colorNum = initColNum; } isNextPhase = true; } // ゲームオーバー時クリック処理 if(isGameOver) { score = 0; phase = 1; colorNum = initColNum; isNextPhase = true; } } // マウスカーソル出る public void mouseExited(MouseEvent e) { } }