简单的JAVA游戏俄罗斯方块
1.初始化游戏窗口
public class Tetris extends JFrame {
public void initWindow() {
// 设置窗口大小
this.setSize(600, 850);
// 设置窗口可见
this.setVisible(true);
// 设置窗口居中
this.setLocationRelativeTo(null);
// 设置释放窗体
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口大小不可变
this.setResizable(true);
// 设置标题
this.setTitle("简单的Java俄罗斯方块");
}
public Tetris() {
initWindow();
}
public static void main(String[] args) {
Tetris t = new Tetris();
}
2.初始化游戏界面1
private static final int game_x=26;
private static final int game_y=12;
//文本域数组
JTextArea [][] text;
//每个格子的数组 二维数组
int[][]data;
//初始化游戏界面
public void initGamePanel() {
//定义一个Jpanel对象
JPanel game_main=new JPanel();
game_main.setLayout(new GridLayout(game_x,game_y,1,1));
}
//在构造方法初始化
public Tetris() {
text=new JTextArea[game_x][game_y];
data=new int[game_x][game_y];
initWindow();
}
3.初始化游戏界面2
//初始化游戏界面
public void initGamePanel() {
//定义一个Jpanel对象
JPanel game_main=new JPanel();
game_main.setLayout(new GridLayout(game_x,game_y,1,1));
//初始化面板
for(int i=0;i<text.length;i++) {
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.blue);
//data=1表示有方块
data[i][j]=1;
}
//设置文本区域不可编辑
text[i][j].setEditable(false);
//文本区域添加到主面板上
game_main.add(text[i][j]);
}
}
}
//把主面板添加到窗口中
this.setLayout(new BorderLayout());
this.add(game_main,BorderLayout.CENTER);
public Tetris() {
text=new JTextArea[game_x][game_y];
data=new int[game_x][game_y];
initGamePanel();
initWindow();
}
4.初始化游戏的说明面板
//显示游戏状态标签
JLabel state;
//显示游戏分数标签
JLabel score;
//设置游戏说明面板
public void initExplainPanel() {
//创建游戏左侧说明面板
JPanel explain_left=new JPanel();
//创建游戏右侧说明面板
JPanel explain_right=new JPanel();
explain_left.setLayout(new GridLayout(4,1));
explain_right.setLayout(new GridLayout(2,1));
//初始化左侧和右侧说明面板
explain_left.add(new JLabel("按空格键变形!"));
explain_left.add(new JLabel("按A键左移动!"));
explain_left.add(new JLabel("按D键右移动!!"));
explain_left.add(new JLabel("按S键下落!"));
//将标签内容设置为红色字体
state.setForeground(Color.red);
//把游戏状态标签游戏分数标签添加到右说明面板
explain_right.add(score);
explain_right.add(state);
//将左说明面板添加到窗口左侧
this.add(explain_left,BorderLayout.WEST);
//将右说明面板添加到窗口右侧
this.add(explain_right,BorderLayout.EAST);
}
public Tetris() {
text=new JTextArea[game_x][game_y];
data=new int[game_x][game_y];
//初始化表示游戏状态的标签
state=new JLabel("游戏当前状态:正在游戏中!");
//初始化表示游戏状态的标签
score=new JLabel("游戏当前分数:0");
initGamePanel();
initExplainPanel();
initWindow();
}
5.开始游戏的方法
boolean isrunning;
//开始游戏的方法
public void game_begin() {
//由于游戏直到死亡或者关闭才会结束,因此先写死循环并且创建一个boolean变量来判断
while(true) {
//判断游戏是否结束
if(!isrunning) {
break;
}
//进行游戏
game_run();
}
//在游戏状态标签显示游戏结束!
state.setText("游戏结束!");
}
//在无参构造方法初始化 开始游戏的标志
public Tetris() {
isrunning=true;
}
6.随机生成下落方块
// 用于存储所有方块的数组
int[] allRect;
// 用于存储当前方块的变量
int rect;
//在无参构造方法初始化
public Tetris() {
allRect=new int[]{0x00cc,0x8888,0x000f,0x888f,0xf888,0xf111,0x0eee,0xffff,0x0008,0x0888,0x000e,0x0088,0x000c,0x08c8,0x00e4,0x04c4,0x004e,0x08c4,0x006c,0x04c8,0x00c6};
}
// 随机生成下落方块形状的方法
public void ranRect() {
Random random=new Random();
rect=allRect[random.nextInt(22)];
}
7.游戏运行的方法1
// 方块当前坐标
int x, y;
// 线程休眠时间
int time = 1000;
// 游戏运行的方法
public void game_run() {
ranRect();
// 方块下落位置
x = 0;
y = 5;
for (int i = 0; i < game_x; i++) {
try {
Thread.sleep(time);
// 判断方块是否可以下落
if (!canFall(x, y)) {
} else {
// 层数+1
x++;
// 方块下落一行
fall(x, y);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
8.游戏运行的方法2
// 游戏运行的方法
public void game_run() {
ranRect();
// 方块下落位置
x = 0;
y = 5;
for (int i = 0; i < game_x; i++) {
try {
Thread.sleep(time);
// 判断方块是否可以下落
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) {
isrunning=false;
break;
}
}
break;
} else {
// 层数+1
x++;
// 方块下落一行
fall(x, y);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
8.判断方块是否继续下落的方法
// 判断方块是否继续下落的方法
public boolean canFall(int m, int n) {
// 定义一个变量
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;
}
9.改变不可方块对应的区域的值的方法
//改变不可方块对应的区域的值的方法
public void changData(int m,int n) {
//定义一个变量赋值为0x8000遍历右移
int temp=0x8000;
//遍历整个4*4方块
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;
}
//行数加1
m++;
//列数回归到首列
n=n-4;
}
}
10.移除某一行的方块上面的方块下落的方法
//定义计数得分
int gameScore;
//移除某一行的方块,令上面的方块下落的方法
public void removeRow(int row) {
int temp=100;
for(int i=row;i>=1;i++) {
for(int j=1;j<=(game_y-2);j++) {
//利用上一层的data值覆盖本层的data值
data[i][j]=data[i-1][j];
}
}
//刷新游戏区域
reflesh(row);
//方块加速
if(time>temp) {
time-=temp;
}
gameScore+=temp;
//显示变化后的得分
score.setText("游戏得分:"+gameScore);
}
11.刷新移除某一行的游戏界面的方法
//刷新移除某一行的游戏界面的方法
public void reflesh(int row) {
//通过双重for循环遍历row行以上区域
for(int i=row;i>=1;i--) {
for(int j=row;j<=(game_y-2);j++) {
if(data[i][j]==1) {
text[i][j].setBackground(Color.BLUE);
}else {
text[i][j].setBackground(Color.WHITE);
}
}
}
}
12.方块向下掉落一层的方法
// 方块向下掉落一层的方法
public void fall(int m, int n) {
if (m > 0) {
//消除上一层方块
clear(m-1,n);
}
//重新绘制方块
draw(m,n);
}
13.清除方块掉落后,上一层颜色的地方的方法
// 清除方块掉落后,上一层颜色的地方的方法
public void clear(int m, int n) {
// 定义变量
int temp = 0x8000;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((temp & rect) != 0) {
text[m][n].setBackground(Color.WHITE);
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
}
14.重新绘制掉落后的方块的方法
// 重新绘制掉落后的方块的方法
public void draw(int m, int n) {
// 定义变量
int temp = 0x8000;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((temp & rect) != 0) {
text[m][n].setBackground(Color.BLUE);
}
n++;
temp >>= 1;
}
m++;
n = n - 4;
}
}
到处游戏基本能够运行了!
15.键盘控制左移
@Override
public void keyPressed(KeyEvent e) {
// 左移
if (e.getKeyCode() == 87) {
// 判断游戏是否结束
if (!isrunning) {
return;
}
// 方块是否碰到左墙壁
if (y <= 1) {
return;
}
// 判断方块左移是否碰到别的方块
int temp = 0x8000;
for (int i = x; i < x + 4; i++) {
for (int j = y; j < y + 4; j++) {
if((temp&rect)!=0) {
if(data[i][j-1]==1) {
return;
}
}
temp>>=1;
}
}
//首先清除目标方块
clear(x,y);
y--;
draw(x,y);
}
}
16.右移
// 右移
if (e.getKeyCode() == 39) {
// 判断游戏是否结束
if (!isrunning) {
return;
}
// 方块是否碰到右墙壁
// if (y >12) {
// return;
// }
int temp = 0x8000;
int m = x;
int n = y;
// 存储方块最右边的值
int num = 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((temp & rect) != 0) {
if (n > num) {
num = n;
}
}
n++;
temp >>= 1;
}
m++;
n = n - 4;
}
// 判断是否碰到右墙壁
if (num >= (game_y - 2)) {
return;
}
// 判断方块右移是否碰到别的方块
temp = 0x8000;
for (int i = x; i < x + 4; i++) {
for (int j = y; j < y + 4; j++) {
if ((temp & rect) != 0) {
if (data[i][j + 1] == 1) {
return;
}
}
temp >>= 1;
}
}
// 首先清除目标方块
clear(x, y);
//右移
y++;
draw(x, y);
}
17.下移
//方块下移
if(e.getKeyCode()==40) {
//判断游戏是否结束
if(!isrunning) {
return;
}
//判断方块是否可以下落
if(!canFall(x,y)) {
return;
}
clear(x,y);
//改变方块的坐标
x++;
draw(x,y);
}
18.变形
@Override
public void keyTyped(KeyEvent e) {
// 空格控制方块变形
if (e.getKeyChar() == KeyEvent.VK_SPACE) {
if (!isrunning) {
return;
}
// 定义变量存储目前方块的索引
int old;
for (old = 0; old < allRect.length; old++) {
// 判断是否是当前方块
if (rect == allRect[old]) {
break;
}
}
// 定义变量存储变形后的方块
int next;
// 判断是方块
if (old == 0 || old == 7 || old == 8 || old == 9) {
return;
}
// 清除当前方块
clear(x, y);
if (old == 1 || old == 2) {
next = allRect[old == 1 ? 2 : 1];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old >= 3 && old < 6) {
next = allRect[old + 1 > 6 ? 3 : old + 1];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old == 10 || old == 11) {
next = allRect[old == 10 ? 11 : 10];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old == 12 || old == 13) {
next = allRect[old == 12 ? 13 : 12];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old >= 14 && old <= 17) {
next = allRect[old + 1 > 17 ? 14 : old + 1];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old == 18 || old == 19) {
next = allRect[old == 18 ? 19 : 18];
if (canTurn(next, x, y)) {
rect = next;
}
}
if (old == 20 || old == 21) {
next = allRect[old == 20 ? 21 : 20];
if (canTurn(next, x, y)) {
rect = next;
}
}
//重新绘制变形后的方块
draw(x,y);
}
}
//判断方块此时是否可以变形的方法
public boolean canTurn(int a,int m,int n) {
int temp=0x8000;
//变量4*4方块
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if((a&temp)!=0) {
if(data[m][n]==1) {
return false;
}
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
//可以变形
return true;
}
19.暂停
//定义一个标志变量,用于判断游戏是否暂停
boolean game_pause=false;
//接收暂停次数
int pausenum=0;
//在game_run()里面加入
if(game_pause) {
i--;
}else {
}
//在变形 左移 右移加入判断
//判断游戏是否暂停
if(game_pause) {
return;
}
//这样就完成了