Java实现俄罗斯方块的源码分享(基于java的俄罗斯方块)

网友投稿 292 2022-07-30


本文实现的功能有:

1、 初始化游戏窗口

2、初始化游戏的界面

3、初始化游戏的说明面板

4、随机生成下落方块

5、方块下落速度变化

6、判断方块是否可以下落

7、移除某一行方块上面的方块后让上面的方块掉落

8、刷新移除某一行方块后的界面

9、清除方块

10、绘制方块

11、键盘控制方块的移动、变形和快速下落

12、游戏的暂停功能

三小时纯手工打造,具体实现代码:

import javax.swing.*;

import java.awt.*;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.util.Random;

public class start extends JFrame implements KeyListener {

public static void main(String[] args) throws Exception {

// SwingUtilities.invokeLater(start::initWindow);

start t=new start();

t.game_begin();

}

//游戏的行数为26,列数为12

private static final int game_x=26;

private static final int game_y=12;

//文本域数组

JTextArea[][] text;

//二维数组

int [][] data;

//显示游戏状态的标签

JLabel Label1;

//显示游戏分数的标签

JLabel Label;

//提示暂停键的标签

JLabel label;

//用于判断游戏是否结束

boolean isrunning;

//用于存储所有方块的数组

int [] allRect;

//用于存储当前方块的变量

int rect;

//线程的休眠时间

int time=1000;

//表示方块坐标

int x,y;

//该变量用于计算得分

int score=0;

//定义一个标志变量,判断游戏是否暂停

boolean game_pause=false;

//定义一个变量,用于记录按下暂停的次数

int pause=0;

public void initWindow(){

//设置窗口大小

this.setSize(600,850);

//设置窗口是否可见

this.setVisible(true);

//设置窗口居中

this.setLocationRelativeTo(null);

//设置释放窗体

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//设置窗体大小不可变

this.setResizable(false);

//设置标题

this.setTitle("俄罗斯方块");

}

public start(){

text=new JTextArea[game_x][game_y];

data=new int[game_x][game_y];

//初始化游戏状态的标签

Label1 =new JLabel("游戏状态:正在游戏中!");

//初始化游戏分数的标签

Label=new JLabel("游戏得分:0");

//初始化提示标签

label=new JLabel("按下s键,即可暂停游戏!");

initGamePanel();

initExplainPanel();

initWindow();

//初始化游戏开始的标志

isrunning=true;

//初始化存放方块的数组

allRect =new int[]{0x00cc,0x8888,0x000f,0x888f,0xf888,0xf111,0x111f,0x0eee,0xffff,0x0008

,0x0888,0x000e,0x0088,0x000c,0x08c8,0x00e4,0x04c4,0x004e,0x08c4,0x006c,0x04c8,0x00c6};

}

//初始化游戏界面

public void initGamePanel(){

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.BLACK);//设置为黑色,这里看个人喜好设置

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 void initExplainPanel(){

//创建游戏的左说明面板

JPanel explain_left=new JPanel();

//创建游戏的右说明面板

JPanel explain_right=new JPanel();

//初始化格式布局

explain_left.setLayout(new GridLayout(4,1));

explain_right.setLayout(new GridLayout(3,1));

//在左说明面板,添加说明文字

explain_left.add(new JLabel("按空格键,方块变形"));

explain_left.add(new JLabel("按左箭头,方块左移"));

explain_left.add(new JLabel("按右箭头,方块右移"));

explain_left.add(new JLabel("按下箭头,方块下落"));

//设置游戏标签的内容为红色字体

Label1.setForeground(Color.RED);

//将游戏状态和得分、提示添加到右面板上

explain_right.add(label);

explain_right.add(Label);

explain_right.add(Label1);

//将左说明面板添加到窗口左侧

this.add(explain_left,BorderLayout.WEST);

//将右说明面板添加到窗口右侧

this.add(explain_right,BorderLayout.EAST);

}

//开始游戏的方法

public void game_begin() throws Exception {

while (true){

//判断游戏是否结束

if(!isrunning){

break;

}

//进行游戏

game_run();

}

//在标签位置显示游戏结束

Label1.setText("游戏状态:游戏结束!");

}

//随机生成下落方块形状的方法

public void ranRect(){

Random random=new Random();

rect=allRect[random.nextInt(22http://)];

}

//游戏运行的方法

public void game_run() throws Exception {

ranRect();

//方块下落位置

x=0;

y=5;

for (int i = 0; i < game_x; i++) {

Thread.sleep(time);

if (game_pause) {

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++;

}

}

http:// //判断是否有一行可以被消除

if (sum == (game_y - 2)) {

//消除J这一行

removeRow(j);

}

}

//判断游戏是否失败

for (int j = 1; j < (game_y - 2); j++) {

if (data[3][j] == 1) {

isrunning = false;

http:// break;

}

}

break;//方块无法下落,我们应该重新生成一个方块,并重新遍历26层

} else {

//方块可以下落,层数加一

x++;

//方块下落一格

fall(x, y);

}

}

}

}

//判断方块是否可以继续下落的方法

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;//让n回归首列

}

//循环结束,可以下落

return true;

}

//改变不可下降的方块对应的区域的值的方法

public void changData(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){

data[m][n]=1;

}

n++;

temp >>=1;//右移一位

}

m++;

n=n-4;

}

}

//移除某一行的所有方块,并让上面的方块掉落的方法

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[i][j]=data[i-1][j];

}

}

//刷新游戏区域

reflesh(row);

//方块加速

if(time>temp){

time-=temqdMYJYnxp;

}

//每消除一行,得分加100

score+=temp;

//显示变化后的分数

Label.setText("游戏得分:"+score);

}

//刷新移除某一行后的游戏界面的方法

public void reflesh(int row){

//遍历row上面的游戏区域

for (int i = row; i >=1 ; i--) {

for (int j = 1; j <=(game_y-2) ; j++) {

if(data[i][j]==1){//如果是方块,将方块设置为蓝色

text[i][j].setBackground(Color.BLUE);

}else{//如果不是方块,说明是游戏的背景区域

text[i][j].setBackground(Color.WHITE);//设置为白色

}

}

}

}

//方块向下掉落一层的方法

public void fall(int m,int n){

if(m>0){

//清除上一层方块

clear(m-1,n);

}

//重新绘制方块

draw(m,n);

}

//清除方块掉落后,上一层有颜色的地方的方法

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;

}

}

//重新绘制掉落后的方块的方法

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;

}

}

@Override

public void keyTyped(KeyEvent e) {

//控制游戏暂停

if(e.getKeyChar()=='s'){//如果按下s,则游戏暂停

//判断游戏是否结束

if(!isrunning){

return;

}

pause++;

//判断是按下一次,暂停游戏

if(pause==1){

game_pause=true;

Label1.setText("游戏状态:暂停中!");

}

//判断是按下两次,继续游戏

if(pause==2){

game_pause=false;

pause=0;//重置暂停次数

Label1.setText("游戏状态:正在游戏中!");

}

}

//控制方块进行变形

if(e.getKeyChar()==KeyEvent.VK_SPACE){

//判断游戏是否结束

if(!isrunning){

return;

}

//判断游戏是否暂停

if(game_pause){

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;

//遍历整个方块

for (int i = 0; i < 4; i++) {

for (int j = 0; j < 4; j++) {

if ((temp & rect) != 0) {

if(data[m][n]==1){

return false;

}

}

n++;

temp >>=1;

}

m++;

n=n-4;

}

//可以变形

return true;

}

@Override

public void keyPressed(KeyEvent e) {

//方块进行左移

if(e.getKeyCode()==37){//左箭头对应的数值为37

//判断游戏是否结束

if(!isrunning){

return;

}

//判断游戏是否暂停

if(game_pause){

return;

}

//方块是否碰到左墙壁

if(y<=1){

return;

}

//方块的左边是否有方块

int temp=0x8000;

for (int i = x; i

for (int j = y; j

if((temp & rect)!=0){

if(data[i][j-1]==1){

return;

}

}

temp >>=1;

}

}

//清除目前方块

clear(x,y);

y--;//向左移动

draw(x,y);//重新绘制出向左移动后的方块

}

//方块进行右移

if(e.getKeyCode()==39) {//右箭头对应的数值为39

//判断游戏是否结束

if(!isrunning){

return;

}

//判断游戏是否暂停

if(game_pause){

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

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);//重新绘制出向右移动后的方块

}

//方块进行下落

if(e.getKeyCode()==40) {//下箭头对应的数值为40

//判断游戏是否结束

if (!isrunning) {

return;

}

//判断游戏是否暂停

if(game_pause){

return;

}

//判断方块是否可以下落

if(!canFall(x,y)){

return;

}

//清除当前方块

clear(x,y);

//改变方块坐标

x++;

draw(x,y);//重新绘制出向右移动后的方块

}

}

@Override

public void keyReleased(KeyEvent e) {

}

}

其中的方块数组中的数字意义:

运行后结果:

for (int j = y; j

if((temp & rect)!=0){

if(data[i][j-1]==1){

return;

}

}

temp >>=1;

}

}

//清除目前方块

clear(x,y);

y--;//向左移动

draw(x,y);//重新绘制出向左移动后的方块

}

//方块进行右移

if(e.getKeyCode()==39) {//右箭头对应的数值为39

//判断游戏是否结束

if(!isrunning){

return;

}

//判断游戏是否暂停

if(game_pause){

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

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);//重新绘制出向右移动后的方块

}

//方块进行下落

if(e.getKeyCode()==40) {//下箭头对应的数值为40

//判断游戏是否结束

if (!isrunning) {

return;

}

//判断游戏是否暂停

if(game_pause){

return;

}

//判断方块是否可以下落

if(!canFall(x,y)){

return;

}

//清除当前方块

clear(x,y);

//改变方块坐标

x++;

draw(x,y);//重新绘制出向右移动后的方块

}

}

@Override

public void keyReleased(KeyEvent e) {

}

}

其中的方块数组中的数字意义:

运行后结果:

if((temp & rect)!=0){

if(data[i][j-1]==1){

return;

}

}

temp >>=1;

}

}

//清除目前方块

clear(x,y);

y--;//向左移动

draw(x,y);//重新绘制出向左移动后的方块

}

//方块进行右移

if(e.getKeyCode()==39) {//右箭头对应的数值为39

//判断游戏是否结束

if(!isrunning){

return;

}

//判断游戏是否暂停

if(game_pause){

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

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);//重新绘制出向右移动后的方块

}

//方块进行下落

if(e.getKeyCode()==40) {//下箭头对应的数值为40

//判断游戏是否结束

if (!isrunning) {

return;

}

//判断游戏是否暂停

if(game_pause){

return;

}

//判断方块是否可以下落

if(!canFall(x,y)){

return;

}

//清除当前方块

clear(x,y);

//改变方块坐标

x++;

draw(x,y);//重新绘制出向右移动后的方块

}

}

@Override

public void keyReleased(KeyEvent e) {

}

}

其中的方块数组中的数字意义:

运行后结果:

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);//重新绘制出向右移动后的方块

}

//方块进行下落

if(e.getKeyCode()==40) {//下箭头对应的数值为40

//判断游戏是否结束

if (!isrunning) {

return;

}

//判断游戏是否暂停

if(game_pause){

return;

}

//判断方块是否可以下落

if(!canFall(x,y)){

return;

}

//清除当前方块

clear(x,y);

//改变方块坐标

x++;

draw(x,y);//重新绘制出向右移动后的方块

}

}

@Override

public void keyReleased(KeyEvent e) {

}

}

其中的方块数组中的数字意义:

运行后结果:


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java实现拓扑排序的示例代码(拓扑排序c语言代码)
下一篇:Spring多租户数据源管理 AbstractRoutingDataSource(多租户数据库)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~