diff --git a/GameCanvas.java b/GameCanvas.java new file mode 100644 index 0000000..5f5aff0 --- /dev/null +++ b/GameCanvas.java @@ -0,0 +1,193 @@ +// 导入必要的包 +package view; + +// 引入颜色类,字体类,绘图类,随机数生成器,Swing的面板类,边界类,以及模型层的Block和Box类 +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.util.Random; +import javax.swing.JPanel; +import javax.swing.border.EtchedBorder; +import model.Block; +import model.Box; + +// 定义GameCanvas类,继承自JPanel +public class GameCanvas extends JPanel { + // 定义成员变量,包括背景色、前景色、行数、列数、游戏分数、分数更新阈值、游戏结束标记、暂停标记、方格数组、方格宽高 + private Color backColor = Color.GRAY, frontColor = Color.orange; + private int rows, cols, score = 0, scoreForLevelUpdate = 0; + private Box[][] boxes; + private int boxWidth = 25, boxHeight = 25; + private boolean gameOver = false; + public boolean pau = false; + + // 构造函数,初始化画布的行数和列数 + public GameCanvas(int rows, int cols) { + // 初始化成员变量 + this.rows = rows; + this.cols = cols; + this.setOpaque(false); + // 创建方格数组 + boxes = new Box[rows][cols]; + // 循环遍历方格数组,初始化每个方格为无色 + for (int i = 0; i < boxes.length; i++) { + for (int j = 0; j < boxes[i].length; j++) { + boxes[i][j] = new Box(false); + } + } + // 设置画布的位置和尺寸,以及边框样式 + setBounds(0, 0, 300, 500); + setBorder(new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140))); + } + + // 构造函数,允许传入背景色和前景色 + public GameCanvas(int rows, int cols, Color backColor, Color frontColor) { + // 调用另一个构造函数初始化行数和列数 + this(rows, cols); + // 设置背景色和前景色 + this.backColor = backColor; + this.frontColor = frontColor; + } + + // 设置背景色的方法 + public void setBackgroundColor(Color backColor) { + this.backColor = backColor; + } + + // 获取背景色的方法 + public Color getBackgroundColor() { + return backColor; + } + + // 设置前景色(方块颜色)的方法 + public void setBlockColor(Color frontColor) { + this.frontColor = frontColor; + } + + // 获取前景色(方块颜色)的方法 + public Color getBlockColor() { + return frontColor; + } + + // 获取画布的行数的方法 + public int getRows() { + return rows; + } + + // 获取画布的列数的方法 + public int getCols() { + return cols; + } + + // 获取游戏分数的方法 + public int getScore() { + return score; + } + + // 获取分数更新阈值的方法 + public int getScoreForLevelUpdate() { + return scoreForLevelUpdate; + } + + // 获取画布上指定位置的方格引用的方法 + public Box getBox(int row, int col) { + // 检查索引是否合法,否则返回null + if (row < 0 || row > boxes.length - 1 || col < 0 || col > boxes[0].length - 1) + return null; + // 返回指定位置的方格引用 + return boxes[row][col]; + } + + // 消行方法,当一行被填满时调用,将该行上方的行下移覆盖已消去的行 + public void delete(int row) { + // 从待消去的行开始向上遍历,直到第一行 + for (int i = row; i > 0; i--) { + // 将当前行复制为上一行的状态 + for (int j = 0; j < 12; j++) + boxes[i][j] = new Box(boxes[i - 1][j].isColorBox()); + } + // 重新绘制画布 + repaint(); + } + + // 自动上涨方法,在游戏过程中调用,模拟方格从下方升起 + public void addRow() { + // 遍历画布的行,除了最后一行 + for (int i = 0; i < 19; i++) { + // 将当前行复制为下一行的状态 + for (int j = 0; j < 12; j++) { + boxes[i][j] = new Box(boxes[i + 1][j].isColorBox()); + } + } + // 随机填充最后一行的状态 + for (int i = 0; i < 12; i++) { + int a = (int) (Math.random() * 2); + if (a == 1) + boxes[19][i] = new Box(true); + else + boxes[19][i] = new Box(false); + } + // 重新绘制画布 + repaint(); + } + + // 重写paint方法,用于绘制游戏界面 + public void paint(Graphics g) { + // 调用父类的paint方法 + super.paint(g); + // 如果游戏结束,绘制游戏结束的信息 + if (gameOver) { + paintGame(g); + g.setColor(Color.RED); + g.setFont(new Font("黑体", Font.BOLD, 80)); + g.drawString("GAME", 50, 220); + g.drawString("OVER", 50, 310); + } else if (pau == true) { + // 如果游戏暂停,绘制游戏暂停的信息 + paintGame(g); + g.setColor(Color.BLUE); + g.setFont(new Font("华文行楷", Font.BOLD, 40)); + g.drawString("暂停", 100, 200); + g.drawString("按C继续!", 60, 310); + } else { + // 如果游戏进行中,绘制游戏界面 + paintGame(g); + } + } + + // 绘制游戏界面的方法 + public void paintGame(Graphics g) { + // 设置画布颜色 + g.setColor(Color.BLUE); + // 绘制画布边框 + g.draw3DRect(0, 0, 298, 498, true); + // 设置方块颜色 + g.setColor(frontColor); + // 遍历画布上的所有方格 + for (int i = 0; i < boxes.length; i++) { + for (int j = 0; j < boxes[i].length; j++) { + // 如果方格有颜色,则绘制方格 + if (boxes[i][j].isColorBox() == true) { + g.setColor(frontColor); + g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight, true); + } + } + } + } + + // 设置游戏结束标记的方法 + public boolean setGameOver(boolean go) { + gameOver = go; + return gameOver; + } + + // 重置画布的方法,将所有方格设置为无色 + public void reset() { + for (int i = 0; i < boxes.length; i++) { + for (int j = 0; j < boxes[i].length; j++) + boxes[i][j].setColor(false); + } + // 重新绘制画布 + repaint(); + } +}