diff --git a/Tetris/bin/.gitignore b/Tetris/bin/.gitignore new file mode 100644 index 0000000..bad4aa0 --- /dev/null +++ b/Tetris/bin/.gitignore @@ -0,0 +1 @@ +/tetris/ diff --git a/Tetris/bin/tetris/Cell.class b/Tetris/bin/tetris/Cell.class index 9b6b82a..c87a654 100644 Binary files a/Tetris/bin/tetris/Cell.class and b/Tetris/bin/tetris/Cell.class differ diff --git a/Tetris/bin/tetris/TetrisFrame.class b/Tetris/bin/tetris/TetrisFrame.class index 321f9f1..8ffe5df 100644 Binary files a/Tetris/bin/tetris/TetrisFrame.class and b/Tetris/bin/tetris/TetrisFrame.class differ diff --git a/Tetris/bin/tetris/TetrisPane$DropExecution.class b/Tetris/bin/tetris/TetrisPane$DropExecution.class index 377674d..d05cfa9 100644 Binary files a/Tetris/bin/tetris/TetrisPane$DropExecution.class and b/Tetris/bin/tetris/TetrisPane$DropExecution.class differ diff --git a/Tetris/bin/tetris/TetrisPane$IShaped.class b/Tetris/bin/tetris/TetrisPane$IShaped.class index e5fa4bf..46a3116 100644 Binary files a/Tetris/bin/tetris/TetrisPane$IShaped.class and b/Tetris/bin/tetris/TetrisPane$IShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$JShaped.class b/Tetris/bin/tetris/TetrisPane$JShaped.class index 3ab86e2..a5a6f9e 100644 Binary files a/Tetris/bin/tetris/TetrisPane$JShaped.class and b/Tetris/bin/tetris/TetrisPane$JShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$KeyControl.class b/Tetris/bin/tetris/TetrisPane$KeyControl.class index a8c5be7..f108b37 100644 Binary files a/Tetris/bin/tetris/TetrisPane$KeyControl.class and b/Tetris/bin/tetris/TetrisPane$KeyControl.class differ diff --git a/Tetris/bin/tetris/TetrisPane$LShaped.class b/Tetris/bin/tetris/TetrisPane$LShaped.class index b908e9f..601b5c8 100644 Binary files a/Tetris/bin/tetris/TetrisPane$LShaped.class and b/Tetris/bin/tetris/TetrisPane$LShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$OShaped.class b/Tetris/bin/tetris/TetrisPane$OShaped.class index d69f0e7..f86e497 100644 Binary files a/Tetris/bin/tetris/TetrisPane$OShaped.class and b/Tetris/bin/tetris/TetrisPane$OShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$SShaped.class b/Tetris/bin/tetris/TetrisPane$SShaped.class index 611b505..151b904 100644 Binary files a/Tetris/bin/tetris/TetrisPane$SShaped.class and b/Tetris/bin/tetris/TetrisPane$SShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$TShaped.class b/Tetris/bin/tetris/TetrisPane$TShaped.class index e6d649a..4439378 100644 Binary files a/Tetris/bin/tetris/TetrisPane$TShaped.class and b/Tetris/bin/tetris/TetrisPane$TShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane$ZShaped.class b/Tetris/bin/tetris/TetrisPane$ZShaped.class index 15fe14c..c34ad0c 100644 Binary files a/Tetris/bin/tetris/TetrisPane$ZShaped.class and b/Tetris/bin/tetris/TetrisPane$ZShaped.class differ diff --git a/Tetris/bin/tetris/TetrisPane.class b/Tetris/bin/tetris/TetrisPane.class index 545d304..994ae63 100644 Binary files a/Tetris/bin/tetris/TetrisPane.class and b/Tetris/bin/tetris/TetrisPane.class differ diff --git a/Tetris/bin/tetris/Tetromino.class b/Tetris/bin/tetris/Tetromino.class index 7238b44..91e7a8c 100644 Binary files a/Tetris/bin/tetris/Tetromino.class and b/Tetris/bin/tetris/Tetromino.class differ diff --git a/Tetris/src/tetris/Cell.java b/Tetris/src/tetris/Cell.java index da74660..4ff824e 100644 --- a/Tetris/src/tetris/Cell.java +++ b/Tetris/src/tetris/Cell.java @@ -3,14 +3,10 @@ import java.awt.Color; import java.awt.Graphics; -/** - * 网格类 - * @author Leslie Leung - */ public class Cell { - public static final int CELL_SIZE = 25; //一个网格的大小 + public static final int CELL_SIZE = 25; //a cell size - /* 格子的所有颜色 */ + /* the color of all the cells */ public static final int COLOR_CYAN = 0; public static final int COLOR_BLUE = 1; public static final int COLOR_GREEN = 2; @@ -19,18 +15,13 @@ public class Cell { public static final int COLOR_RED = 5; public static final int COLOR_PINK = 6; - private int color; //格子的颜色 - private int x; //横坐标 - private int y; //纵坐标 + private int color; //color of the cell + private int x; //x-axis + private int y; //y-axis + - /** - * 构造方法 - * @param x 横坐标 - * @param y 纵坐标 - * @param style 格子的样式,通过颜色来指定 - */ public Cell(int x, int y, int style) { - /* 根据传进来的样式决定格子的颜色 */ + /* choose the color with style */ switch(style) { case 0: color = COLOR_CYAN; break; case 1: color = COLOR_BLUE; break; @@ -45,42 +36,26 @@ public Cell(int x, int y, int style) { this.y = y; } - /** - * 设置该格子的横坐标 - * @param newX 新的横坐标 - */ + // Set the new coordinate public void setX(int newX) { x = newX; } - /** - * 设置该格子的纵坐标 - * @param newY 新的纵坐标 - */ + // Set the y-axis of the Cell public void setY(int newY) { y = newY; } - /** - * 获取该Cell的横坐标 - * @return 横坐标 - */ + // Get the x-axis of the Cell public int getX() { return x; } - /** - * 获取该Cell的纵坐标 - * @return 纵坐标 - */ + // Get the y-axis of the Cell public int getY() { return y; } - /** - * 绘图方法 - * @param g Graphics引用 - */ public void paintCell(Graphics g) { switch(color) { case COLOR_CYAN: g.setColor(Color.CYAN); diff --git a/Tetris/src/tetris/TetrisFrame.java b/Tetris/src/tetris/TetrisFrame.java index 38c1a6b..97003cc 100644 --- a/Tetris/src/tetris/TetrisFrame.java +++ b/Tetris/src/tetris/TetrisFrame.java @@ -4,32 +4,31 @@ import javax.swing.JFrame; import javax.swing.JLabel; -/** - * 框架类 - * @author Leslie Leung - */ public class TetrisFrame extends JFrame { - private TetrisPane tp; //俄罗斯方块主游戏场景类 - private JLabel mention; //游戏的提示信息 + private TetrisPane tp; + private JLabel mention; /** * 构造方法 */ public TetrisFrame() { - setSize(550, 600); //设置窗体大小 + setSize(550, 600); //set the window's size setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setLocationRelativeTo(null); //设置窗体于屏幕中央 - setTitle("Tetris"); //设置标题为Tetris - setResizable(false); //不允许窗体缩放 - setLayout(new FlowLayout()); //设置布局管理器 + setLocationRelativeTo(null); //set the window's location in the middle of screen + setTitle("Tetris"); //set the title + setResizable(false); //Don't allow to resize the window + setLayout(new FlowLayout()); //typesetting - tp = new TetrisPane(); //新建场景类对象 - mention = new JLabel("按A键逆时针转,按D顺时针转,按方向键控制向左、向右和向下的运动,按空格键硬下落"); + tp = new TetrisPane(); //new pane object + mention = new JLabel("Press 'A' to do Counterclockwise rotation\n" + + "Press 'D' to do Counterclockwise rotation\n" + + "The arrow keys can move the cell\n" + + "Press the space can let the cell fall quickly"); - add(mention); //把标签添加到主框架中 - add(tp); //把游戏主场景面板添加到主框架中 + add(mention); //add the label to the main frame + add(tp); //add the game - /* 注册键盘事件 */ + //keyboard event addKeyListener(tp.getInnerInstanceOfKeyControl()); tp.addKeyListener(tp.getInnerInstanceOfKeyControl()); diff --git a/Tetris/src/tetris/TetrisPane.java b/Tetris/src/tetris/TetrisPane.java index b13449e..d0f4f07 100644 --- a/Tetris/src/tetris/TetrisPane.java +++ b/Tetris/src/tetris/TetrisPane.java @@ -17,8 +17,8 @@ * @author Leslie Leung */ public class TetrisPane extends JPanel { - public static final int ROWS = 20; //整个场景的行数 - public static final int COLUMNS = 16; //整个场景的列数 + public static final int ROWS = 20; //the rows of scene + public static final int COLUMNS = 16; //the columns of scene /* 表示7种不同的四格方块 */ public static final int I_SHAPED = 0; @@ -29,20 +29,17 @@ public class TetrisPane extends JPanel { public static final int O_SHAPED = 5; public static final int J_SHAPED = 6; - public static final int KIND = 7; //表示四格方块有7个种类 - public static final int INIT_SPEED = 1000; //表示下落的初始速度 + public static final int KIND = 7; + public static final int INIT_SPEED = 1000; //fall down's speed - private static int randomNum = 0; //表示已生成的俄罗斯方块的数目 + private static int randomNum = 0; //the number of block that have been made private Random random; - private Tetromino currentTetromino; //表示当前的四格方块 - private Cell[][] wall; //表示墙,null表示方块内没对象 - private Timer autoDrop; //实现自动下落的计时器 - private KeyControl keyListener; //表示键盘事件监控变量 + private Tetromino currentTetromino; //the current block + private Cell[][] wall; + private Timer autoDrop; + private KeyControl keyListener; - /** - * 构造方法 - */ public TetrisPane() { setPreferredSize(new Dimension(COLUMNS * Cell.CELL_SIZE, ROWS * Cell.CELL_SIZE)); @@ -56,13 +53,10 @@ public TetrisPane() { autoDrop.schedule(new DropExecution(), (long)interval(), (long)interval()); } - /** - * 随机生成一个四格方块 - */ public void randomOne() { Tetromino tetromino = null; - /* 随机生成7种四格方块的其中一种 */ + // Product a tetris randomly switch(random.nextInt(KIND)) { case I_SHAPED: tetromino = new IShaped(); @@ -86,21 +80,17 @@ public void randomOne() { tetromino = new JShaped(); break; } - currentTetromino = tetromino; //当前的四格方块为生成的四格方块 + currentTetromino = tetromino; //the current block is the generated block randomNum ++; } - /** - * 判断玩家是否输了 - * @return true,输了;false,没输 - */ public boolean isGameOver() { - int x, y; //当前俄罗斯方块格子的横坐标和纵坐标 + int x, y; //The current block's coordinate for(int i = 0; i < getCurrentCells().length; i ++) { x = getCurrentCells()[i].getX(); y = getCurrentCells()[i].getY(); - if(isContain(x, y)) {//看其刚生成的位置是否已存在方块对象,存在的话,表示输了 + if(isContain(x, y)) {//if there is already a block at the position just be generated and it exists.then you lost return true; } } @@ -108,33 +98,23 @@ public boolean isGameOver() { return false; } - /** - * 每生成一个俄罗斯方块,通过改变TimerTask的时间间隔来加快下落速度 - * @return 时间间隔 - */ + //Each time a block is generated,the falling speed increased by changing the interval of the TimerTask public double interval() { return INIT_SPEED * Math.pow((double)39 / 38, 0 - randomNum); } - /** - * 返回KeyControl类的实例 - * @return KeyControl类实例 - */ public KeyControl getInnerInstanceOfKeyControl() { return keyListener; } - /** - * 内部类,用于实现俄罗斯方块的自动下落 - * @author Leslie Leung - */ + //For automatic drop of Tetris private class DropExecution extends TimerTask { @Override public void run() { // TODO Auto-generated method stub - if(isGameOver()) {//如果输了 - JOptionPane.showMessageDialog(null, "你输了"); + if(isGameOver()) { + JOptionPane.showMessageDialog(null, "You are lost"); autoDrop.cancel(); removeKeyListener(keyListener); return; @@ -143,9 +123,9 @@ public void run() { if(!isReachBottomEdge()) { currentTetromino.softDrop(); } else { - landIntoWall(); //把俄罗斯方块添加到墙上 - removeRows(); //如满行,删除行 - randomOne(); //马上新建一个俄罗斯方块 + landIntoWall(); //add the block to the wall + removeRows(); //If the row is full,then delete the row + randomOne(); //New a block autoDrop.cancel(); autoDrop = new Timer(); @@ -156,11 +136,8 @@ public void run() { } } - /** - * 把俄罗斯方块添加到墙上 - */ public void landIntoWall() { - int x, y; //定义俄罗斯方块不能移动后的横坐标和纵坐标 + int x, y; //The block's coordinate which can't move for(int i = 0; i < getCurrentCells().length; i ++) { x = getCurrentCells()[i].getX(); @@ -170,44 +147,40 @@ public void landIntoWall() { } } - /** - * 内部类,用于实现键盘的事件控制 - * @author Leslie Leung - */ private class KeyControl extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { - case KeyEvent.VK_LEFT: //往左移动 + case KeyEvent.VK_LEFT: //move left - if(!isReachLeftEdge()) {//当俄罗斯方块没到达左边界时,往左移动 + if(!isReachLeftEdge()) { currentTetromino.moveLeft(); repaint(); } break; - case KeyEvent.VK_RIGHT: //往右移动 + case KeyEvent.VK_RIGHT: //move right - if(!isReachRightEdge()) {//当俄罗斯方块没到达右边界时,往右移动 + if(!isReachRightEdge()) { currentTetromino.moveRight(); repaint(); } break; - case KeyEvent.VK_DOWN: //向下移动 + case KeyEvent.VK_DOWN: //move down - if(!isReachBottomEdge()) {//当俄罗斯方块没到达下边界时,往下移动 + if(!isReachBottomEdge()) { currentTetromino.softDrop(); repaint(); } break; - case KeyEvent.VK_SPACE: //硬下落 + case KeyEvent.VK_SPACE: //move quickly - hardDrop(); //硬下落 - landIntoWall(); //添加到墙中 - removeRows(); //如满行,删除行 + hardDrop(); + landIntoWall(); + removeRows(); randomOne(); autoDrop.cancel(); @@ -217,7 +190,7 @@ public void keyPressed(KeyEvent e) { repaint(); break; - case KeyEvent.VK_D: //顺时针转 + case KeyEvent.VK_D: if(!clockwiseRotateIsOutOfBounds() && !(currentTetromino instanceof OShaped)) {//俄罗斯方块没越界且其不为O形时,旋转 currentTetromino.clockwiseRotate(getAxis(), getRotateCells()); @@ -225,7 +198,7 @@ public void keyPressed(KeyEvent e) { } break; - case KeyEvent.VK_A: //逆时针转 + case KeyEvent.VK_A: if(!anticlockwiseRotateIsOutOfBounds() && !(currentTetromino instanceof OShaped)) {//俄罗斯方块没越界且其不为O形时,旋转 currentTetromino.anticlockwiseRotate(getAxis(), getRotateCells()); @@ -236,14 +209,8 @@ public void keyPressed(KeyEvent e) { } } - /** - * 内部类,I形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class IShaped extends Tetromino { - /** - * 构造方法 - */ + public IShaped() { cells = new Cell[4]; @@ -252,7 +219,6 @@ public IShaped() { cells[2] = new Cell(5, 0, Cell.COLOR_CYAN); cells[3] = new Cell(6, 0, Cell.COLOR_CYAN); - /* 设置旋转轴和要旋转的格子 */ setAxis(); setRotateCells(); @@ -260,14 +226,8 @@ public IShaped() { } } - /** - * 内部类,S形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class SShaped extends Tetromino { - /** - * 构造方法 - */ + public SShaped() { cells = new Cell[4]; @@ -276,7 +236,6 @@ public SShaped() { cells[2] = new Cell(3, 1, Cell.COLOR_BLUE); cells[3] = new Cell(4, 1, Cell.COLOR_BLUE); - /* 设置旋转轴和要旋转的格子 */ setAxis(); setRotateCells(); @@ -284,14 +243,8 @@ public SShaped() { } } - /** - * 内部类,T形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class TShaped extends Tetromino { - /** - * 构造方法 - */ + public TShaped() { cells = new Cell[4]; @@ -300,22 +253,15 @@ public TShaped() { cells[2] = new Cell(5, 0, Cell.COLOR_GREEN); cells[3] = new Cell(4, 1, Cell.COLOR_GREEN); - /* 设置旋转轴和要旋转的格子 */ setAxis(); setRotateCells(); repaint(); } } - - /** - * 内部类,Z形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ + private class ZShaped extends Tetromino { - /** - * 构造方法 - */ + public ZShaped() { cells = new Cell[4]; @@ -324,7 +270,6 @@ public ZShaped() { cells[0] = new Cell(4, 1, Cell.COLOR_ORANGE); cells[3] = new Cell(5, 1, Cell.COLOR_ORANGE); - /* 设置旋转轴和要旋转的格子 */ setAxis(); setRotateCells(); @@ -332,14 +277,8 @@ public ZShaped() { } } - /** - * 内部类,L形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class LShaped extends Tetromino { - /** - * 构造方法 - */ + public LShaped() { cells = new Cell[4]; @@ -347,8 +286,7 @@ public LShaped() { cells[0] = new Cell(4, 0, Cell.COLOR_PINK); cells[2] = new Cell(5, 0, Cell.COLOR_PINK); cells[3] = new Cell(3, 1, Cell.COLOR_PINK); - - /* 设置旋转轴和要旋转的格子 */ + setAxis(); setRotateCells(); @@ -356,14 +294,8 @@ public LShaped() { } } - /** - * 内部类,O形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class OShaped extends Tetromino { - /** - * 构造方法 - */ + public OShaped() { cells = new Cell[4]; @@ -371,8 +303,7 @@ public OShaped() { cells[1] = new Cell(5, 0, Cell.COLOR_RED); cells[2] = new Cell(4, 1, Cell.COLOR_RED); cells[3] = new Cell(5, 1, Cell.COLOR_RED); - - /* 设置旋转轴和要旋转的格子 */ + setAxis(); setRotateCells(); @@ -380,14 +311,8 @@ public OShaped() { } } - /** - * 内部类,J形的四格方块,继承了Tetromino类 - * @author Leslie Leung - */ private class JShaped extends Tetromino { - /** - * 构造方法 - */ + public JShaped() { cells = new Cell[4]; @@ -396,7 +321,6 @@ public JShaped() { cells[2] = new Cell(5, 0, Cell.COLOR_YELLOW); cells[3] = new Cell(5, 1, Cell.COLOR_YELLOW); - /* 设置旋转轴和要旋转的格子 */ setAxis(); setRotateCells(); @@ -404,43 +328,24 @@ public JShaped() { } } - /** - * 删除若干行 - */ public void removeRows() { for(int i = 0; i < getCurrentCells().length; i ++) { removeRow(getCurrentCells()[i].getY()); } } - /** - * 获取旋转轴 - * @return 旋转轴 - */ public Cell getAxis() { return currentTetromino.getAxis(); } - - /** - * 获取需要旋转的格子 - * @return 需要旋转的格子 - */ + public Cell[] getRotateCells() { return currentTetromino.getRotateCells(); } - - /** - * 获取当前俄罗斯方块的所有格子 - * @return 当前俄罗斯方块的所有格子 - */ + public Cell[] getCurrentCells() { return currentTetromino.getCells(); } - - /** - * 判断俄罗斯方块是否到达底部(包括是否到达面板底部和下一位置是否有方块) - * @return true,到达;false,没到达 - */ + public boolean isReachBottomEdge() { int oldY, newY, oldX; //定义格子旧的纵坐标、新的纵坐标和旧的横坐标 @@ -459,117 +364,95 @@ public boolean isReachBottomEdge() { } return false; } - - /** - * 判断俄罗斯方块是否到达左边界(包括是否超出面板左边界和下一位置是否出现与其他方块碰撞) - * @return true,已到达;false,没到达 - */ + public boolean isReachLeftEdge() { - int oldX, newX, oldY; //定义格子旧的横坐标、新的横坐标和旧的纵坐标 + int oldX, newX, oldY; for(int i = 0; i < getCurrentCells().length; i ++) { oldX = getCurrentCells()[i].getX(); newX = oldX - 1; oldY = getCurrentCells()[i].getY(); - if(oldX == 0 || isContain(newX, oldY)) {//到达左边界 + if(oldX == 0 || isContain(newX, oldY)) { return true; } - if(isContain(newX, oldY)) {//下一位置有方块 + if(isContain(newX, oldY)) { return true; } } return false; } - - /** - * 判断俄罗斯方块是否到达右边界(包括是否超出面板右边界和下一位置是否出现与其他方块碰撞) - * @return true,已到达;false,没到达 - */ + public boolean isReachRightEdge() { - int oldX, newX, oldY; //定义格子旧的横坐标、新的横坐标和旧的纵坐标 + int oldX, newX, oldY; for(int i = 0; i < getCurrentCells().length; i ++) { oldX = getCurrentCells()[i].getX(); newX = oldX + 1; oldY = getCurrentCells()[i].getY(); - if(oldX == COLUMNS - 1 || isContain(newX, oldY)) {//到达右边界 + if(oldX == COLUMNS - 1 || isContain(newX, oldY)) { return true; } - if(isContain(newX, oldY)) {//下一位置有方块 + if(isContain(newX, oldY)) { return true; } } return false; } - - /** - * 判断俄罗斯方块顺时针转后是否超出边界(包括是否超出面板边界和下一位置是否有方块) - * @return true,超出边界;false,没超边界 - */ + public boolean clockwiseRotateIsOutOfBounds() { - int oldX; //rotateCell的横坐标 - int oldY; //rotateCell的纵坐标 - int newX; //rotateCell旋转后的横坐标 - int newY; //rotateCell旋转后的纵坐标 + int oldX; + int oldY; + int newX; + int newY; for(int i = 0; i < 3; i ++) { oldX = getRotateCells()[i].getX(); oldY = getRotateCells()[i].getY(); - newX = getAxis().getX() - oldY + getAxis().getY(); //新横坐标计算算法 - newY = getAxis().getY() + oldX - getAxis().getX(); //新纵坐标计算算法 + newX = getAxis().getX() - oldY + getAxis().getY(); + newY = getAxis().getY() + oldX - getAxis().getX(); - if(newX < 0 || newY < 0 || newX > COLUMNS - 1 || newY > ROWS - 1) {//如果越界,返回true + if(newX < 0 || newY < 0 || newX > COLUMNS - 1 || newY > ROWS - 1) { return true; } - if(isContain(newX, newY)) {//如果越界,返回true + if(isContain(newX, newY)) { return true; } } return false; } - - /** - * 判断俄罗斯方块逆时针转后是否超出边界(包括是否超出面板边界和下一位置是否有方块) - * @return true,超出边界;false,没超边界 - */ + public boolean anticlockwiseRotateIsOutOfBounds() { - int oldX; //rotateCell的横坐标 - int oldY; //rotateCell的纵坐标 - int newX; //rotateCell旋转后的横坐标 - int newY; //rotateCell旋转后的纵坐标 + int oldX; + int oldY; + int newX; + int newY; for(int i = 0; i < 3; i ++) { oldX = getRotateCells()[i].getX(); oldY = getRotateCells()[i].getY(); - newX = getAxis().getX() - getAxis().getY() + oldY; //新横坐标计算算法 - newY = getAxis().getY() + getAxis().getX() - oldX; //新纵坐标计算算法 + newX = getAxis().getX() - getAxis().getY() + oldY; + newY = getAxis().getY() + getAxis().getX() - oldX; - if(newX < 0 || newY < 0 || newX > COLUMNS - 1 || newY > ROWS - 1) {//如果越界,返回true + if(newX < 0 || newY < 0 || newX > COLUMNS - 1 || newY > ROWS - 1) { return true; } - if(isContain(newX, newY)) {//如果越界,返回true + if(isContain(newX, newY)) { return true; } } return false; } - - /** - * 判断某个格子是否存在方块对象 - * @param x 横坐标 - * @param y 纵坐标 - * @return true,存在对象;false,不存在对象 - */ + public boolean isContain(int x, int y) { if(wall[y][x] == null) { return false; @@ -577,35 +460,27 @@ public boolean isContain(int x, int y) { return true; } } - - /** - * 实现俄罗斯方块的硬下落 - */ + public void hardDrop() { while(!isReachBottomEdge()) { currentTetromino.softDrop(); } } - - /** - * 消除单行 - * @param i 行的下标 - */ + public void removeRow(int i) { int oldY, newY; for(int j = 0; j < COLUMNS; j ++) { - if(wall[i][j] == null) {//如果其中一个方块没有填满,return + if(wall[i][j] == null) { return; } } - /* 消除行并把该行上面的方块往下移 */ for(int k = i; k >= 1; k --){ System.arraycopy(wall[k - 1], 0, wall[k], 0, COLUMNS); for(int m = 0; m < COLUMNS; m ++) { - if(wall[k][m] != null) {//对于不是空的对象,要重设其纵坐标 + if(wall[k][m] != null) { oldY = wall[k][m].getY(); newY = oldY + 1; wall[k][m].setY(newY); @@ -621,19 +496,17 @@ public void paint(Graphics g) { g.setColor(Color.BLACK); g.fillRect(0, 0, getBounds().width, getBounds().height); - /* 画墙 */ for(int i = 0; i < ROWS; i ++) { for(int j = 0; j < COLUMNS; j ++) { - if(wall[i][j] == null) {//某点的方块为空时 + if(wall[i][j] == null) { g.setColor(Color.WHITE); g.fillRect(j * Cell.CELL_SIZE + 1, i * Cell.CELL_SIZE + 1, Cell.CELL_SIZE - 2, Cell.CELL_SIZE - 2); - } else {//当方块不为空时 + } else { wall[i][j].paintCell(g); } } } - /* 画当前俄罗斯方块 */ for(int i = 0; i < getCurrentCells().length; i ++) { getCurrentCells()[i].paintCell(g); } diff --git a/Tetris/src/tetris/Tetromino.java b/Tetris/src/tetris/Tetromino.java index 422a5fd..d603e57 100644 --- a/Tetris/src/tetris/Tetromino.java +++ b/Tetris/src/tetris/Tetromino.java @@ -1,57 +1,43 @@ package tetris; -/** - * 四格方块类 - * @author Leslie Leung - */ public class Tetromino { - protected Cell[] cells; //用对象数组cells存储四格方块 - protected Cell axis; //旋转轴 - protected Cell[] rotateCells; //需要旋转的格子集合 + protected Cell[] cells; + protected Cell axis; + protected Cell[] rotateCells; - /** - * 实现四格方块逆时针转的算法 - * @param axis 旋转轴,以cells中下标为0的Cell为旋转轴 - * @param rotateCells 要旋转的格子的集合 - */ protected void anticlockwiseRotate(Cell axis, Cell[] rotateCells) { - int oldX; //用以表示传进来的rotateCell的横坐标 - int oldY; //用以表示传进来的rotateCell的纵坐标 - int newX; //用以表示传进来的rotateCell旋转后的横坐标 - int newY; //用以表示传进来的rotateCell旋转后的纵坐标 + int oldX; + int oldY; + int newX; + int newY; for(int i = 0; i < 3; i ++) { oldX = rotateCells[i].getX(); oldY = rotateCells[i].getY(); - newX = axis.getX() - axis.getY() + oldY; //新横坐标计算算法 - newY = axis.getY() + axis.getX() - oldX; //新纵坐标计算算法 + newX = axis.getX() - axis.getY() + oldY; + newY = axis.getY() + axis.getX() - oldX; - rotateCells[i].setX(newX); //重新设置目标格子的横坐标 - rotateCells[i].setY(newY); //重新设置目标格子的纵坐标 + rotateCells[i].setX(newX); + rotateCells[i].setY(newY); } } - /** - * 实现四格方块顺时针转的算法 - * @param axis 旋转轴,以cells中下标为0的Cell为旋转轴 - * @param rotateCells 要旋转的格子的集合 - */ protected void clockwiseRotate(Cell axis, Cell[] rotateCells) { - int oldX; //用以表示传进来的rotateCell的横坐标 - int oldY; //用以表示传进来的rotateCell的纵坐标 - int newX; //用以表示传进来的rotateCell旋转后的横坐标 - int newY; //用以表示传进来的rotateCell旋转后的纵坐标 + int oldX; + int oldY; + int newX; + int newY; for(int i = 0; i < 3; i ++) { oldX = rotateCells[i].getX(); oldY = rotateCells[i].getY(); - newX = axis.getX() - oldY + axis.getY(); //新横坐标计算算法 - newY = axis.getY() + oldX - axis.getX(); //新纵坐标计算算法 + newX = axis.getX() - oldY + axis.getY(); + newY = axis.getY() + oldX - axis.getX(); - rotateCells[i].setX(newX); //重新设置目标格子的横坐标 - rotateCells[i].setY(newY); //重新设置目标格子的纵坐标 + rotateCells[i].setX(newX); + rotateCells[i].setY(newY); } } @@ -59,10 +45,9 @@ protected void clockwiseRotate(Cell axis, Cell[] rotateCells) { * 实现四格方块的自动下落 */ protected void softDrop() { - int oldY; //某个格子下落前的纵坐标 - int newY; //某个格子下落后的纵坐标 + int oldY; + int newY; - /* 所有格子下移 */ for(int i = 0; i < cells.length; i ++) { oldY = cells[i].getY(); newY = oldY + 1; @@ -71,14 +56,10 @@ protected void softDrop() { } } - /** - * 实现四格方块左移的算法 - */ protected void moveLeft() { - int oldX; //某个格子左移前的横坐标 - int newX; //某个格子左移后的横坐标 + int oldX; + int newX; - /* 所有格子左移 */ for(int i = 0; i < cells.length; i ++) { oldX = cells[i].getX(); newX = oldX - 1; @@ -87,14 +68,10 @@ protected void moveLeft() { } } - /** - * 实现四格方块右移的算法 - */ protected void moveRight() { - int oldX; //某个格子右移前的横坐标 - int newX; //某个格子右移后的横坐标 + int oldX; + int newX; - /* 所有格子右移 */ for(int i = 0; i < cells.length; i ++) { oldX = cells[i].getX(); newX = oldX + 1; @@ -103,40 +80,22 @@ protected void moveRight() { } } - /** - * 返回四格方块的格子的集合 - * @return Cell的集合 - */ protected Cell[] getCells() { return cells; } - /** - * 获取旋转轴 - * @return 旋转轴 - */ protected Cell getAxis() { return axis; } - /** - * 获取需要旋转的目标格子的集合 - * @return 目标格子的集合 - */ protected Cell[] getRotateCells() { return rotateCells; } - /** - * 把cells[0]设置为旋转轴 - */ protected void setAxis() { axis = cells[0]; } - /** - * 新建长度为3的数组并把cells[1]、cells[2]、cells[3]添加到rotateCells中 - */ protected void setRotateCells() { rotateCells = new Cell[]{cells[1], cells[2], cells[3]}; }