java课设--扫雷

1.团队成员及负责模块

成员负责模块
聂闽鹭界面设计,游戏界面设计,难度选择
郑钧雷分布算法,失败重来选择,计时

2.git提交记录

在这里插入图片描述

3.项目介绍

仿照传统游戏扫雷制作了一个扫雷小游戏
在这里插入图片描述

4.功能架构图

1.流程图

在这里插入图片描述

2.UML类图

在这里插入图片描述

5.运行截图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6.主要代码

1.主要流程

 void launch(){
        GameUtil.START_TIME = System.currentTimeMillis();//开始时间
        this.setVisible(true);//可见
        if(GameUtil.state==3){
            this.setSize(500,500);

        }else{
            this.setSize(width,height);//窗口大小
        }
        //this.setSize(width,height);//窗口大小
        this.setLocationRelativeTo(null);//居中显示
        this.setTitle("扫雷");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭方法
        //鼠标事件
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch(GameUtil.state){
                    case 0:
                        //左键被点击
                        if(e.getButton()==1){
                        GameUtil.MOUSE_x = e.getX();
                        GameUtil.MOUSE_Y  =e.getY();
                        GameUtil.LEFT = true;
                    }
                        //右键被点击
                        if(e.getButton()==3){
                            GameUtil.MOUSE_x = e.getX();
                            GameUtil.MOUSE_Y  =e.getY();
                            GameUtil.RIGHT = true;
                        }
                    case 1:
                    case 2:
                        if(e.getButton()==1) {
                            if (e.getX() > GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W / 2)
                                    && e.getX() < GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W / 2) + GameUtil.SQUARE_LENGTH
                                    && e.getY() > GameUtil.OFFSET
                                    && e.getY() < GameUtil.OFFSET + GameUtil.SQUARE_LENGTH) {
                                mapBottom.reGame();
                                mapTop.reGame();
                                GameUtil.FLAG_NUM = 0;
                                GameUtil.START_TIME = System.currentTimeMillis();
                                GameUtil.state = 0;
                            }
                        }
                        //单机滚轮,切换难度
                        if(e.getButton()==2){
                            GameUtil.state=3;
                            begin=true;
                        }
                        break;
                    case 3:
                        if(e.getButton()==1){
                            GameUtil.MOUSE_x = e.getX();
                            GameUtil.MOUSE_Y = e.getY();
                            begin = gameSelect.hard();
                        }
                        break;
                }

            }
        });
        while(true){
            repaint();
            begin();
            try {
                Thread.sleep(40);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

设置了鼠标监视器,来判断当前是点击空格还是插旗子或者选择难度,根据选择难度绘制各个难度对应的窗口大小

2.地雷初始化

 void newRay(){
        for(int i=0;i<GameUtil.RAY_MAX*2;i=i+2){
            x=(int)(Math.random()*GameUtil.MAP_W+1);//1-12
            y=(int)(Math.random()*GameUtil.MAP_H+1);//1-12
            rays[i]=x;
            rays[i+1]=y;
            //判断坐标是否存在
            for(int j=0;j<i;j+=2){
                if(x==rays[j]&&y==rays[j+1]){
                    i=i-2;
                    isplace = false;
                    break;
                }
            }
            //将坐标放入数组
            if(isplace){
                rays[i] = x;
                rays[i+1] = y;
            }
            isplace = true;
        }
        for (int i= 0;i<GameUtil.RAY_MAX*2;i=i+2){
            GameUtil.DATA_BUTTON[rays[i]][rays[i+1]]=-1;
        }
    }

初始化地雷

3.游戏重置

    void reGame(){
        for (int i = 1; i <= GameUtil.MAP_W; i++) {
            for (int j = 1; j <= GameUtil.MAP_H; j++) {
                GameUtil.DATA_BUTTON[i][j]=0;
            }
        }
        bottomRay.newRay();
        bottomNum.newNum();
    }

游戏返回初始状态

4.失败判断

   boolean boom() {
        for (int i = 1; i < GameUtil.MAP_W; i++) {
            for (int j = 1; j <= GameUtil.MAP_H; j++) {
                if (GameUtil.DATA_BUTTON[i][j] == -1 && GameUtil.DATA_TOP[i][j] == -1) {
                    GameUtil.state=2;
                    seeBoom();
                    return true;
                }
            }
        }
        return false;
    }

判断是否有踩雷,如果踩到地雷则失败

5.胜利判断

    boolean victory(){
        //统计未打开格子数
        int count = 0;
        for (int i = 1; i < GameUtil.MAP_W; i++) {
            for (int j = 1; j <= GameUtil.MAP_H; j++) {
                if(GameUtil.DATA_TOP[i][j]!=-1){
                    count++;
                }
            }
        }
        if(count==GameUtil.RAY_MAX){
            GameUtil.state=1;
            for (int i = 1; i < GameUtil.MAP_W; i++) {
                for (int j = 1; j <= GameUtil.MAP_H; j++) {
                    //未翻开,变成旗
                    if(GameUtil.DATA_TOP[i][j]==0){
                        GameUtil.DATA_TOP[i][j]=1;
                    }
                }
            }
            return true;
        }
        return false;
    }

统计未打开格子的数量,如果剩下的格子数量与雷的数量相同,则胜利

6.操作的逻辑判断

void logic(){
        temp_x=0;
        temp_y=0;
        if(GameUtil.MOUSE_x>GameUtil.OFFSET&&GameUtil.MOUSE_Y>3*GameUtil.OFFSET){
            temp_x = (GameUtil.MOUSE_x-GameUtil.OFFSET)/GameUtil.SQUARE_LENGTH+1;
            temp_y = (GameUtil.MOUSE_Y-GameUtil.OFFSET*3)/GameUtil.SQUARE_LENGTH+1;
        }
        if(temp_x>=1&&temp_x<=GameUtil.MAP_W
        &&temp_y>=1&&temp_y<=GameUtil.MAP_H){
            if(GameUtil.LEFT){
                //覆盖则翻开
               if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
                   GameUtil.DATA_TOP[temp_x][temp_y]=-1;
               }
               spaceOpen(temp_x,temp_y);
                GameUtil.LEFT = false;
            }
            if(GameUtil.RIGHT){
                //覆盖则插旗
                if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
                    GameUtil.DATA_TOP[temp_x][temp_y]=1;
                    GameUtil.FLAG_NUM++;
                }
                //插旗则取消
                else if(GameUtil.DATA_TOP[temp_x][temp_y]==1){
                    GameUtil.DATA_TOP[temp_x][temp_y]=0;
                    GameUtil.FLAG_NUM--;
                }
                else if(GameUtil.DATA_TOP[temp_x][temp_y]==-1){
                    numOpen(temp_x,temp_y);
                }
                GameUtil.RIGHT = false;
            }
        }
        boom();
        victory();
    }

判断操作的逻辑

背景设计

界面背景
初始界面背景
在这里插入图片描述
地雷
在这里插入图片描述
旗帜
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三个表情

打印格式

    void paintSelf(Graphics g){

            g.setColor(Color.blue);
        //画竖线
        for(int i = 0;i<=GameUtil.MAP_W;i++){
            g.drawLine(GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
                    3*GameUtil.OFFSET,
                    GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
                    3*GameUtil.OFFSET+GameUtil.MAP_H*GameUtil.SQUARE_LENGTH);
        }
        //画横线
        for(int i = 0;i<=GameUtil.MAP_H;i++){
            g.drawLine(GameUtil.OFFSET,
                    3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
                    GameUtil.OFFSET+GameUtil.MAP_W*GameUtil.SQUARE_LENGTH,
                    3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH);
        }
        for(int i=1;i<=GameUtil.MAP_W;i++){
            for( int j =1;j<= GameUtil.MAP_H;j++){
                //雷
                if(GameUtil.DATA_BUTTON[i][j]==-1) {
                    g.drawImage(GameUtil.lei,
                            GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
                            GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
                            GameUtil.SQUARE_LENGTH - 2,
                            GameUtil.SQUARE_LENGTH - 2,
                            null);
                }
                //数字
                if(GameUtil.DATA_BUTTON[i][j]>=0) {
                    g.drawImage(GameUtil.images[GameUtil.DATA_BUTTON[i][j]],
                            GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
                            GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
                            GameUtil.SQUARE_LENGTH - 2,
                            GameUtil.SQUARE_LENGTH - 2,
                            null);
            }
        }
    }
//绘制数字,倒计时
        GameUtil.drawWord(g,""+(GameUtil.RAY_MAX-GameUtil.FLAG_NUM),GameUtil.OFFSET,2*GameUtil.OFFSET,30,Color.red);
        GameUtil.drawWord(g,""+(GameUtil.END_TIME-GameUtil.START_TIME)/1000,
                GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W-1),
                2*GameUtil.OFFSET,30,Color.black);
        switch(GameUtil.state){
            case 0:
                GameUtil.END_TIME = System.currentTimeMillis();
                g.drawImage(GameUtil.face,
                        GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
                        GameUtil.OFFSET,
                        null);
                break;
            case 1:
                g.drawImage(GameUtil.win,
                        GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
                        GameUtil.OFFSET,
                        null);
                break;
            case 2:
                g.drawImage(GameUtil.over,
                        GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
                        GameUtil.OFFSET,
                        null);
                break;
        }
   }

个人仓库

github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值