自己制作的扫雷小游戏

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();
    }
}

最后的效果展示:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值