📄 game.java
字号:
//Game.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//************************************游戏主程序*****************************
public class Game extends Applet
{
private GameTable gTable;//创建一个游戏桌
private Image myImage0,myImage1;//加载两个图片,用来覆盖背景和组成方块
private AudioClip myAudio;//加载背景音乐
private JButton btStart,btRestart;//创建两个按钮,一个开始,一个重新开始
private int nTime=1000;//速度,创建记时器时使用
private int nWhich;//标志创建哪一个要下落的方块
private boolean canMove=false; //标志是否响应键盘
private Root root;//要落下的方块的引用,即根类
private int tempnWhich;//标志下一个要创建的方块,即提前显示下落块
private Timer timer;//计时器,用于控制下落时间间隔
private int nScore=0;//每消掉一行加10分,用来记录总分数
private JComboBox speedcombobox;//选择速度的控件
private Label scorelabel;//显示成绩的控件
private StartListener startlistener;//开始按钮事件监听器
private String[] choices={"1","2","3","4","5","6","7","8","9"};//JComboBox的选项单
//***********************Initialize**********************
public void init()//初始化各个变量
{
btStart=new JButton("开始");
btRestart=new JButton("重来");
btStart.setToolTipText("开始游戏");//加提示
btRestart.setToolTipText("重新游戏");
setLayout(null);//自己定义布局
btStart.setBounds(320,270,90,25);//定位按钮
btRestart.setBounds(320,330,90,25);
add(btStart);//添加按钮
add(btRestart);
startlistener=new StartListener();//为两个按钮添加事件监听
btStart.addActionListener(startlistener);
btRestart.addActionListener(new RestartListener());
btRestart.setEnabled(false);//开始时候禁用"重来"按钮
myImage0=getImage(getCodeBase(),"b0.jpg");//加载图片和声音
myImage1=getImage(getCodeBase(),"b1.jpg");
myAudio=getAudioClip(getCodeBase(),"001.wav");
speedcombobox=new JComboBox(choices);//初始速度选择控件
speedcombobox.addItemListener(new SpeedListener());
speedcombobox.setEditable(false);
speedcombobox.setBounds(320,70,90,20);
add(speedcombobox);
scorelabel=new Label("0");//初始化成绩标签控件
scorelabel.setBounds(320,125,90,20);
add(scorelabel);
gTable.x=15;//初始化游戏框架,创建一个15*20的游戏框架,0代表无方块,1代表有方块
gTable.y=20;
gTable.myTable=new int[gTable.x][gTable.y];
for(int i=0;i<gTable.x;i++)
for(int j=0;j<gTable.y;j++)
gTable.myTable[i][j]=0;
nWhich=(((int)Math.round(Math.random()*12345))%8)+1;//产生随机方块
switch(nWhich)//初始化产生的方块
{
case 1:root=new One();break;
case 2:root=new Two();break;
case 3:root=new Three();break;
case 4:root=new Four();break;
case 5:root=new Five();break;
case 6:root=new Six();break;
case 7:root=new Seven();break;
case 8:root=new Eight();break;
default:break;
}
root.begin();//占据桌子,详见root类
tempnWhich=(((int)Math.round(Math.random()*12345))%8)+1;//产生下一个提前显示的方块
nWhich=tempnWhich;
timer=new Timer(nTime,new MyRun());//创建记时器,调用MyRun
addKeyListener(new KeyAdapter()//主窗口添加键盘监听器
{
public void keyPressed(KeyEvent e)
{
if(canMove)//如果满足记时器开始
judgement(e);//响应输入
}
});
btStart.addKeyListener(new KeyAdapter()//两个按钮添加键盘监听器,前面添的是鼠标点击监听器
{
public void keyPressed(KeyEvent e)
{
if(canMove)
judgement(e);
}
});
btRestart.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(canMove)
judgement(e);
}
});
}
//***********************Start**************************
public void start()
{
myAudio.loop();//循环播放背景音乐
}
public void stop()
{
myAudio.stop();//停止播放
}
public void paint(Graphics g)
{
g.setColor(new Color(131,20,62));//画背景框架,两个大长方形
for(int i=0;i<10;i++)
g.drawRect(10+i,10+i,420-2*i,400-2*i);
g.setColor(new Color(238,45,233));
for(int i=0;i<5;i++)
g.drawRect(40+i,40+i,267-2*i,352-2*i);
for(int i=0;i<gTable.x;i++)//根据桌子上的标记决定是否画方块
for(int j=0;j<gTable.y;j++)
{
if(gTable.myTable[i][j]==1)//有,画蓝方块
{
g.drawImage(myImage1,45+i*(15+2)+2,45+j*(15+2)+2,this);
}
else if(gTable.myTable[i][j]==0)//无,画白方块
{
g.drawImage(myImage0,45+i*(15+2)+2,45+j*(15+2)+2,this);
}
}
btStart.repaint();//添加背景,按钮控件和标签
btRestart.repaint();
speedcombobox.repaint();
scorelabel.setText(Integer.toString(nScore));//更新成绩
scorelabel.setBackground(new Color(55,240,40));
scorelabel.repaint();
g.drawString("级别",320,60);
g.drawString("成绩:",320,110);
g.drawString("下一个:",325,165);
g.setColor(new Color(233,44,152));
nextTo(g);//画下一个提前显示的方块
}
public void update(Graphics g)
{
paint(g);//防止闪烁
}
public void nextTo(Graphics g)//画下一个提前显示的方块
{
for(int i=0;i<3;i++)//先全部用白方块覆盖
for(int j=0;j<4;j++)
g.drawImage(myImage0,330+i*(15+2),180+j*(15+2),this);
switch(tempnWhich)//根据标志决定画哪个方块,画蓝方块
{//中间的参数根据各个方块的不同形状决定方块的原点,
//使得有总是在标签下固定位置显示的效果
case 1:g.drawImage(myImage1,347,180,this);
g.drawImage(myImage1,347,197,this);
g.drawImage(myImage1,347,214,this);
g.drawImage(myImage1,347,231,this);
break;
case 2:g.drawImage(myImage1,330,197,this);
g.drawImage(myImage1,330,214,this);
g.drawImage(myImage1,347,197,this);
g.drawImage(myImage1,347,214,this);
break;
case 3:g.drawImage(myImage1,330,197,this);
g.drawImage(myImage1,330,214,this);
g.drawImage(myImage1,347,180,this);
g.drawImage(myImage1,347,197,this);
break;
case 4:g.drawImage(myImage1,330,180,this);
g.drawImage(myImage1,330,197,this);
g.drawImage(myImage1,347,197,this);
g.drawImage(myImage1,347,214,this);
break;
case 5:g.drawImage(myImage1,330,180,this);
g.drawImage(myImage1,330,197,this);
g.drawImage(myImage1,330,214,this);
g.drawImage(myImage1,347,180,this);
break;
case 6:g.drawImage(myImage1,330,180,this);
g.drawImage(myImage1,347,180,this);
g.drawImage(myImage1,347,197,this);
g.drawImage(myImage1,347,214,this);
break;
case 7:g.drawImage(myImage1,347,197,this);
g.drawImage(myImage1,347,214,this);
g.drawImage(myImage1,330,214,this);
g.drawImage(myImage1,364,214,this);
break;
case 8:g.drawImage(myImage1,347,197,this);
break;
default:break;
}
}
public void judgement(KeyEvent e)//判断输入的是哪个键,并做出响应
{
switch(e.getKeyCode())
{
case KeyEvent.VK_DOWN://如果是向下键,就一下到底,并产生一个新的方块
root.downTo();
lineOver();//消去添满的一行,并加10分
switch(nWhich)//产生新的方块
{
case 1:root=new One();break;
case 2:root=new Two();break;
case 3:root=new Three();break;
case 4:root=new Four();break;
case 5:root=new Five();break;
case 6:root=new Six();break;
case 7:root=new Seven();break;
case 8:root=new Eight();break;
default:break;
}
tempnWhich=(((int)Math.round(Math.random()*12345))%8)+1;
nWhich=tempnWhich;
if(!root.begin())//如果新的方块产生失败,则游戏结束
{
repaint();
gameover();
}
else
{
repaint();
}
break;
case KeyEvent.VK_LEFT:root.left();repaint();break; //左移
case KeyEvent.VK_RIGHT:root.right();repaint();break;//右移
case KeyEvent.VK_UP:root.change();repaint();break; //转动
default:break;
}
}
public void lineOver()//消去添满的一行,成绩加10分
{
boolean isCan;//标志是否消去某一行
boolean isContinue=true;//标志是否还有待消的行
int k=gTable.y-1;
while(isContinue)
{
isCan=true;
while(isCan)
{
for(int i=0;i<gTable.x;i++)
{
if(gTable.myTable[i][k]!=1)
isCan=false;
}
if(isCan)//满足条件,开始消行
{
for(int i=0;i<gTable.x;i++)
gTable.myTable[i][k]=0;
for(int j=k-1;j>=0;j--)
for(int i=0;i<gTable.x;i++)
{
if(gTable.myTable[i][j]==1)
{
gTable.myTable[i][j+1]=1;
gTable.myTable[i][j]=0;
}
}
repaint();
nScore+=10;//加成绩
}
}
k--;
if(k<1)
isContinue=false;
}
}
public void gameover()//游戏结束
{
timer.stop();
JOptionPane anOptionPane=new JOptionPane();//弹出对话框
anOptionPane.showMessageDialog(this,"游戏结束!","^_^",JOptionPane.WARNING_MESSAGE);
over();//处理各个变量,以便重新开始
}
public void over()//游戏结束后,处理各个变量,以便重新开始
{
timer.stop();
for(int i=0;i<gTable.x;i++)//重新给游戏图框设置0标志
for(int j=0;j<gTable.y;j++)
{
gTable.myTable[i][j]=0;
}
repaint();
nScore=0;
switch(nWhich)//产生新的方块
{
case 1:root=new One();break;
case 2:root=new Two();break;
case 3:root=new Three();break;
case 4:root=new Four();break;
case 5:root=new Five();break;
case 6:root=new Six();break;
case 7:root=new Seven();break;
case 8:root=new Eight();break;
default:break;
}
tempnWhich=(((int)Math.round(Math.random()*12345))%8)+1;
nWhich=tempnWhich;
root.begin();
repaint();
btStart.setLabel("开始");
btStart.setToolTipText("开始游戏");
btStart.setEnabled(true);
speedcombobox.setEnabled(true);
btRestart.setEnabled(false);
btStart.setLabel("开始");
startlistener.setisRun(true);
canMove=false;
}
public class MyRun implements ActionListener//记时器调用的监听器
{
public void actionPerformed(ActionEvent e)
{
if(!root.down())//将方块下落一行,如果不能再下降了,就调用下面语句
{
lineOver();//消行
switch(nWhich)//产生新的方块
{
case 1:root=new One();break;
case 2:root=new Two();break;
case 3:root=new Three();break;
case 4:root=new Four();break;
case 5:root=new Five();break;
case 6:root=new Six();break;
case 7:root=new Seven();break;
case 8:root=new Eight();break;
default:break;
}
tempnWhich=(((int)Math.round(Math.random()*12345))%8)+1;
nWhich=tempnWhich;
if(!root.begin())//如果失败,游戏结束
{
repaint();
gameover();
}
else
repaint();
}
else
{
repaint();
}
}
}
public class StartListener implements ActionListener//开始按钮监听器
{
private boolean isRun=true;//标志是开始还是暂停,一钮两用
public void setisRun(boolean run)
{
isRun=run;
}
public void actionPerformed(ActionEvent e)
{
speedcombobox.setEnabled(false);
btRestart.setEnabled(true);
if(isRun)//开始,运行状态
{
btStart.setLabel("暂停");
btStart.setToolTipText("游戏暂停!");
timer.start();
isRun=!isRun;
canMove=true;//可以响应键盘
}
else//暂停状态
{
btStart.setLabel("开始");
btStart.setToolTipText("开始游戏!");
timer.stop();
isRun=!isRun;
canMove=false;//不可以响应键盘
}
}
}
public class RestartListener implements ActionListener//重新开始按钮监听器
{
public void actionPerformed(ActionEvent e)
{
over();//重新初始化各个变量
}
}
public class SpeedListener implements ItemListener//速度控件监听器
{
public void itemStateChanged(ItemEvent e)
{
nTime=1000-(new Integer(speedcombobox.getSelectedItem().toString()).intValue())*110;
timer=new Timer(nTime,new MyRun());//根据选择的nTime间隔重新设置记时器,以变换速度
}
}
}//主程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -