📄 game.java
字号:
//俄罗斯方块原代码!
//作者:温泉
//时间: 2006.08.03
// QQ:114587904
//Email:wenquan836@163.com
//水平有限。见笑!~
package code;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;
class appIn
{
public static void main(String args[])
{
new Form();
}
}
class Form extends JFrame //主窗口
{
mainGrid m;
view v;
controlPanel ctr;
Container ctn;
int allState=0;
int nextX[];
int nextY[];
Form()
{
this.setResizable(false);
ctn=getContentPane();
nextY=new int[4];
nextX=new int[4];
ctn.setLayout(new BorderLayout());
setSize(500,500);
v=new view();
m=new mainGrid();
ctr=new controlPanel();
ctr.add(v);
ctr.setSize(100,500);
m.Update();
ctn.add(ctr,BorderLayout.EAST);
ctn.add(m,BorderLayout.CENTER);
show();
}
private class gButton extends JButton
{
public boolean flag;
}
private class controlPanel extends JPanel implements ActionListener
{
JButton rst;
JButton pus;
JLabel lblFS;
JLabel lblHS;
controlPanel()
{
rst=new JButton("复位");
pus=new JButton("暂停");
setLayout(new GridLayout(4,2));
rst.addActionListener(this);
pus.addActionListener(this);
lblFS=new JLabel();
lblHS=new JLabel();
add(rst);
add(pus);
add(lblFS);
add(lblHS);
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==rst)
{
m.reset();
}
if(ae.getSource()==pus)
{
m.pause();
}
}
}
private class view extends JPanel//这个类是旁边的预览小窗口
{
gButton v[];
view()
{
setSize(200,200);
setLayout(new GridLayout(4,4));
v=new gButton[16];
for(int i=0;i<16;i++)
{
v[i]=new gButton();
v[i].flag=false;
v[i].setBackground(Color.white);
add(v[i]);
}
Refresh();
}
public void Refresh()//生成下一个方块并预览
{
int tmp=0;
boolean Flag=false;
//--------------固定的8种情况
tmp=(int)(Math.random()*7);
switch(tmp)
{
case 0:
{
for(int i=0;i<4;i++)
{
nextX[i]=0;
nextY[i]=i;
}
break;
}
case 1:
{
for(int i=0;i<3;i++)
{
nextY[i]=i;
nextX[i]=1;
}
nextY[3]=1;
nextX[3]=0;
break;
}
/*case 1:
{
for(int i=0;i<3;i++)
{
nextX[i]=i;
nextY[i]=1;
}
nextX[3]=1;
nextY[3]=2;
break;
}*/
case 2:
{
for(int i=0;i<3;i++)
{
nextX[i]=i;
nextY[i]=1;
}
nextX[3]=0;
nextY[3]=0;
break;
}
case 3:
{
for(int i=0;i<3;i++)
{
nextX[i]=i;
nextY[i]=1;
}
nextX[3]=0;
nextY[3]=2;
break;
}
case 4:
{
for(int i=0;i<2;i++)
{
nextX[i]=i;
nextY[i]=0;
}
for(int i=2;i<4;i++)
{
nextX[i]=i-2;
nextY[i]=1;
}
break;
}
case 5:
{
for(int i=0;i<2;i++)
{
nextX[i]=0;
nextY[i]=i;
}
for(int i=2;i<4;i++)
{
nextX[i]=1;
nextY[i]=i-1;
}
break;
}
case 6:
{
for(int i=0;i<2;i++)
{
nextX[i]=i;
nextY[i]=0;
}
for(int i=2;i<4;i++)
{
nextX[i]=i-1;
nextY[i]=1;
}
break;
}
}
//=============================================================
//验证方块的有效性(必须4个紧挨在一起)
//=============================================================
/*do
{
nextX[tmp]=(int)(Math.random()*4);
nextY[tmp]=(int)(Math.random()*4);
Flag=false;
if(tmp>0)
{
for(int i=0;i<tmp-1;i++)
if(nextX[i]==nextX[tmp] && nextY[tmp]==nextY[i])
{
Flag=true;
}
if(!Flag)
if(nextX[tmp-1]==nextX[tmp] || nextY[tmp-1]==nextY[tmp])
if(Math.abs(nextY[tmp-1]-nextY[tmp])==1 || Math.abs(nextX[tmp-1]-nextX[tmp])==1)
tmp++;
}
else
{
tmp++;
}
}while(tmp<4);*/
//================================
//左靠齐
//================================
int maxX,minX,minY;
minX=nextX[0];
minY=nextY[0];
maxX=nextX[0];
for(int i=0;i<3;i++)
{
for(int j=i+1;j<4;j++)
{
if(nextX[j]<nextX[i])
{
minX=nextX[j];
}
else
{
maxX=nextX[j];
}
if(nextY[j]<nextY[i])
{
minY=nextY[j];
}
}
}
//在右边的预览窗口显示下一个访块
for(int i=0;i<16;i++)
{
v[i].setBackground(Color.white);
}
for(int i=0;i<4;i++)
{
//nextX[i]=nextX[i]-minX;
//nextY[i]=nextY[i]-minY;
v[nextX[i]*4+nextY[i]].setBackground(Color.black);
nextX[i]=nextX[i]-(maxX-minX);
}
//---------------------------------------------
}
}
private class mainGrid extends JPanel//这个类是游戏的方阵
{
int curX[],curY[];
Timer t;
int Step=1000;
gButton b[][];
int lineCounter=0;
int Results=0;
mainGrid()
{
setSize(200,400);
curX=new int[4];curY=new int[4];
setLayout(new GridLayout(20,10));
b=new gButton[20][10];
for(int i=0;i<20;i++)
{
for(int j=0;j<10;j++)
{
b[i][j]=new gButton();
b[i][j].addKeyListener(new KeyBoard());
b[i][j].setBackground(Color.white);
add(b[i][j]);
}
}
t=new Timer(Step,new ThraedEvent());
t.start();
}
class KeyBoard extends KeyAdapter
{
public void keyPressed(KeyEvent ke)
{
Key_Down(ke.getKeyCode());
}
}
public void Key_Down(int r)
{
boolean tmp=false;//标记变量()
switch(r)
{
case 37://左移动
{
for(int i=0;i<4;i++)
{
if(curY[i]<=0)
tmp=true;
}
if(!tmp)
for(int i=0;i<4;i++)
{
if(curX[i]>=0&&b[curX[i]][curY[i]-1].flag)
tmp=true;
}
if(!tmp)
for(int i=0;i<4;i++)
{
curY[i]--;
}
break;
}
case 38://旋转
{
xz();
return;
}
case 39://向右运动
{
for(int i=0;i<4;i++)
{
if(curY[i]>=9)
tmp=true;
}
if(!tmp)
{
for(int i=0;i<4;i++)
{
if(curX[i]>=0&&b[curX[i]][curY[i]+1].flag)
tmp=true;
}
}
if(!tmp)
for(int i=0;i<4;i++)
{
curY[i]++;
}
break;
}
case 40://向下运动
{
T_Timer();
return;
}
}
ff();//从新刷新整个方阵
}//键盘按下事件处理
private void xz()
//旋转的同时,不能改变方块整体的坐标,所以运算比较复杂
//可以说是整个游戏的最难点
{
int k=0;
int w,h;
int flag;
int tmp=0;
int cz=0;
int mX=0,mY=0;
int sX=0,sY=0;
w=0;h=0;
mX=curX[0];
sX=curX[0];
mY=curY[0];
sY=curY[0];
for(int i=0;i<4;i++)
{
if(curX[i]>mX)
mX=curX[i];
if(curY[i]>mY)
mY=curY[i];
if(curX[i]<sX)
sX=curX[i];
if(curY[i]<sY)
sY=curY[i];
}
w=mX-sX;
h=mY-sY;
flag=w>h?0:1;
//h大代表横向
//w大代表纵象
if(flag==0)
cz=w;
else
cz=h;
if(cz==0) return;
if(cz==2)
{
if(flag==1)//纵向
{
for(int i=0;i<4;i++)
{
if(curX[i]==sX)tmp++;
}
switch(tmp)
{
case 2:
{
//for()
//sX--;
sX--;
//sY--;
break;
}
case 3:
{
sX--;
}
}
}
else
{
for(int i=0;i<4;i++)
{
if(curY[i]==sY)tmp++;
}
switch(tmp)
{
case 2:
{
/*for(int i=0;i<4;i++)
{
curY[i]=curY[i]-1;
}*/
break;
}
case 3:
{
sY--;
}
}
}
if(sX<0||sX>17) return;
if(sY<0||sY>7) return;
ePoint eb[][];
ePoint eb2[][];
eb=new ePoint[3][3];
eb2=new ePoint[3][3];
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{ eb[i][j]=new ePoint();
eb[i][j].x=sX+i;
eb[i][j].y=sY+j;
eb[i][j].flag=0;
for(k=0;k<4;k++)
{
if(curX[k]==sX+i && curY[k]==sY+j)
{
eb[i][j].flag=1;
}
}
eb2[i][j]=new ePoint();
eb2[i][j].x=eb[i][j].x;
eb2[i][j].y=eb[i][j].y;
}
}
k=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(b[eb2[i][j].x][eb2[i][j].y].flag==true)
return;
}
}
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
eb2[j][i].flag=eb[i][2-j].flag;
if(eb2[j][i].flag==1)
{
curX[k]=eb[j][i].x;
curY[k]=eb[j][i].y;
k++;
}
}
}
}
if(cz==3)
{
if(curX[0]==curX[1])//纵向
{
sX--;
sY++;
if(sY<0||sY>7) return;
if(sX<0||sX>16)return;
for(int i=0;i<4;i++)
{
if(b[sX+i][sY].flag) return;
}
for(int i=0;i<4;i++)
{
curX[i]=sX+i;
curY[i]=sY;
}
}
else //横向
{
sY--;
sX++;
if(sY<0||sY>6) return;
if(sX<0||sX>16)return;
for(int i=0;i<4;i++)
{
if(b[sX][sY+i].flag) return;
}
for(int i=0;i<4;i++)
{
curY[i]=sY+i;
curX[i]=sX;
}
}
}
//=================特殊情况(当4个方块形成"Z"形的时候必须这样)
if(tmp==2&&flag==1)
for(int i=0;i<4;i++)
curY[i]--;
//-------------------------------
ff();
} //旋转(整个游戏的难点!)
class ThraedEvent implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
try
{
T_Timer();
}
catch(ArrayIndexOutOfBoundsException aibe)
{
v.Refresh();
}
}
}
public void T_Timer()
{
int i,j,k;
boolean flag=false;
for(i=0;i<10;i++)
{
if(b[0][i].flag==true)
{
t.stop();
return;
}
}
//表示是否还可以往下走flag=TRUE代表不行
for(i=0;i<4;i++)
{
if(curX[i]<0) break;
if(curX[i]>=19||b[curX[i]+1][curY[i]].flag==true)
{
flag=true;
break;
}
}
//====================================
ff();//刷新整个方阵
//========================================================
if(flag==true)
{
for(i=0;i<4;i++)
{
b[curX[i]][curY[i]].flag=true;
}
Update();
flag=false;
}
else
{
for(i=0;i<4;i++)
{
curX[i]++;
}
}
}
public void ff() //矩阵刷新
{
int i,j,k;
Color color;
//着色
for(j=0;j<20;j++)
{
for(k=0;k<10;k++)
{
color=Color.white;
for(i=0;i<4;i++)
{
if(j==curX[i]&&curY[i]==k)
{
color=Color.black;
break;
}
}
if(b[j][k].flag==true)color=Color.black;
b[j][k].setBackground(color);
}
}
}
public void Update()
{
for(int i=0;i<4;i++)
{
nextY[i]=nextY[i]+4;
curX[i]=nextX[i];
curY[i]=nextY[i];
nextX[i]=0;nextY[i]=0;
}
v.Refresh();
scan();
} //更换方块
public void reset()
{
for(int i=0;i<20;i++)
{
for(int j=0;j<10;j++)
{
b[i][j].flag=false;
}
}
t.restart();
lineCounter=0;
Results=0;
//ff();
m.Update();
} //重新启动
public void pause()
{
if(t.isRunning())
t.stop();
else
t.restart();
//if(t.State==Thread.State.)
//t.yield()
} //暂停
public void scan()
{
int c=0;
boolean flag=true;
int i=19;
while(i>0)
{
flag=true;
for(int j=0;j<10;j++)
{
if(b[i][j].flag==false)
{
flag=false;
break;
}
}
if(flag)
{
for(int x=i;x>0;x--)
{
for(int y=0;y<10;y++)
{
b[x][y].flag=b[x-1][y].flag;
}
}
c++;
ff();
}
else
{
i--;
}
}
lineCounter+=c;
switch(c)//加分
{
case 1:{Results+=100;break;}
case 2:{Results+=300;break;}
case 3:{Results+=700;break;}
case 4:{Results+=1000;break;}
}
ctr.lblFS.setText("分数:"+Results);
ctr.lblHS.setText("行数:"+lineCounter);
Step=1000-(Results/5000)*100;//游戏速度,(每5000分加快0.1秒)
t.setDelay(Step);
} //扫描得分情况
private class ePoint extends Point
{
public int flag=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -