简易完整版Java的俄罗斯方块源码加注释
时间: 2023-08-05 19:04:59 浏览: 130
好的,以下是简易完整版Java的俄罗斯方块源码加注释:
```java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
// 方块类
class Block {
// 方块的形状
private ArrayList<Point> shape;
// 方块的颜色
private Color color;
// 方块的位置
private int x, y;
// 构造函数,随机生成方块的形状和颜色
public Block() {
Random rand = new Random();
// 随机生成方块的形状
shape = new ArrayList<Point>();
int type = rand.nextInt(7);
switch (type) {
case 0: // I型
shape.add(new Point(0, 0));
shape.add(new Point(1, 0));
shape.add(new Point(2, 0));
shape.add(new Point(3, 0));
color = Color.CYAN;
break;
case 1: // J型
shape.add(new Point(0, 0));
shape.add(new Point(0, 1));
shape.add(new Point(1, 1));
shape.add(new Point(2, 1));
color = Color.BLUE;
break;
case 2: // L型
shape.add(new Point(2, 0));
shape.add(new Point(0, 1));
shape.add(new Point(1, 1));
shape.add(new Point(2, 1));
color = Color.ORANGE;
break;
case 3: // O型
shape.add(new Point(0, 0));
shape.add(new Point(1, 0));
shape.add(new Point(0, 1));
shape.add(new Point(1, 1));
color = Color.YELLOW;
break;
case 4: // S型
shape.add(new Point(1, 0));
shape.add(new Point(2, 0));
shape.add(new Point(0, 1));
shape.add(new Point(1, 1));
color = Color.GREEN;
break;
case 5: // T型
shape.add(new Point(1, 0));
shape.add(new Point(0, 1));
shape.add(new Point(1, 1));
shape.add(new Point(2, 1));
color = Color.MAGENTA;
break;
case 6: // Z型
shape.add(new Point(0, 0));
shape.add(new Point(1, 0));
shape.add(new Point(1, 1));
shape.add(new Point(2, 1));
color = Color.RED;
break;
}
// 随机生成方块的位置
x = rand.nextInt(10);
y = -2;
}
// 获取方块的形状
public ArrayList<Point> getShape() {
return shape;
}
// 获取方块的颜色
public Color getColor() {
return color;
}
// 获取方块的位置
public int getX() {
return x;
}
public int getY() {
return y;
}
// 移动方块
public void move(int dx, int dy) {
x += dx;
y += dy;
}
// 旋转方块
public void rotate() {
for (Point p : shape) {
int x = p.x;
int y = p.y;
p.x = y;
p.y = -x;
}
}
}
// 俄罗斯方块游戏类
public class Tetris extends JPanel implements Runnable {
// 方块的大小
private static final int BLOCK_SIZE = 30;
// 游戏区域的宽度和高度
private static final int BOARD_WIDTH = 10;
private static final int BOARD_HEIGHT = 20;
// 游戏区域的左上角坐标
private static final int BOARD_X = 150;
private static final int BOARD_Y = 50;
// 游戏的状态
private boolean isRunning = true;
private boolean isPaused = false;
private boolean isGameOver = false;
// 当前的方块和下一个方块
private Block currentBlock, nextBlock;
// 游戏区域的方块矩阵
private Color[][] board = new Color[BOARD_WIDTH][BOARD_HEIGHT];
// 随机数生成器
private Random rand = new Random();
// 构造函数
public Tetris() {
// 初始化游戏区域的方块矩阵
for (int i = 0; i < BOARD_WIDTH; i++) {
for (int j = 0; j < BOARD_HEIGHT; j++) {
board[i][j] = Color.WHITE;
}
}
// 预先生成下一个方块
nextBlock = new Block();
}
// 绘制游戏区域
private void drawBoard(Graphics g) {
// 绘制游戏区域的边框
g.setColor(Color.GRAY);
g.drawRect(BOARD_X - 1, BOARD_Y - 1, BLOCK_SIZE * BOARD_WIDTH + 2, BLOCK_SIZE * BOARD_HEIGHT + 2);
// 绘制游戏区域的方块
for (int i = 0; i < BOARD_WIDTH; i++) {
for (int j = 0; j < BOARD_HEIGHT; j++) {
Color c = board[i][j];
if (c != Color.WHITE) {
g.setColor(c);
g.fillRect(BOARD_X + i * BLOCK_SIZE, BOARD_Y + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
g.drawRect(BOARD_X + i * BLOCK_SIZE, BOARD_Y + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}
}
}
}
// 绘制当前方块和下一个方块
private void drawBlock(Graphics g) {
// 绘制当前方块
ArrayList<Point> shape = currentBlock.getShape();
Color c = currentBlock.getColor();
for (Point p : shape) {
int x = currentBlock.getX() + p.x;
int y = currentBlock.getY() + p.y;
g.setColor(c);
g.fillRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
g.drawRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}
// 绘制下一个方块
shape = nextBlock.getShape();
c = nextBlock.getColor();
for (Point p : shape) {
int x = BOARD_WIDTH + 2 + p.x;
int y = 2 + p.y;
g.setColor(c);
g.fillRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
g.drawRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}
}
// 是否可以移动方块
private boolean canMove(Block block, int dx, int dy) {
ArrayList<Point> shape = block.getShape();
for (Point p : shape) {
int x = block.getX() + p.x + dx;
int y = block.getY() + p.y + dy;
if (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT || board[x][y] != Color.WHITE) {
return false;
}
}
return true;
}
// 将方块放到游戏区域中
private void placeBlock() {
ArrayList<Point> shape = currentBlock.getShape();
Color c = currentBlock.getColor();
for (Point p : shape) {
int x = currentBlock.getX() + p.x;
int y = currentBlock.getY() + p.y;
board[x][y] = c;
}
}
// 消除可以消除的行
private void eliminateLines() {
for (int j = BOARD_HEIGHT - 1; j >= 0; j--) {
boolean isFull = true;
for (int i = 0; i < BOARD_WIDTH; i++) {
if (board[i][j] == Color.WHITE) {
isFull = false;
break;
}
}
if (isFull) {
// 将上面的所有行向下移动一行
for (int k = j; k > 0; k--) {
for (int i = 0; i < BOARD_WIDTH; i++) {
board[i][k] = board[i][k - 1];
}
}
// 最上面一行变成空白
for (int i = 0; i < BOARD_WIDTH; i++) {
board[i][0] = Color.WHITE;
}
// 分数加一
score++;
// 继续判断当前行是否可以消除
j++;
}
}
}
// 游戏结束
private void gameOver() {
isGameOver = true;
repaint();
}
// 游戏主循环
public void run() {
// 不断地移动方块下落,直到游戏结束
while (isRunning) {
if (!isPaused) {
// 检查是否可以移动当前方块
if (canMove(currentBlock, 0, 1)) {
currentBlock.move(0, 1);
} else {
// 将当前方块放到游戏区域中
placeBlock();
// 消除可以消除的行
eliminateLines();
// 检查游戏是否结束
if (currentBlock.getY() < 0) {
gameOver();
break;
}
// 生成下一个方块,并将其设置为当前方块
currentBlock = nextBlock;
nextBlock = new Block();
}
repaint();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 绘制游戏界面
public void paint(Graphics g) {
super.paint(g);
// 绘制游戏区域
drawBoard(g);
// 绘制当前方块和下一个方块
if (!isGameOver) {
drawBlock(g);
} else {
// 游戏结束时显示 Game Over
g.setColor(Color.RED);
g.drawString("Game Over", BOARD_X + BLOCK_SIZE * BOARD_WIDTH / 2 - 30, BOARD_Y + BLOCK_SIZE * BOARD_HEIGHT / 2);
}
// 绘制分数
g.setColor(Color.BLACK);
g.drawString("Score: " + score, BOARD_X + BLOCK_SIZE * BOARD_WIDTH + 20, BOARD_Y + BLOCK_SIZE * 4);
}
// 暂停游戏
public void pause() {
isPaused = true;
}
// 恢复游戏
public void resume() {
isPaused = false;
}
// 开始游戏
public void start() {
// 生成第一个方块
currentBlock = new Block();
// 启动游戏主循环线程
Thread t = new Thread(this);
t.start();
}
// 分数
private int score = 0;
// 主函数
public static void main(String[] args) {
JFrame frame = new JFrame("俄罗斯方块");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 600);
frame.setLocationRelativeTo(null);
Tetris tetris = new Tetris();
frame.add(tetris);
frame.addKeyListener(new TetrisKeyListener(tetris));
frame.setVisible(true);
tetris.start();
}
}
// 键盘监听器
class TetrisKeyListener implements java.awt.event.KeyListener {
private Tetris tetris;
public TetrisKeyListener(Tetris tetris) {
this.tetris = tetris;
}
public void keyPressed(java.awt.event.KeyEvent e) {
switch (e.getKeyCode()) {
case java.awt.event.KeyEvent.VK_LEFT:
if (tetris.canMove(tetris.currentBlock, -1, 0)) {
tetris.currentBlock.move(-1, 0);
}
break;
case java.awt.event.KeyEvent.VK_RIGHT:
if (tetris.canMove(tetris.currentBlock, 1, 0)) {
tetris.currentBlock.move(1, 0);
}
break;
case java.awt.event.KeyEvent.VK_DOWN:
if (tetris.canMove(tetris.currentBlock, 0, 1)) {
tetris.currentBlock.move(0, 1);
}
break;
case java.awt.event.KeyEvent.VK_UP:
Block temp = new Block();
temp.getShape().addAll(tetris.currentBlock.getShape());
temp.rotate();
if (tetris.canMove(temp, 0, 0)) {
tetris.currentBlock.rotate();
}
break;
case java.awt.event.KeyEvent.VK_SPACE:
tetris.pause();
String[] options = {"Resume", "Restart", "Quit"};
int choice = javax.swing.JOptionPane.showOptionDialog(tetris, "Game Paused", "Pause", javax.swing.JOptionPane.DEFAULT_OPTION,
javax.swing.JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
switch (choice) {
case 0:
tetris.resume();
break;
case 1:
tetris.restart();
break;
case 2:
System.exit(0);
break;
}
break;
}
tetris.repaint();
}
public void keyReleased(java.awt.event.KeyEvent e) {
}
public void keyTyped(java.awt.event.KeyEvent e) {
}
}
```
以上是简易完整版Java的俄罗斯方块源码加注释,希望对你有所帮助!
阅读全文