美文网首页
猿学-扫雷java版

猿学-扫雷java版

作者: 猿学 | 来源:发表于2018-08-18 13:16 被阅读0次

    首先说一下扫雷规则。

    1.数字是几就表示此数字位置邻接的八个方向有几个地雷

    2.鼠标右键单击一次标记此位置为地雷(插上一个小旗),再单击一次标记为?

    3.鼠标左键单击某位置

    如果这个位置上的数字为1-8 即显示

    如果为数字为0(即空白) 自动延伸八个方向直到遇见数字(1-8)为止

    如果为地雷,游戏失败

    4.当地图上的所有数字都点击完毕 游戏胜利

    首先是MineClient类,初始化地雷,有刷新线程,画图等等

    packagecom.xynu.mine;

    importjava.awt.Color;

    importjava.awt.Font;

    importjava.awt.Graphics;

    importjava.awt.Image;

    importjava.awt.Toolkit;

    importjava.awt.event.ActionEvent;

    importjava.awt.event.ActionListener;

    importjava.util.ArrayList;

    importjavax.swing.JFrame;

    importjavax.swing.JMenu;

    importjavax.swing.JMenuBar;

    importjavax.swing.JMenuItem;

    importjavax.swing.JPanel;

    importjavax.swing.JSeparator;

    publicclassMineClient extendsJFrame {

        /**

         *

         */

        privatestaticfinallongserialVersionUID = 1L;

        //屏幕宽度

        privateintscreenWidth;

        //屏幕高度

        privateintscreenHeight;

        //图片宽度

        privateintimgWidth = 20;

        //图片高度

        privateintimgHeight = 20;

        //地图的行数

        privateintrowNum = 0;

        //地图的列数

        privateintcolNum = 0;

        //地雷的总数

        privateintmineNum=99;

        //计时器

        privateinttimer=0;

        //游戏时间

        privateinttime=0;

        //未扫雷的个数

        privateintrestMine;

        //不是雷的个数

        privateintnotMine;

        privateMyPanel myPanel;

        //当前游戏状态

        privateString gameState = "start";

        //第一次点击

        privatebooleanfirstClick = true;

        privateJMenuBar menuBar;

        privateJMenu menu;

        privateJMenuItem lowLevel;

        privateJMenuItem midLevel;

        privateJMenuItem heightLevel;

        privateJMenuItem restart;

        privateToolkit tk=Toolkit.getDefaultToolkit();

        privateImage icon=tk.getImage("Image/icon.jpg");

        //地图集合

        privateArrayList bombList = newArrayList();

        publicMineClient(intscreenWidth,intscreenHeight,intmineNum) {

            this.screenHeight=screenHeight;

            this.screenWidth=screenWidth;

            this.mineNum=mineNum;

            //初始化菜单栏

            initMenu();

            setTitle("扫雷");

            setIconImage(icon);

            setSize(screenWidth , screenHeight);

            setLocationRelativeTo(null);

            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            setVisible(true);

            initList();

            myPanel = newMyPanel();

            myPanel.setBackground(Color.BLACK);

            add(myPanel);

            //鼠标事件

            myPanel.addMouseListener(newMyMouseListener(this));

            newupdateThread().start();

        }

        /*

         * 初始化菜单栏

         */

        privatevoidinitMenu() {

            menu=newJMenu("参数设置");

            menuBar=newJMenuBar();

            lowLevel=newJMenuItem("初级(10个雷)");

            midLevel=newJMenuItem("中级(44个雷)");

            heightLevel=newJMenuItem("高级(99个雷)");

            restart=newJMenuItem("重新开始");

            lowLevel.addActionListener(newActionListener() {

                publicvoidactionPerformed(ActionEvent e) {

                    // TODO Auto-generated method stub

                    dispose();

                    newMineClient(225,305,10);

                }

            });

            midLevel.addActionListener(newActionListener() {

                publicvoidactionPerformed(ActionEvent e) {

                    // TODO Auto-generated method stub

                    dispose();

                    newMineClient(380,460,44);

                }

            });

            heightLevel.addActionListener(newActionListener() {

                publicvoidactionPerformed(ActionEvent e) {

                    // TODO Auto-generated method stub

                    dispose();

                    newMineClient(660,460,99);

                }

            });

            restart.addActionListener(newActionListener() {

                publicvoidactionPerformed(ActionEvent e) {

                    // TODO Auto-generated method stub

                    dispose();

                    newMineClient(screenWidth,screenHeight,mineNum);

                }

            });

            menu.add(restart);

            menu.add(newJSeparator());

            menu.add(lowLevel);

            menu.add(midLevel);

            menu.add(heightLevel);

            menuBar.add(menu);

            setJMenuBar(menuBar);

        }

        publicbooleanisFirstClick() {

            returnfirstClick;

        }

        publicvoidsetFirstClick(booleanfirstClick) {

            this.firstClick = firstClick;

        }

        publicintgetImgWidth() {

            returnimgWidth;

        }

        publicvoidsetImgWidth(intimgWidth) {

            this.imgWidth = imgWidth;

        }

        publicintgetImgHeight() {

            returnimgHeight;

        }

        publicvoidsetImgHeight(intimgHeight) {

            this.imgHeight = imgHeight;

        }

        publicMyPanel getMyPanel() {

            returnmyPanel;

        }

        publicvoidsetMyPanel(MyPanel myPanel) {

            this.myPanel = myPanel;

        }

        publicString getGameState() {

            returngameState;

        }

        publicvoidsetGameState(String gameState) {

            this.gameState = gameState;

        }

        publicArrayList getBombList() {

            returnbombList;

        }

        publicintgetRowNum() {

            returnrowNum;

        }

        publicvoidsetRowNum(introwNum) {

            this.rowNum = rowNum;

        }

        publicintgetColNum() {

            returncolNum;

        }

        publicvoidsetColNum(intcolNum) {

            this.colNum = colNum;

        }

        publicintgetMineNum() {

            returnmineNum;

        }

        //创建地图

        privatevoidinitList() {

            for(inti = imgWidth; i < this.getWidth() - 2* imgWidth; i += imgWidth) {

                for(intj = imgWidth; j < this.getHeight() - 6* imgWidth; j += imgHeight) {

                    rowNum = rowNum > i / imgWidth ? rowNum : i / imgWidth;

                    colNum = colNum > j / imgWidth ? colNum : j / imgWidth;

                    Bomb bomb = newBomb(i, j, 13, this);

                    bombList.add(bomb);

                }

            }

        }

        publicstaticvoidmain(String[] args) {

            newMineClient(225,305,10);

        }

        //自定义panel

        publicclassMyPanel extendsJPanel {

            /**

             *

             */

            privatestaticfinallongserialVersionUID = 1L;

            publicvoidpaint(Graphics g) {

                super.paintComponent(g);

                restMine=mineNum;

                notMine=0;

                //画地雷 数字

                for(Bomb bomb : bombList) {

                    bomb.draw(g);

                    if(bomb.getWhat()==11)

                        restMine--;

                    if(bomb.getWhat()>=0&&bomb.getWhat()<=8)

                        notMine++;

                }

                //游戏失败

                if(gameState.equals("lose")) {

                    for(Bomb bomb : bombList) {

                        if(bomb.getHide() == 9) {

                            bomb.setWhat(bomb.getHide());

                        }

                    }

                    Font font = newFont("微软雅黑", Font.BOLD, 20);

                    g.setFont(font);

                    g.setColor(newColor(255, 0, 255));

                    g.drawString("GAME OVER!!", this.getWidth() / 2- 80,

                            this.getHeight() / 2);

                }

                //画当前游戏进行时间  和未扫的地雷数目

                drawTimeAndMineNum(g);

                //取得游戏胜利

                if(!gameState.equals("lose")&¬Mine+mineNum==colNum*rowNum)

                {

                    gameState="win";

                    Toolkit tk=Toolkit.getDefaultToolkit();

                    Image img=tk.getImage("Image/win.jpg");

                    g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);

                    Font font1 = newFont("华文行楷", Font.BOLD, 40);

                    g.setFont(font1);

                    g.setColor(newColor(248,29,56));

                    g.drawString("YOU WIN!!!", this.getWidth()/2-100, 30);

                }

            }

            privatevoiddrawTimeAndMineNum(Graphics g) {

                Font font = newFont("微软雅黑", Font.BOLD, 15);

                g.setFont(font);

                g.setColor(Color.orange);

                g.drawString("已用时:"+time+" 秒", 0, this.getHeight()-20);

                g.drawString("未扫雷:"+restMine+" 个", this.getWidth()-100, this.getHeight()-20);

            }

        }

        //屏幕每隔100ms刷新一次

        publicclassupdateThread extendsThread {

            publicvoidrun() {

                while(true) {

                    repaint();

                    if(!firstClick){

                        timer+=100;

                        if(timer==1000){

                            timer=0;

                            time++;

                        }

                    }

                    try{

                        Thread.sleep(100);

                    } catch(InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }

        }

    }

    然后是Bomb封装类。

    解释两个变量。、

    what表示当前地雷(不一定是地雷)所画的内容

    hide表示当前地雷(不一定是地雷)真实的内容

    解释两个方法

    ?

    1

    2

    3

    publicRectangle getRec() {

            returnnewRectangle(x, y, w, h);

    }

    返回当前地雷的矩形,具体作用我会在MyMouseListener类里面说

    ?

    1draw(Graphics g)

    draw方法 主要实在panel里面画图

    packagecom.xynu.mine;

    importjava.awt.Graphics;

    importjava.awt.Image;

    importjava.awt.Rectangle;

    importjava.awt.Toolkit;

    publicclassBomb {

        privateintx;

        privateinty;

        privateintwhat;

        privateinthide = 0;

        privateintw = 19;

        privateinth = 19;

        privateMineClient mc;

        privateToolkit tk = Toolkit.getDefaultToolkit();

        privateImage bomb = tk.getImage("Image/bomb.jpg");

        privateImage bomb0 = tk.getImage("Image/bomb0.jpg");

        privateImage zeroBomb = tk.getImage("Image/0.jpg");

        privateImage oneBomb = tk.getImage("Image/1.jpg");

        privateImage twoBomb = tk.getImage("Image/2.jpg");

        privateImage threeBomb = tk.getImage("Image/3.jpg");

        privateImage fourBomb = tk.getImage("Image/4.jpg");

        privateImage fiveBomb = tk.getImage("Image/5.jpg");

        privateImage sixBomb = tk.getImage("Image/6.jpg");

        privateImage severnBomb = tk.getImage("Image/7.jpg");

        privateImage eightBomb = tk.getImage("Image/8.jpg");

        privateImage flag = tk.getImage("Image/flag.jpg");

        privateImage flag2 = tk.getImage("Image/flag2.jpg");

        privateImage bg = tk.getImage("Image/s.jpg");

        publicBomb() {

            super();

            // TODO Auto-generated constructor stub

        }

        publicBomb(intx, inty, intwhat, MineClient mc) {

            super();

            this.x = x;

            this.y = y;

            this.what = what;

            this.mc = mc;

        }

        publicintgetX() {

            returnx;

        }

        publicvoidsetX(intx) {

            this.x = x;

        }

        publicintgetY() {

            returny;

        }

        publicvoidsetY(inty) {

            this.y = y;

        }

        publicintgetWhat() {

            returnwhat;

        }

        publicvoidsetWhat(intwhat) {

            this.what = what;

        }

        publicintgetHide() {

            returnhide;

        }

        publicvoidsetHide(inthide) {

            this.hide = hide;

        }

        //画地雷 数字

        publicvoiddraw(Graphics g) {

            switch(what) {

            case0:

                g.drawImage(zeroBomb, x, y, w, h, mc);

                break;

            case1:

                g.drawImage(oneBomb, x, y, w, h, mc);

                break;

            case2:

                g.drawImage(twoBomb, x, y, w, h, mc);

                break;

            case3:

                g.drawImage(threeBomb, x, y, w, h, mc);

                break;

            case4:

                g.drawImage(fourBomb, x, y, w, h, mc);

                break;

            case5:

                g.drawImage(fiveBomb, x, y, w, h, mc);

                break;

            case6:

                g.drawImage(sixBomb, x, y, w, h, mc);

                break;

            case7:

                g.drawImage(severnBomb, x, y, w, h, mc);

                break;

            case8:

                g.drawImage(eightBomb, x, y, w, h, mc);

                break;

            case9:

                g.drawImage(bomb, x, y, w, h, mc);

                break;

            case10:

                g.drawImage(bomb0, x, y, w, h, mc);

                break;

            case11:

                g.drawImage(flag, x, y, w, h, mc);

                break;

            case12:

                g.drawImage(flag2, x, y, w, h, mc);

                break;

            case13:

                g.drawImage(bg, x, y, w, h, mc);

                break;

            }

        }

        publicRectangle getRec() {

            returnnewRectangle(x, y, w, h);

        }

    }

    MyMouseListener类(自定义的鼠标事件)

    最难的都在这里面了

    1.开始玩游戏的时候要保证第一下点击的不是地雷

    2.点击到数字0(空白)时自动延伸

    解决:

    在解决问题之前 我们要首先知道鼠标点击的是哪个地雷

    packagecom.xynu.mine;

    importjava.awt.Rectangle;

    importjava.awt.event.MouseAdapter;

    importjava.awt.event.MouseEvent;

    importjava.util.ArrayList;

    importjava.util.Random;

    publicclassMyMouseListener extendsMouseAdapter {

        privateMineClient mc;

        privateintcolNum;

        privateintrowNum;

        privatebooleanisFirstClick;

        privateArrayList bombList = newArrayList();

        boolean[] vis ;

        publicMyMouseListener() {

            super();

            // TODO Auto-generated constructor stub

        }

        publicMyMouseListener(MineClient mc) {

            super();

            this.mc = mc;

            colNum = mc.getColNum();

            rowNum = mc.getRowNum();

            vis = newboolean[colNum * rowNum];

            bombList = mc.getBombList();

            this.isFirstClick=mc.isFirstClick();

        }

        /*

         * 鼠标松下事件

         * 如果松下的是鼠标左键  那么显示当前位置的地雷

         * 如果松下的鼠标右键  那么标记当前位置

         * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)

         */

        publicvoidmouseReleased(MouseEvent e) {

            if(mc.getGameState().equals("lose")) {

                return;

            }

            intx = e.getX();

            inty = e.getY();

            Rectangle rec = newRectangle(x, y, 1, 1);

            if(e.getButton() == MouseEvent.BUTTON1) {

                for(Bomb bomb : bombList) {

                    if(rec.intersects(bomb.getRec())) {

                        if(bomb.getHide() == 9) {

                            mc.setGameState("lose");

                        } else{

                            if(bomb.getHide() == 0) {

                                increasePoint(bombList.indexOf(bomb));

                            }

                            bomb.setWhat(bomb.getHide());

                        }

                    }

                }

            }

            if(e.getButton() == MouseEvent.BUTTON3) {

                for(Bomb bomb : bombList) {

                    if(rec.intersects(bomb.getRec())) {

                        if(bomb.getWhat()!=bomb.getHide()){

                            if(bomb.getWhat()==13){

                                bomb.setWhat(11);

                            }

                            elseif(bomb.getWhat()==11){

                                bomb.setWhat(12);

                            }

                            elseif(bomb.getWhat()==12){

                                bomb.setWhat(13);

                            }

                        }

                    }

                }

            }

        }

        //自动扩大区域直到遇见数字

        privatevoidincreasePoint(intindex) {

            if(vis[index])

                return;

            vis[index] = true;

            booleanedgeU = false, edgeD = false;

            if((index + 1) % (colNum) != 0)

                edgeU = true;

            if(index % (colNum) != 0)

                edgeD = true;

            if(judgeLimit(index - 1) && edgeD) {

                Bomb bomb = bombList.get(index - 1);

                setVis(bomb, index - 1);

            }

            if(judgeLimit(index + 1) && edgeU) {

                Bomb bomb = bombList.get(index + 1);

                setVis(bomb, index + 1);

            }

            if(judgeLimit(index - colNum)) {

                Bomb bomb = bombList.get(index - colNum);

                setVis(bomb, index - colNum);

            }

            if(judgeLimit(index + colNum)) {

                Bomb bomb = bombList.get(index + colNum);

                setVis(bomb, index + colNum);

            }

            if(judgeLimit(index - colNum + 1) && edgeU) {

                Bomb bomb = bombList.get(index - colNum + 1);

                setVis(bomb, index - colNum + 1);

            }

            if(judgeLimit(index - colNum - 1) && edgeD) {

                Bomb bomb = bombList.get(index - colNum - 1);

                setVis(bomb, index - colNum - 1);

            }

            if(judgeLimit(index + colNum + 1) && edgeU) {

                Bomb bomb = bombList.get(index + colNum + 1);

                setVis(bomb, index + colNum + 1);

            }

            if(judgeLimit(index + colNum - 1) && edgeD) {

                Bomb bomb = bombList.get(index + colNum - 1);

                setVis(bomb, index + colNum - 1);

            }

        }

        //判断边界

        privatebooleanjudgeLimit(inti) {

            if(i >= 0&& i < bombList.size())

                returntrue;

            returnfalse;

        }

        //显示某位置

        publicvoidsetVis(Bomb bomb, intindex) {

            if(bomb.getWhat() == bomb.getHide() && bomb.getWhat() != 0)

                return;

            if(bomb.getHide() >= 0&& bomb.getHide() <= 8&& bomb.getHide() != 9) {

                bomb.setWhat(bomb.getHide());

                if(bomb.getWhat() == 0)

                    increasePoint(index);

            } else{

                increasePoint(index);

            }

        }

        /*

         * 按下鼠标左键的同时开始初始化地图

         * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)

         */

        @Override

        publicvoidmousePressed(MouseEvent e) {

            if(mc.getGameState().equals("lose")) {

                return;

            }

            if(e.getButton() == MouseEvent.BUTTON1) {

                if(isFirstClick) {

                    isFirstClick = false;

                    mc.setFirstClick(false);

                    initBomb(e);

                    checkBomb();

                }

            }

        }

        privatevoidcheckBomb() {

            for(Bomb bomb : bombList) {

                intx = bombList.indexOf(bomb);

                //edgeU edgeD边界状态值

                booleanedgeU = false, edgeD = false;

                if((x + 1) % (colNum) != 0)

                    edgeU = true;

                if(x % (colNum) != 0)

                    edgeD = true;

                if(bomb.getHide() != 9) {

                    if(judge(x - 1) && edgeD)

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x + 1) && edgeU)

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x - colNum))

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x + colNum))

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x - colNum + 1) && edgeU)

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x - colNum - 1) && edgeD)

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x + colNum + 1) && edgeU)

                        bomb.setHide(bomb.getHide() + 1);

                    if(judge(x + colNum - 1) && edgeD)

                        bomb.setHide(bomb.getHide() + 1);

                }

            }

        }

        //判断某位置是否是地雷

        privatebooleanjudge(intx) {

            if(x >= 0&& x < bombList.size()) {

                if(bombList.get(x).getHide() == 9)

                    returntrue;

            }

            returnfalse;

        }

        /*

         * 初始化地雷

         */

        privatevoidinitBomb(MouseEvent e) {

            intx = e.getX();

            inty = e.getY();

            Rectangle rec = newRectangle(x, y, 1, 1);

            Bomb bombTemp=newBomb();  

            intwhat=0;

            //为了避免第一下点击的不是地雷 首先让它设置为地雷,初始化地雷完成后 在恢复原样

            for(Bomb bomb : bombList) {

                if(rec.intersects(bomb.getRec())){

                    what=bomb.getHide();

                    bombTemp=bomb;

                    bomb.setHide(9);

                    break;

                }

            }

            //使用随机数  初始化地图

            Random r = newRandom();

            for(inti = 0; i < mc.getMineNum(); i++) {

                while(true) {

                    intindex = r.nextInt(bombList.size());

                    if(bombList.get(index).getHide() != 9) {

                        bombList.get(index).setHide(9);

                        break;

                    }

                }

            }

            bombTemp.setHide(what);

        }

    }

    还是自己的扫雷玩着有意思 哈哈

    如果有问题 可以留言哦~一起解决

    相关文章

      网友评论

          本文标题:猿学-扫雷java版

          本文链接:https://www.haomeiwen.com/subject/epkfiftx.html