自己制作的扫雷小游戏

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

最后的效果展示:

 

 

 

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个简易的扫雷小游戏的实现步骤: 1. 首先,我们需要创建一个 HTML 网页和一个 JavaScript 文件。 2. 在 HTML 文件中,创建一个包含游戏界面的主要容器。这个容器可以是一个 div 元素,它包含了游戏区域以及一些游戏统计信息。 3. 在这个容器中,我们可以创建一个表格,用于展示扫雷的主要游戏区域。这个表格应该包含若干行和列,它们可以用 tr 和 td 元素来创建。 4. 接下来,我们需要用 JavaScript 来生成扫雷的游戏区域。我们可以创建一个二维数组,用于表示游戏区域。对于每一个位置,我们可以用一个对象来表示它的状态和周围地雷的数量。 5. 在这个二维数组中,我们随机生成一些位置,用于放置地雷。对于每一个地雷,我们可以将它所在位置的对象的状态设置为 "mine"。 6. 接下来,我们需要计算出每一个格子周围地雷的数量,以便后面用于显示该格子的数字。我们可以使用一个循环来遍历每一个格子,然后判断它周围的格子是否为地雷,并计算出地雷的数量。 7. 当用户点击某一个格子时,我们需要检查这个格子的状态。如果它是地雷,则游戏结束;如果它已经被揭示过了,则不做任何操作。如果它是未揭示的格子,并且周围没有地雷,则我们需要递归地揭示周围的格子。否则,我们需要显示该格子的数字。 8. 当游戏结束时,我们需要显示游戏结束的信息,并清空游戏区域,以便开始下一局游戏。 这只是一个简单的扫雷小游戏实现示例,实际上还有很多细节和优化可以进行。希望这个实现过程能够给你一些启示,帮助你成功实现一个属于自己的扫雷小游戏

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

用手写的从前

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值