前言
欢迎阅读本文,本文将介绍如何使用Java语言实现一个简易的俄罗斯方块游戏。俄罗斯方块,作为一种经典的益智游戏,不仅操作简单,而且富有娱乐性,深受很多玩家喜欢。通过本文,读者将了解到如何利用Java编程语言,结合GUI技术,实现一个基本的俄罗斯方块游戏。本文参考b站尚学堂博主代码,在此基础上有些改动。
代码解释
初始化游戏窗口
生成一个宽650,高850的窗口。
public void initWindow() {
//设置窗口大小
this.setSize(650, 850);
//设置窗口是否可见
this.setVisible(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置释放窗体(点击差号正常退出)
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗口大小不变
this.setResizable(false);
//设置标题
this.setTitle("俄罗斯方块");
}
初始化游戏界面
生成一个26*12的方格面板添加到窗口上
public void initGamePanel() {
JPanel game = new JPanel();
game.setLayout(new GridLayout(game_x, game_y, 1, 1));//水平竖直间距为1
//初始化面板
for (int i = 0; i < text.length; i++) {//两个for循环遍历游戏界面
for (int j = 0; j < text[i].length; j++) {
//设置文本域行列数
text[i][j] = new JTextArea(game_x, game_y);
//设置文本域背景颜色
text[i][j].setBackground(Color.WHITE);
//添加键盘监听事件
text[i][j].addKeyListener(this);
//初始化游戏边界
if (j == 0 || j == text[i].length - 1 || i == text.length - 1) {//左右下边界
text[i][j].setBackground(Color.RED);
data[i][j] = 1;
}
//设置文本区域不可编辑
text[i][j].setEditable(false);
//文本区域添加到主面板上
game.add(text[i][j]);
}
}
//添加到窗口中
this.setLayout(new BorderLayout());
this.add(game, BorderLayout.CENTER);
}
初始化游戏说明面板
在游戏窗口的左边和右边添加面板,左边是操作方法,右边是分数和状态。
public void initExplainPanel() {
//创建游戏的左右说明面板
JPanel left = new JPanel();
JPanel right = new JPanel();
//初始化说明面板
left.setLayout(new GridLayout(4, 1));
right.setLayout(new GridLayout(2, 1));
//在左说明面板添加声明文字
left.add(new JLabel("按空格键,方块翻转"));
left.add(new JLabel("按左键,方块左移"));
left.add(new JLabel("按右键,方块右移"));
left.add(new JLabel("按下键,方块下落"));
//设置标签的内容为黑色
label1.setForeground(Color.black);
//把状态和分数添加到右面板
right.add(label2);
right.add(label1);
//说明面板的添加
this.add(left, BorderLayout.WEST);
this.add(right, BorderLayout.EAST);
}
开始游戏的方法
来判断此时的游戏状态
public void begin() {
while (true) {
//判断游戏是否结束
if (!running) {
break;
}
//进行游戏
run();
}
//在标签位置显示游戏结束
label1.setText("游戏状态:游戏结束");
}
随机生成下落方块形状的方法
本文采用十六进制的方法在4*4的区域内表示方块。有方块的数字为1,无方块为0.
以下是所有可能的形状(变形都是经过顺逆时针旋转,无逆时针旋转)
public void Rect() {
Random random = new Random();
rect = allRect[random.nextInt(19)];
}
游戏运行的方法
调用多个方法来实现游戏。
public void run() {
Rect();
//方块下落位置
x = 0;
y = 5;
for (int i = 0; i < game_x; i++) {
try {
Thread.sleep(time);
if (zanting) {
i--;
} else {
//判断方块是否可以下落
if (!canFall(x, y)) {
//将data设置为1,表示有方块占用
changData(x,y);
//循环遍历4层,看是否有行可以消除
for (int j = x;j < x + 4;j++) {
int sum = 0;
for (int k = 1;k <= (game_y-2);k++) {
if (data[j][k] == 1) {
sum++;
}
}
//判断是否有一行可以被消除
if (sum == (game_y-2)) {
//消除j这一行
removeRow(j);
}
}
//判断游戏失败
for (int j = 1; j <= (game_y - 2); j++) {
if (data[3][j] == 1) {
running = false;
jieshu over=new jieshu();
break;
}
}
break;
} else {
//层数+1
x++;
//方块下落一格
fall(x, y);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
判断方块是否可以继续下落的方法
定义一个temp变量,从左上角开始遍历4*4区域,确定方块位置,看下一行是否有方块。
public boolean canFall(int m, int n) {//用0x8000的不断右移一位来与rect中存储的图形相比较
//定义一个变量
int temp = 0x8000;
//遍历4*4方格
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((temp & rect) != 0) {
//判断该位置下一行是否有方块
if (data[m + 1][n] == 1) {
return false;
}
}
n++;
temp >>= 1;
}
m++;
n = n - 4;
}
//可以下落
return true;
}
改变不可下降的方块的区域的值
将不可下降方块的区域的值设置为1.
public void changData(int m, int n) {//用0x8000的不断右移,来获取到每一个方块的位置,然后我么将他的data值设置为1
//定义一个变量
int temp = 0x8000;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((temp & rect) != 0) {
data[m][n] = 1;
}
n++;
temp >>= 1;
}
m++;
n = n - 4;
}
}
移除某一行,上面方块掉落的方法
经过判断某一行可以消除,通过该行以上的所有位置往下移动