Java-做了一个java swing的俄罗斯方块,出现下落程序块的BUG,求解决
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Travil extends JFrame implements KeyListener{//游戏类
private JTextArea[][] grids;//存放各自的文本域
private int data[][];//对应每个格子的数据,1代表有,0代表无
private int rect;//当前下落方块的类型,对应ALL中的数据
private int[] allRect;//所有方块的数据,由16个字节来记录
private int x,y;//当前方块的坐标位置,X代表行,Y代表列
private JLabel label;//显示分数的标签
private int score;//得分,每消失一层得一分
private boolean running;//游戏是否结束
public Travil(){
grids = new JTextArea[21][12];//最右边最左和最下边对应游戏的边框
data = new int[21][12];//与格子对应的数据
//所有方块的类型,由16个字节来记录方块占用格子的情况
allRect =new int[]{0xcc,0x8888,0xf,0xc44,0x2e,0x88c,0xe8,0xc88,0xe2,0x44c,0x8e,0x8c4,
0x6c,0x4c8,0xc6,0x8c8,0x4e,0x4c4,0xe4};
label = new JLabel("socre:0");//分数的默认值
running = false;
init();//开始操作
}
public void init() {
JPanel main = new JPanel();//主版面
JPanel right = new JPanel();//说明信息面板
main.setLayout(new GridLayout(21,12,1,1));//Grid布局
for(int i=0;i<grids.length;i++){//初始化每个格子
for(int j=0;j<grids[i].length;j++){
grids[i][j] = new JTextArea(20,20);
grids[i][j].setBackground(Color.WHITE);
if(j==0 || j == grids[i].length-1 || i == grids.length-1){
grids[i][j].setBackground(Color.GREEN);
grids[i][j].addKeyListener(this);
data[i][j]=1;//1代表需要显示的方块
}
grids[i][j].setEditable(false);
main.add(grids[i][j]);
}
}
right.setLayout(new GridLayout(4,4,1,1));
//设置右边的说明文字和分数记录
right.add(new JLabel("a : left"));//添加标签a
right.add(new JLabel("d : right"));//添加标签d
right.add(new JLabel("s : down"));//添加标签s
right.add(new JLabel("w : change"));//添加标签w
right.add(new JLabel(" "));
right.add(new JLabel(" "));
right.add(label);
this.setLayout(new BorderLayout());
this.add(main,BorderLayout.CENTER);
this.add(right,BorderLayout.EAST);
running = true;//正在运行
// TODO Auto-generated method stub
}
public void ranRect(){//随机产生方块类型
rect = allRect[(short)(Math.random()*19)];
}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){//捕获按键进行右,左,下落,变形的操作
if(e.getKeyChar() == 'a'){//左移操作
if(running == false)
return;
if(y<=1)
return;
int tmp=0x8000;
for(int i=x;i<x+4;i++){//二次循环判断是否碰壁
for(int j=y;j<y+4;j++){
if( (rect&tmp) != 0){
if(data[i][j-1] == 1)
return;//碰壁
}
tmp>>=1;//位置移动一位
}
}
clear(x,y);//消除图像
y--;//重绘图像
draw(x,y);
}
if(e.getKeyChar()=='d'){//右移操作
if(running == false)
return;
int tmp=0x8000;
int num = 7;
int m=x,n=y;
for(int i=0;i<4;i++){//两次循环判断是否碰壁
for(int j=0;j<4;j++){
if( (tmp&rect) != 0){
if(n>num)
num=n;
}
tmp>>=1;//移动一位
n++;
}
m++;
n-=4;
}
if(num>=10)
return;
tmp=0x8000;
for(int i=x;i<x+4;i++){//判断
for(int j=y;j<y+4;j++){
if( (rect&tmp) != 0){
if(data[i][j+1]==1)//碰壁,返回
return;
}
tmp>>=1;//移动一位
}
}
clear(x,y);//清楚图像
y++;//坐标加一
draw(x,y);//绘制图像
}
if(e.getKeyChar()=='s'){//下落操作
if(running == false)
return;
if(canFall(x,y)==false){//判断是否还可以继续下滑
saveData(x,y);//保存此时的数据
return;//返回
}
clear(x,y);//清除图像
x++;//坐标加1
draw(x,y);//绘制图像
}
if(e.getKeyChar()=='w'){//变形操作
if(running == false)
return;
int i=0;
for(;i<allRect.length;i++){//如果是石头,则直接返回,它无法变形
if (rect == allRect[i])
break;
}
if(i==0)
return;
clear(x,y);//清除图像
if(i==1 || i==2){
rect=allRect[i==1?2:1]; //图形类型1
if(y>7)
y=7;
}
if(i>=3 && i<=6){
rect=allRect[i+1>6?3:i+1]; //图形类型2
}
if(i>=7 && i<=10){
rect=allRect[i+1>10?7:i+1]; //图形类型2
}
if(i==11 && i==12){
rect=allRect[i==11?12:11]; //图形类型2
}
if(i==13 && i==14){
rect=allRect[i==13?14:13]; //图形类型2
}
if(i>=15 && i<=18){
rect=allRect[i+1>18?15:i+1]; //图形类型2
}
if(y>8)
y=8;
draw(x,y); //绘制图像
}
}
public void fall(int m,int n){ //方块下落一格
if(m>0)
clear(m-1,n);
draw(m,n); //绘制图像
}
public void draw(int m, int n) { //在M,N坐标下画出方块
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){ //根据方块的数据来绘制图像
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){
//变成黑色
grids[m][n].setBackground(Color.BLACK);
}
tmp>>=1;
n++;
}
m++; //下一列
n-=4; //下一行
}
}
public void clear(int n, int m) { //在M,N坐标下画出方块
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){//根据方块数据清除方块图像
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){
//变成白色
grids[m][n].setBackground(Color.WHITE);
}
tmp>>=1;
n++;
}
m++; //下一列
n-=4;; // 下一行
}
}
public boolean canFall(int m, int n) {//判断是否可以还可以继续下滑
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if( (tmp&rect) != 0){
if(data[m+1][n]==1)//如果下一个地方有东西则直接返回false
return false;
}
tmp>>=1; //再移动一位
n++;
}
m++; //下一列
n-=4;;//下一行
}
return true;
}
public void saveData(int m, int n) { //在M,N坐标下画出方块保存到DATA
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){//有数据
data[m][n] = 1;//保存平面数据
}
tmp>>=1;
n++;
}
m++;//下一列
n-=4;;//下一行
}
}
public void removeRow(int row){//删除第ROW行,以上的依次下降
for(int i=row;i>=1;i--){
for(int j=1;j<=10;j++){
data[i][j]=data[i-1][j];//去掉数据
}
}
reflesh();//刷新
score++;//分数加1
label.setText("score:"+score);//设置文本
}
public void reflesh() {//根据DATA来刷新每个格子
// TODO Auto-generated method stub
for(int i=1;i<20;i++){//有数据为黑色
for(int j=1;j<11;j++){
if(data[i][j]==1)
grids[i][j].setBackground(Color.BLACK);
else//没有数据为白色
grids[i][j].setBackground(Color.WHITE);
}
}
}
public void start(){//方块开始自动下落
x=0;//横向从0开始
y=5;//纵向从5开始
for(int i=0;i<21;i++){
try{
Thread.sleep(1000);//每个一秒。下降一次
if(canFall(x,y)==false){//如果可以掉
saveData(x,y);//保存数据
for(int k=x;k<x+4;k++){//进入第一层循环
int sum=0;
for(int j=1;j<=10;j++){
if(data[k][j]==1)
sum++;//数据加1
}
if(sum==10)
removeRow(k);//去掉一行
}
for(int j=1;j<=10;j++){
if(data[3][j]==1){//如果没有数据
running = false;//运行结束
break;//退出循环
}
}
break;
}
x++;//层加一
fall(x,y);//掉下来一层
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public void showMe(){//显示整个窗口
this.setSize(600,800);//窗口的大小
this.setVisible(true);//是否可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void go(){//开始游戏
while(true){//永真循环
if(running == false)//判断游戏是否结束
break;
ranRect();//绘制方格
start();//开始游戏
}
label.setText("game over");//游戏结束
}
public static void main(String[] args) {//主方法
Travil t = new Travil();
t.showMe();
t.go();//开始
// TODO Auto-generated method stub
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Travil extends JFrame implements KeyListener{//游戏类
private JTextArea[][] grids;//存放各自的文本域
private int data[][];//对应每个格子的数据,1代表有,0代表无
private int rect;//当前下落方块的类型,对应ALL中的数据
private int[] allRect;//所有方块的数据,由16个字节来记录
private int x,y;//当前方块的坐标位置,X代表行,Y代表列
private JLabel label;//显示分数的标签
private int score;//得分,每消失一层得一分
private boolean running;//游戏是否结束
public Travil(){
grids = new JTextArea[21][12];//最右边最左和最下边对应游戏的边框
data = new int[21][12];//与格子对应的数据
//所有方块的类型,由16个字节来记录方块占用格子的情况
allRect =new int[]{0xcc,0x8888,0xf,0xc44,0x2e,0x88c,0xe8,0xc88,0xe2,0x44c,0x8e,0x8c4,
0x6c,0x4c8,0xc6,0x8c8,0x4e,0x4c4,0xe4};
label = new JLabel("socre:0");//分数的默认值
running = false;
init();//开始操作
}
public void init() {
JPanel main = new JPanel();//主版面
JPanel right = new JPanel();//说明信息面板
main.setLayout(new GridLayout(21,12,1,1));//Grid布局
for(int i=0;i<grids.length;i++){//初始化每个格子
for(int j=0;j<grids[i].length;j++){
grids[i][j] = new JTextArea(20,20);
grids[i][j].setBackground(Color.WHITE);
if(j==0 || j == grids[i].length-1 || i == grids.length-1){
grids[i][j].setBackground(Color.GREEN);
grids[i][j].addKeyListener(this);
data[i][j]=1;//1代表需要显示的方块
}
grids[i][j].setEditable(false);
main.add(grids[i][j]);
}
}
right.setLayout(new GridLayout(4,4,1,1));
//设置右边的说明文字和分数记录
right.add(new JLabel("a : left"));//添加标签a
right.add(new JLabel("d : right"));//添加标签d
right.add(new JLabel("s : down"));//添加标签s
right.add(new JLabel("w : change"));//添加标签w
right.add(new JLabel(" "));
right.add(new JLabel(" "));
right.add(label);
this.setLayout(new BorderLayout());
this.add(main,BorderLayout.CENTER);
this.add(right,BorderLayout.EAST);
running = true;//正在运行
// TODO Auto-generated method stub
}
public void ranRect(){//随机产生方块类型
rect = allRect[(short)(Math.random()*19)];
}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){//捕获按键进行右,左,下落,变形的操作
//=====左移===================
if(e.getKeyChar() == 'a'){//左移操作
if(running == false)
return;
if(y<=1)
return;
int tmp=0x8000;
for(int i=x;i<x+4;i++){//二次循环判断是否碰壁
for(int j=y;j<y+4;j++){
if( (rect&tmp) != 0){
if(data[i][j-1] == 1)
return;//碰壁
}
tmp>>=1;//位置移动一位
}
}
clear(x,y);//消除图像
y--;//重绘图像
draw(x,y);
}
//=====左移===================
//=======右移============
if(e.getKeyChar()=='d'){//右移操作
if(running == false)
return;
int tmp=0x8000;
int num = 7;
int m=x,n=y;
for(int i=0;i<4;i++){//两次循环判断是否碰壁
for(int j=0;j<4;j++){
if( (tmp&rect) != 0){
if(n>num)
num=n;
}
tmp>>=1;//移动一位
n++;
}
m++;
n-=4;
}
if(num>=10)
return;
tmp=0x8000;
for(int i=x;i<x+4;i++){//判断
for(int j=y;j<y+4;j++){
if( (rect&tmp) != 0){
if(data[i][j+1]==1)//碰壁,返回
return;
}
tmp>>=1;//移动一位
}
}
clear(x,y);//清楚图像
y++;//坐标加一
draw(x,y);//绘制图像
}
//=======右移============
//=======下落============
if(e.getKeyChar()=='s'){//下落操作
if(running == false)
return;
if(canFall(x,y)==false){//判断是否还可以继续下滑
saveData(x,y);//保存此时的数据
return;//返回
}
clear(x,y);//清除图像
x++;//坐标加1
draw(x,y);//绘制图像
}
//=======下落============
//=======变形============
if(e.getKeyChar()=='w'){//变形操作
if(running == false)
return;
int i=0;
for(;i<allRect.length;i++){//如果是石头,则直接返回,它无法变形
if (rect == allRect[i])
break;
}
if(i==0)
return;
clear(x,y);//清除图像
if(i==1 || i==2){
rect=allRect[i==1?2:1]; //图形类型1
if(y>7)
y=7;
}
if(i>=3 && i<=6){
rect=allRect[i+1>6?3:i+1]; //图形类型2
}
if(i>=7 && i<=10){
rect=allRect[i+1>10?7:i+1]; //图形类型2
}
if(i==11 && i==12){
rect=allRect[i==11?12:11]; //图形类型2
}
if(i==13 && i==14){
rect=allRect[i==13?14:13]; //图形类型2
}
if(i>=15 && i<=18){
rect=allRect[i+1>18?15:i+1]; //图形类型2
}
if(y>8)
y=8;
draw(x,y); //绘制图像
}
//=======变形============
}
public void fall(int x,int y){ //方块下落一格
if(x>0)
clear(x-1,y);
draw(x,y); //绘制图像
}
public void draw(int m, int n) { //在M,N坐标下画出方块
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){ //根据方块的数据来绘制图像
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){
//变成黑色
grids[m][n].setBackground(Color.BLACK);
}
tmp>>=1;
n++;
}
m++; //下一列
n-=4; //下一行
}
}
public void clear(int n, int m) { //在M,N坐标下画出方块
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){//根据方块数据清除方块图像
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){
//变成白色
grids[n][m].setBackground(Color.WHITE);
}
tmp>>=1;
m++;
}
n++; //下一列
m=m-4; // 下一行
}
}
public boolean canFall(int m, int n) {//判断是否可以还可以继续下滑
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if( (tmp&rect) != 0){
if(data[m+1][n]==1)//如果下一个地方有东西则直接返回false
return false;
}
tmp>>=1; //再移动一位
n++;
}
m++; //下一列
n-=4;;//下一行
}
return true;
}
public void saveData(int m, int n) { //在M,N坐标下画出方块保存到DATA
// TODO Auto-generated method stub
int tmp = 0x8000;
for(int j=0;j<4;j++){
for(int k=0;k<4;k++){
if( (tmp&rect) != 0){//有数据
data[m][n] = 1;//保存平面数据
}
tmp>>=1;
n++;
}
m++;//下一列
n-=4;;//下一行
}
}
public void removeRow(int row){//删除第ROW行,以上的依次下降
for(int i=row;i>=1;i--){
for(int j=1;j<=10;j++){
data[i][j]=data[i-1][j];//去掉数据
}
}
reflesh();//刷新
score++;//分数加1
label.setText("score:"+score);//设置文本
}
public void reflesh() {//根据DATA来刷新每个格子
// TODO Auto-generated method stub
for(int i=1;i<20;i++){//有数据为黑色
for(int j=1;j<11;j++){
if(data[i][j]==1)
grids[i][j].setBackground(Color.BLACK);
else//没有数据为白色
grids[i][j].setBackground(Color.WHITE);
}
}
}
public void start(){//方块开始自动下落
x=0;//横向从0开始
y=5;//纵向从5开始
for(int i=0;i<21;i++){
try{
Thread.sleep(1000);//每个一秒。下降一次
if(canFall(x,y)==false){//如果可以掉
saveData(x,y);//保存数据
for(int k=x;k<x+4;k++){//进入第一层循环
int sum=0;
for(int j=1;j<=10;j++){
if(data[k][j]==1)
sum++;//数据加1
}
if(sum==10)
removeRow(k);//去掉一行
}
for(int j=1;j<=10;j++){
if(data[3][j]==1){//如果没有数据
running = false;//运行结束
break;//退出循环
}
}
break;
}
x++;//层加一
fall(x,y);//掉下来一层
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public void showMe(){//显示整个窗口
this.setSize(600,800);//窗口的大小
this.setVisible(true);//是否可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void go(){//开始游戏
while(true){//永真循环
if(running == false)//判断游戏是否结束
break;
ranRect();//绘制方格
start();//开始游戏
}
label.setText("game over");//游戏结束
}
public static void main(String[] args) {//主方法
Travil t = new Travil();
t.showMe();
t.go();//开始
// TODO Auto-generated method stub
}
}
通过自己的努力下落的问题解决了,现在的问题是N方块的下落不能进行变形处理!