扫雷课程设计-个人

该项目是一个扫雷游戏的实现,包括用户登录注册功能,使用二维数组存储游戏信息,支持不同难度级别的选择。游戏界面直观,用户可以进行标记和点击操作。通过文件读取和存储处理用户注册信息,利用Java实现游戏逻辑和图形界面交互。
摘要由CSDN通过智能技术生成

一、项目介绍

扫雷是一款大众类的益智小游戏。根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏通过简单的玩法,加上一个好看的游戏界面,每一处的细节都体现了扫雷的魅力。

项目采用技术

二维数组

文件读取存储

 

人员负责功能
杨德旭页面搭建,雷的标记,方块点击,初始化雷区

功能需求分析

完成 难度选择雷随机生成数字生成用户登录与注册等功能实现
游戏四种状态: 难度选择游戏状态游戏胜利游戏失败
游戏难度: 初级中级高级(不同难度对应不同的雷区大小和雷数量)
游戏核心: 二维数组 的相关操作
其他: 窗口绘制、界面规划、操作计数、重新开始。

项目亮点

1.登陆注册用到了文件的读取和存储

2.用二维数组来储存信息

3.将容器划分为网格,每个网格中可以放置一个组件,再对组件进行处理

系统演示图片

注册

 

登录

 

主页面

核心代码

文件的存储和读取

public void mouseClicked(MouseEvent t) {
        if (t.getSource() == submit) {
            //注册
            if (username.getText().length() == 0 || password.getText().length() == 0 || rePassword.getText().length() == 0) {
                showDialog("用户名和密码不能为空");
                return;
            }
            if (!password.getText().equals(rePassword.getText())) {
                showDialog("两次密码不一致");
                return;
            }
            if (!username.getText().matches("[a-zA-Z0-9]{3,16}")) {
                showDialog("用户名不符合规则");
                return;
            }
            if (!password.getText().matches("[a-zA-Z0-9]{3,16}")) {
                showDialog("密码不符合规则");
                return;
            }
            if (containsUsername(username.getText())) {
                showDialog("用户名已存在,重新输入");
                return;
            }
            //添加用户
            allUsers.add(new User(username.getText(), password.getText()));
            //写入文件
            BufferedWriter bw = null;
            try {
                //创建输出缓冲流对象
                bw = new BufferedWriter(new FileWriter("C:\\Users\\86151\\IdeaProjects\\untitled1\\42\\src\\user.txt"));
                for (User u : allUsers) {
                    bw.write(u.toString());
                    bw.newLine();
                    bw.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (bw != null) {
                    try {
                        bw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            //提醒注册成功
            showDialog("注册成功");
            //关闭注册界面,打开登陆界面
            this.setVisible(false);
            new LoginJFrame();
        }
         else if (t.getSource() == reset) {
            //重置
            username.setText("");
            password.setText("");
            rePassword.setText("");
        }
    }
=====================================================================
private void readUser(){
        //读取数据
        // 创建了一个 BufferedReader 对象,并将其与一个 FileReader 对象关联。
                BufferedReader reader = null;
        // 创建了一个 List 集合,
                List<String> list = new ArrayList<>();
                try {
                    reader = new BufferedReader(new FileReader("C:\\Users\\86151\\IdeaProjects\\untitled1\\42\\src\\user.txt"));
                    String line;
                    // 使用 BufferedReader 类的 readLine() 方法来一行一行地读取文件中的内容。
                    while ((line = reader.readLine()) != null) {
                        // 对于每一行,我们都将其添加到 List 集合中
                        list.add(line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                //遍历集合获取用户信息
        for(String str:list){
            //username=zhangsan & password=123
            String []userIn=str.split("&");
            String[] list1=userIn[0].split("=");
            String[] list2=userIn[1].split("=");
            User u=new User(list1[1],list2[1]);
            allUsers.add(u);
        }
    }

初始化雷区

public void initMineArea(int row,int colum,int mineCount,String grade){
        //它首先清空面板 pCenter 中的所有组件,并将类的成员变量的值设置为相应的参数值。
        pCenter.removeAll();
        spendTime=0;
        markMount=mineCount;
        this.row=row;
        this.colum=colum;
        this.mineCount=mineCount;
        this.grade=grade;
        // 然后,它创建了一个二维数组,并使用两个嵌套循环遍历这个数组中的每一个元素。
        block=new Block[row][colum];
        for(int i=0;i<row;i++){
            for(int j=0;j<colum;j++)
                // 对于每一个元素,它创建了一个新的 Block 对象并将其存储在数组中。
                block[i][j]=new Block();
        }
        // 接下来,它调用布雷者对象的成员方法来布置地雷,并调用扫雷者对象的成员方法来准备扫雷。
        lay.layMinesForBlock(block,mineCount);     //布雷
        peopleScoutMine.setBlock(block,mineCount); //准备扫雷
        blockView=new BlockView[row][colum];       //创建方块的视图
        //GridLayout布局管理器将容器划分为网格,每个网格中可以放置一个组件。
        // 指定网格的行数和列数。
        pCenter.setLayout(new GridLayout(row,colum));
        // 然后,它创建了一个二维数组,并使用两个嵌套循环遍历这个数组中的每一个元素。
        // 对于每一个元素,它创建了一个新的 BlockView 视图对象并将其存储在数组中。
        for(int i=0;i<row;i++) {
            for(int j=0;j<colum;j++) {
                blockView[i][j]=new BlockView();
                block[i][j].setBlockView(blockView[i][j]); //方块设置自己的视图
                // 调用视图对象的成员方法来将block[i][j]的数据放入视图中。
                blockView[i][j].setDataOnView();
                // 接下来,它将视图对象添加到面板 pCenter 中,
                // 并为视图对象上的按钮注册了一个动作监听器和一个鼠标监听器。
                pCenter.add(blockView[i][j]);
                blockView[i][j].getBlockCover().addActionListener(this);//注册监视器
                blockView[i][j].getBlockCover().addMouseListener(this);
                blockView[i][j].seeBlockCover(); //初始时盖住block[i][j]的数据信息
                //将按钮设置为可用状态。
                blockView[i][j].getBlockCover().setEnabled(true);
                //按钮将显示这个图标,而不是文本。
                blockView[i][j].getBlockCover().setIcon(null);
            }
        }
        //将探明的雷数添加到文本中
        showMarkedMineCount.setText(""+markMount);
        //重绘面板。
        repaint();
    }

点击方块

public void actionPerformed(ActionEvent e) {
        // 如果方块是地雷,则调用视图对象的成员方法来显示标签。
        //如果事件源是重新开始按钮,则调用类的成员方法来初始化雷区,并重绘面板。
        //如果事件源是计时器,则将用时增加 1,并更新文本字段 showTime 的文本。
        //最后,检查玩家是否获胜。如果获胜,则停止计时器并显示提示框。
        if(e.getSource()!=reStart&&e.getSource()!=time) {
            //开始计时
            time.start();
            int m=-1,n=-1;
            for(int i=0;i<row;i++) { //找到单击的方块以及它的位置索引
                for(int j=0;j<colum;j++) {
                    if(e.getSource()==blockView[i][j].getBlockCover()){
                        m=i;
                        n=j;
                        break;
                    }
                }
            }
            //检查该方块是否是地雷。
            if(block[m][n].isMine()) { //用户输掉游戏
                //遍历二维数组中的每一个元素,并将每一个方块的按钮设置为不可用状态。
                for(int i=0;i<row;i++) {
                    for(int j=0;j<colum;j++) {
                        blockView[i][j].getBlockCover().setEnabled(false);//用户单击无效了
                        if(block[i][j].isMine())
                            blockView[i][j].seeBlockNameOrIcon(); //视图显示方块上的数据信息
                    }
                }
                time.stop();
                spendTime=0;             //恢复初始值
                markMount=mineCount;      //恢复初始值
            }
            else {
                //遍历周围没有地雷的方块,并显示它们上面的数据信息。
                //首先调用peopleScoutMine.getNoMineAroundBlock(block[m][n])方法获取周围没有地雷的方块,并将它们存储在notMineBlock栈中。
                Stack<Block> notMineBlock =peopleScoutMine.getNoMineAroundBlock(block[m][n]);
                while(!notMineBlock.empty()){
                    //在每次循环中,它使用notMineBlock.pop()方法移除栈顶元素并返回它。。
                    Block bk = notMineBlock.pop();
                    //接下来,它调用bk.getBlockView()方法获取该方块的视图对象,并将其赋值给变量viewforBlock。
                    ViewForBlock viewforBlock = bk.getBlockView();
                    //最后,它调用viewforBlock.seeBlockNameOrIcon()方法显示方块上的数据信息。
                    viewforBlock.seeBlockNameOrIcon();
                }
            }
        }
        //如果事件源是重新开始按钮,则调用类的成员方法来初始化雷区,并重绘面板。
        if(e.getSource()==reStart) {
            initMineArea(row,colum,mineCount,grade);
            repaint();
            validate();
        }
        //如果点击计时器,则将用时增加 1,并更新文本字段 showTime 的文本。
        if(e.getSource()==time){
            spendTime++;
            showTime.setText(""+spendTime);
        }
        if(peopleScoutMine.verifyWin()) {  //判断用户是否扫雷成功
            //则停止计时器并显示提示框
            showDialog("你胜利了");
 
            spendTime=0;
 
 
        }
    }

雷的标记

public void mousePressed(MouseEvent e){ //探雷:给方块上插一个小旗图标(再次单击取消)
        // 当用户按下鼠标右键时,这个方法会被调用。
 
        //e.getSource()方法返回了触发事件的组件。强转将其转换为JButton类型,并将其赋值给变量source
        JButton source=(JButton)e.getSource();
        for(int i=0;i<row;i++) {
            for(int j=0;j<colum;j++) {
                // 对于每一个元素,如果事件源与该元素上的按钮相同,则检查该元素是否已经被标记。
                //1.检查鼠标事件的修饰符是否为InputEvent.BUTTON3_MASK。如果是,则表示用户按下了鼠标右键。
                //2.检查事件源(即被单击的按钮)是否与blockView[i][j]元素上的按钮相同。
                if(e.getModifiers()==InputEvent.BUTTON3_MASK&&
                        source==blockView[i][j].getBlockCover()){
                    if(block[i][j].getIsMark()) {
                        //将按钮上的图标设置为null。这样,按钮上原先显示的图标就会消失。
                        source.setIcon(null);
                        //将方块的isMark属性设置为false。这样,该方块就不再被标记为有地雷。
                        block[i][j].setIsMark(false);
                        markMount=markMount+1;
                        //更新文本
                        showMarkedMineCount.setText(""+markMount);
                    }
                    else{
                        // 标记该元素
                        source.setIcon(mark);
                        block[i][j].setIsMark(true);
                        markMount=markMount-1;
                        showMarkedMineCount.setText(""+markMount);
                    }
                }
            }
        }
    }

github地址:

https://gitee.com/yaun_123/minesweeping-mini-program-1

github提交照片:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值