You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 导入必要的包
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();
}
}