package saolei; import sun.audio.AudioPlayer; import sun.audio.AudioStream; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileInputStream; import java.util.Random; /* -1是雷 0是没有雷 1~8是周围有几颗雷 */ public class saoleiTEst extends JFrame implements ActionListener { static int h=9;//行数 static int l=9;//列数 int [][]data=new int[h][l];//此数组用于设置显示在每个块中的数字,范围1~8 JButton [][]jbs=new JButton[h][l]; static int LEICOUNT=10;//雷的总数 int time=0;//已用时间 Timer timer=new Timer(1000, this); JLabel jLabel1=new JLabel(time+"s"); ImageIcon icon=new ImageIcon("笑脸.jpg"); JButton j=new JButton(icon); ImageIcon iconan=new ImageIcon("按钮.jpg"); JPanel jPanel3=new JPanel(new BorderLayout()); public saoleiTEst(){ this.setSize(520, 600); this.setLocationRelativeTo(null);//设置窗口位置居中 this.setDefaultCloseOperation(3);// this.setTitle("扫雷"); this.setResizable(false);//设置不可改变窗口大小 /* 设置菜单 */ JMenuBar jMenuBar=new JMenuBar(); JMenu jMenu=new JMenu("难度设置"); jMenuBar.add(jMenu); JMenuItem jMenuItem1=new JMenuItem("初级"); JMenuItem jMenuItem2=new JMenuItem("中级"); JMenuItem jMenuItem3=new JMenuItem("高级"); jMenu.add(jMenuItem1); jMenu.add(jMenuItem2); jMenu.add(jMenuItem3); this.setJMenuBar(jMenuBar); /* 设置面板1 */ JPanel jPanel1=new JPanel(); jPanel1.setBackground(new Color(204, 204,204 )); j.addActionListener(this); j.setBackground(new Color(204, 204,204 )); jPanel1.add(jLabel1); j.setBorderPainted(false); jPanel1.add(j); /* 设置面板2 */ JPanel jPanel2=new JPanel(new GridLayout(h,l,2,2)); jPanel2.setBackground(new Color(204, 204,204 )); /* 设置面板3,将面板1和面板2装在面板3中 */ JPanel jPanel3=new JPanel(new BorderLayout()); jPanel3.add(jPanel1,BorderLayout.NORTH); jPanel3.add(jPanel2,BorderLayout.CENTER); /* 方法应用区 */ addlei(LEICOUNT);//埋雷,参数是要埋的雷的总数 leishu();//计算每个按钮旁边有几颗雷 addleiqu(jPanel2);//设置雷区 /* 难度设置 */ //初级 jMenuItem1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); h=9; l=9; LEICOUNT=10; saoleiTEst a=new saoleiTEst(); a.setSize(520,600); } }); //中级 jMenuItem2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); h=16; l=16; LEICOUNT=40; saoleiTEst b=new saoleiTEst(); b.setSize(800,900); b.setLocationRelativeTo(null); } }); //高级 jMenuItem3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); h=16; l=30; LEICOUNT=99; saoleiTEst b=new saoleiTEst(); b.setSize(1400,900); b.setLocationRelativeTo(null); } }); this.add(jPanel3); timer.start(); this.setVisible(true); } /* 添加雷区方法 */ public void addleiqu(JPanel jP2){ for (int i=0;i<h;i++){ for (int j=0;j<l;j++){ //JButton jButton=new JButton(Integer.valueOf(data[i][j]).toString() ); JButton jButton=new JButton(iconan); jButton.setFont(new Font("宋体", Font.BOLD, 18)); jP2.add(jButton);//将按钮添加至面板中 jButton.addActionListener(this);//给每个按钮添加动作事件 jbs[i][j]=jButton;//将按钮添加至按钮数组 } } } /* 动作事件监听 */ public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof Timer){//时钟监听 time++; jLabel1.setText(+time+"s"); timer.start(); return; } if(e.getSource().equals(j)){//重新开始 restart(); return; } JButton jb=(JButton)e.getSource(); for (int i=0;i<h;i++){ for(int j=0;j<l;j++){ if(jb.equals(jbs[i][j])){ if(data[i][j]==-1){ lose();//踩到雷时触发 }else{ opencell(i,j);//点到其他按钮时触发 checkwin();//每点击按钮时判断是否胜利 } return; } } } } /* 添加指定数目的雷方法 实质是将指定数目的-1随机赋值到数组中 */ public void addlei(int count){ Random random=new Random(); int hang; int lei; for (int i=0;i<count;){ hang=random.nextInt(h);//生成随机数行 lei=random.nextInt(l);//生成随机数列 if(data[hang][lei]!=-1){//避免重复埋雷 data[hang][lei]=-1; i++; } } } /* 计算每个按钮周围有几个雷 */ public void leishu(){ for (int i=0;i<h;i++){ for (int j=0;j<l;j++){ if(data[i][j]==-1) continue;//有雷时不加 int c=0;//八种情况下计算数量 if(i>0&&j>0&&data[i-1][j-1]==-1) c++; if(i>0&&data[i-1][j]==-1) c++; if(i>0&&j<h-1&&data[i-1][j+1]==-1) c++; if(j>0&&data[i][j-1]==-1) c++; if(j<h-1&&data[i][j+1]==-1) c++; if(i<h-1&&j>0&&data[i+1][j-1]==-1) c++; if(i<h-1&&data[i+1][j]==-1) c++; if(i<h-1&&j<h-1&&data[i+1][j+1]==-1) c++; data[i][j]=c; } } } /* 各自自动连级打开(使用递归) */ public void opencell(int i,int j){ JButton jb=jbs[i][j];//获取这个按钮 if(!jb.isEnabled()) return;//判断是否已经打开 //对打开按钮的设置 jb.setIcon(null); jb.setEnabled(false); jb.setOpaque(true); jb.setBackground(new Color(190, 190, 190)); jb.setText(data[i][j]+""); if(data[i][j]!=-1&&data[i][j]!=0){//碰到1~8时停止递归,结束操作 return; } if(data[i][j]==0){//碰到空格时,对其周围八个都进行此操作,进入递归 jbs[i][j].setText(""); if(i>0&&j>0&&data[i-1][j-1]!=-1) opencell(i-1,j-1); if(i>0&&data[i-1][j]!=-1) opencell(i-1,j); if(i>0&&j<h-1&&data[i-1][j+1]!=-1) opencell(i-1,j+1); if(j>0&&data[i][j-1]!=-1) opencell(i,j-1); if(j<h-1&&data[i][j+1]!=-1) opencell(i,j+1); if(i<h-1&&j>0&&data[i+1][j-1]!=-1) opencell(i+1,j-1); if(i<h-1&&data[i+1][j]!=-1) opencell(i+1,j); if(i<h-1&&j<h-1&&data[i+1][j+1]!=-1) opencell(i+1,j+1); } } /* 踩到雷时触发 */ public void lose() { timer.stop();//踩到雷时时钟停止 /* 踩到雷时添加爆炸音效 */ try { FileInputStream fileau = new FileInputStream("boom.wav"); AudioStream as = new AudioStream(fileau); AudioPlayer.player.start(as); } catch (Exception e) { e.printStackTrace(); } /* 踩到雷时将所有按钮都显现出来 */ for (int i = 0; i < h; i++) { for (int j = 0; j < l; j++) { if (jbs[i][j].isEnabled()) { JButton jb=jbs[i][j]; if (data[i][j]==-1){ ImageIcon iconlei=new ImageIcon("雷.jpg"); jb.setEnabled(false); jb.setIcon(iconlei); jb.setDisabledIcon(iconlei); } else if(data[i][j]==0){ jb.setIcon(null); jb.setEnabled(false); jb.setOpaque(true); jb.setBackground(new Color(190, 190, 190)); jb.setText(""); }else{ jb.setIcon(null); jb.setEnabled(false); jb.setOpaque(true); jb.setBackground(new Color(190, 190, 190)); jb.setText(data[i][j]+""); } } } }//失败时跳出的窗口 JOptionPane.showMessageDialog(new Frame(), "你输了,点击笑脸重新开始!","失败",JOptionPane.PLAIN_MESSAGE); } /* 判断是否胜利 */ public void checkwin(){ int count=0; for (int i = 0; i < h; i++) { //计算剩余格子的数量 for (int j = 0; j < l; j++) { if(jbs[i][j].isEnabled()) count++; } } if(count==LEICOUNT){//剩余格子数等于雷数时,游戏胜利,跳出胜利窗口 timer.stop(); JOptionPane.showMessageDialog(new Frame(), "你赢了,加油,奥利给!","胜利",JOptionPane.PLAIN_MESSAGE); } } /* 重新开始 */ public void restart(){ /* 重新开始将每个格子进行复原,重新埋雷,时间也重新开始 */ for (int i = 0; i < h; i++) { for (int j = 0; j < l; j++) { data[i][j]=0; jbs[i][j].setEnabled(true); jbs[i][j].setText(""); jbs[i][j].setIcon(iconan); } } time=0; jLabel1.setText(time+"s"); addlei(LEICOUNT); timer.start(); leishu(); } public static void main(String[] args) { saoleiTEst sl=new saoleiTEst(); } }
最后的效果展示: