?? ersblock.java
字號:
/**
* File: ErsBlock.java
* User: 隋國丞
* Date: 2004.12.3
* Describe: 俄羅斯方塊的 Java 實現
*/
package ersblock;
/**
* 塊類,繼承自線程類(Thread)
* 由 4 * 4 個方格(ErsBox)構成一個塊,
* 控制塊的移動、下落、變形等
*/
class ErsBlock extends Thread {
/**
* 一個塊占的行數是4行
*/
public final static int BOXES_ROWS = 4;
/**
* 一個塊占的列數是4列
*/
public final static int BOXES_COLS = 4;
/**
* 讓升級變化平滑的因子,避免最后幾級之間的速度相差近一倍
*/
public final static int LEVEL_FLATNESS_GENE = 2;
/**
* 相近的兩級之間,塊每下落一行的時間差別為多少(毫秒)
*/
public final static int BETWEEN_LEVELS_DEGRESS_TIME = 50;
/**
* 方塊的樣式數目為7
*/
private final static int BLOCK_KIND_NUMBER = 7;
/**
* 每一個樣式的方塊的反轉狀態種類為4
*/
private final static int BLOCK_STATUS_NUMBER = 4;
/**
* 分別對應對7種模型的28種狀態
*/
public final static int[][] STYLES = {// 共28種狀態
{0x0f00, 0x4444, 0x0f00, 0x4444}, // 長條型的四種狀態
{0x04e0, 0x0464, 0x00e4, 0x04c4}, // 'T'型的四種狀態
{0x4620, 0x6c00, 0x4620, 0x6c00}, // 反'Z'型的四種狀態
{0x2640, 0xc600, 0x2640, 0xc600}, // 'Z'型的四種狀態
{0x6220, 0x1700, 0x2230, 0x0740}, // '7'型的四種狀態
{0x6440, 0x0e20, 0x44c0, 0x8e00}, // 反'7'型的四種狀態
{0x0660, 0x0660, 0x0660, 0x0660}, // 方塊的四種狀態
};
private GameCanvas canvas;
private ErsBox[][] boxes = new ErsBox[BOXES_ROWS][BOXES_COLS];
private int style, y, x, level;
private boolean pausing = false, moving = true;
/**
* 構造函數,產生一個特定的塊
* @param style 塊的樣式,對應STYLES的28個值中的一個
* @param y 起始位置,左上角在canvas中的坐標行
* @param x 起始位置,左上角在canvas中的坐標列
* @param level 游戲等級,控制塊的下落速度
* @param canvas 畫板
*/
public ErsBlock(int style, int y, int x, int level, GameCanvas canvas) {
this.style = style;
this.y = y;
this.x = x;
this.level = level;
this.canvas = canvas;
int key = 0x8000;
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
boolean isColor = ((style & key) != 0);
boxes[i][j] = new ErsBox(isColor);
key >>= 1;
}
}
display();
}
/**
* 線程類的run()函數覆蓋,下落塊,直到塊不能再下落
*/
public void run() {
while (moving) {
try {
sleep(BETWEEN_LEVELS_DEGRESS_TIME
* (ErsBlocksGame.MAX_LEVEL - level + LEVEL_FLATNESS_GENE));
} catch (InterruptedException ie) {
ie.printStackTrace();
}
//后邊的moving是表示在等待的100毫秒間,moving沒被改變
if (!pausing) moving = (moveTo(y + 1, x) && moving);
}
}
/**
* 塊向左移動一格
*/
public void moveLeft() {
moveTo(y, x - 1);
}
/**
* 塊向右移動一格
*/
public void moveRight() {
moveTo(y, x + 1);
}
/**
* 塊向下落一格
*/
public void moveDown() {
moveTo(y + 1, x);
}
/**
* 塊變型
*/
public void turnNext() {
for (int i = 0; i < BLOCK_KIND_NUMBER; i++) {
for (int j = 0; j < BLOCK_STATUS_NUMBER; j++) {
if (STYLES[i][j] == style) {
int newStyle = STYLES[i][(j + 1) % BLOCK_STATUS_NUMBER];
turnTo(newStyle);
return;
}
}
}
}
/**
* 暫停塊的下落,對應游戲暫停
*/
public void pauseMove() {
pausing = true;
}
/**
* 繼續塊的下落,對應游戲繼續
*/
public void resumeMove() {
pausing = false;
}
/**
* 停止塊的下落,對應游戲停止
*/
public void stopMove() {
moving = false;
}
/**
* 將當前塊從畫布的對應位置移除,要等到下次重畫畫布時才能反映出來
*/
private void earse() {
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(i + y, j + x);
if (box == null) continue;
box.setColor(false);
}
}
}
}
/**
* 讓當前塊放置在畫布的對應位置上,要等到下次重畫畫布時才能看見
*/
private void display() {
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(y + i, x + j);
if (box == null) continue;
box.setColor(true);
}
}
}
}
/**
* 當前塊能否移動到newRow/newCol所指定的位置
* @param newRow int, 目的地所在行
* @param newCol int, 目的地所在列
* @return boolean, true-能移動,false-不能
*/
private boolean isMoveAble(int newRow, int newCol) {
earse();
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(newRow + i, newCol + j);
if (box == null || (box.isColorBox())) {
display();
return false;
}
}
}
}
display();
return true;
}
/**
* 將當前畫移動到newRow/newCol所指定的位置
* @param newRow int, 目的地所在行
* @param newCol int, 目的地所在列
* @return boolean, true-移動成功,false-移動失敗
*/
private synchronized boolean moveTo(int newRow, int newCol) {
if (!isMoveAble(newRow, newCol) || !moving) return false;
earse();
y = newRow;
x = newCol;
display();
canvas.repaint();
return true;
}
/**
* 當前塊能否變成newStyle所指定的塊樣式,主要是要考慮
* 邊界以及被其它塊擋住、不能移動的情況
* @param newStyle int,希望改變的塊樣式,對應STYLES的28個值中的一個
* @return boolean,true-能改變,false-不能改變
*/
private boolean isTurnAble(int newStyle) {
int key = 0x8000;
earse();
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
if ((newStyle & key) != 0) {
ErsBox box = canvas.getBox(y + i, x + j);
if (box == null || box.isColorBox()) {
display();
return false;
}
}
key >>= 1;
}
}
display();
return true;
}
/**
* 將當前塊變成newStyle所指定的塊樣式
* @param newStyle int,將要改變成的塊樣式,對應STYLES的28個值中的一個
* @return boolean,true-改變成功,false-改變失敗
*/
private boolean turnTo(int newStyle) {
if (!isTurnAble(newStyle) || !moving) return false;
earse();
int key = 0x8000;
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
boolean isColor = ((newStyle & key) != 0);
boxes[i][j].setColor(isColor);
key >>= 1;
}
}
style = newStyle;
display();
canvas.repaint();
return true;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -