|
|
@ -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();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|