用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

游戏--扫雷

2015-12-19 作者: 永夜极光举报

[java]代码库

1.主类
package s1213扫雷6;
//3.改变难度  关闭旧窗体,新建一个窗体,执行所有原来的代码
//7.菜单栏选项的时间,应该放在public void actionPerformed(ActionEvent e) 这个方法里面
//8尽量使用if+elseif 少用if+else 因为一旦情况发生改变,else很容易出现判断失误的情况
//10.每一次更改状态变量都要写上条件,因为以后更改程序,有可能发生条件变化,原代码就会出错!!!
//12.打开和读取文件的功能
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
 
public class Main1213 extends JFrame {
      
       int bombNum=30;                       //地雷数目
       int nearBombNum[][]=new int[100][100];       //存储这个格子周围地雷的数目
       int stackNum=0;                              //表示堆栈中有多少个元素,用作while循环的终止条件
       Boolean isBomb[][]=new Boolean [50][50];             //存储格子是不是地雷,false(不是地雷),true(地雷)
       Mybutton button[][]=new Mybutton[100][100];  //Mybutton类型的数组,专门存放按钮,方便得到按钮的x,y参数(坐标参数)
       Stack<Mybutton> a=new Stack<Mybutton>();     //创建一个堆栈对象,用来开图
       static Main1213 b=null;
        
      
    ImageIcon redFlagIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/1.jpg");       //红旗
    ImageIcon clickIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/2.jpg");       //鼠标左键单击时的图标
    ImageIcon InitialIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/3.png");       //初始图片
    ImageIcon mouseOverIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/4.png");       //鼠标覆盖时的图标
    ImageIcon bombIcon=new ImageIcon("E:/Michael/javaImage/扫雷图片/5.jpg");       //地雷的图标
     
    //地雷数从1-8的对应图标,BombNumberPicture[0]对应图标地雷数为1,BombNumberPicture[7]对应图标地雷数为8
    ImageIcon BombNumberPicture[]={
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/6.jpg"), 
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/7.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/8.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/9.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/10.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/11.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/12.jpg"),
                             new ImageIcon("E:/Michael/javaImage/扫雷图片/13.jpg"),};
 
             
          public static void main(String[] args)       
          {     b=new Main1213(); 
                b.setBomb();             //布雷
                b.Mymenu();              //添加菜单栏
                b.init();                //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。         
                b.setButton();           //在界面中添加按钮和监听事件           
          }
             
          public void init()                                                                       
          {      this.setTitle("扫雷");                                                                   //设置窗体的标题          
                 this.setLocationRelativeTo(null);                                                      //设置窗体出现位置居中
                 this.setDefaultCloseOperation(3);                                                      //设置窗体的关闭操作
                 this.setResizable(true);                                                               //设置禁止调整窗体的大小
                 this.setIconImage((new ImageIcon("E:/Michael/javaImage/扫雷图片/bomb.png").getImage()));//设置标题栏图标     
                 this.setSize(430,500);                                                                 //设置窗体的大小             
                 this.setLocationRelativeTo(null);                                                      //设置窗体出现在屏幕中间            
                 this.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));         
                 this.setVisible(true);             
          }
                 
           public void setButton()                             //绘制界面,鼠标对界面的操作事件(地雷格子)
           {           
             //事件监听***************************************************************************************************  
                MouseListener mouseListener=new MouseListener()                       
                {                   
                    public void mousePressed(MouseEvent e)
                    {  
                    //右键点击********************************************************************
                        if(e.getButton()==MouseEvent.BUTTON3)
                        {  
                           Mybutton btn = (Mybutton)e.getSource();  //得到事件源对象,并强制转型为Mybutton
                           int flagAndBomb=0;         
            
                            if(btn.status==0)                           //如果该按钮状态为没翻转过 
                                {btn.setIcon(redFlagIcon);btn.setStatus(4);}     //改变图标为redFlagIcon,并设置为状态3(红旗)
                            else if(btn.status==4)                      //如果该按钮状态为红旗   
                                {btn.setIcon(InitialIcon);btn.setStatus(0);}     //改变图标为InitialIcon(初始图标)
                            else if(btn.status==1)                      //如果是已经翻开的图标
                            {
                              int x=btn.x, y=btn.y; //x,y用来表示当前按钮的坐标   
                              checkBomb(x, y);  
                                 //如果标记的红旗下面不是地雷,那么游戏结束*********************************
                            }
                             
                     
                             
                               //胜利判断**************************
                               for(int i=0;i<20;i++)                             
                               for(int j=0;j<20;j++)
                               { if(isBomb[i][j]&&button[i][j].status==4)
                                flagAndBomb++;        
                               }
                               if(flagAndBomb==bombNum)
                                { for(int i=0;i<20;i++)                               //判断胜利后开全图
                                       for(int j=0;j<20;j++)
                                       {changeBombIcon(button[i][j]);}                    
                                       JOptionPane.showMessageDialog(null, "你胜利了");}
                              //**********************************
                        }
                    //***************************************************************************
                         
                         
                    //左键点击********************************************************************
                        if(e.getButton()==MouseEvent.BUTTON1)
                        { Mybutton btn = (Mybutton)e.getSource();
                            if(btn.status==0)
                            {   btn.setStatus(1);
                                if(!isBomb[btn.x][btn.y])                  //如果点击不是地雷
                                     {   findBomb();                         //遍历地图,找到所有位置周围的地雷数目
                                         showBomb(btn);                      //根据周围地雷数目,更换图标
                                     
                                     }
                                 
                                 if(isBomb[btn.x][btn.y])                             //如果鼠标点击是地雷
                                     {   for(int i=0;i<20;i++)                              //找到所有的地雷
                                         for(int j=0;j<20;j++)
                                         { button[i][j].setStatus(1);                       //改变所有按钮的状态变量为1(翻转状态)
                                             if(isBomb[i][j]) button[i][j].setIcon(bombIcon);} //找到地雷并改变图标为bombIcon(地雷图标)                                        
                                         JOptionPane.showMessageDialog(null, "游戏结束");    //弹出消息提示框,提示游戏结束                                       
                                     }
                             }                     
                        }
                    //左键点击**********************************************************************
                    }
 
    //计算点击处周围8个格子中的红旗数,保存在flag,用count来记录红旗和地雷的吻合数目 
    public void checkBomb(int x, int y) {
    int bomb=0,flag=0;                  
           for(int i=0;i<8;i++)
           {
               if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge())   //边界判断
               
     
                   if(button[getX(x,i)][getY(y,i)].status==3||button[getX(x,i)][getY(y,i)].status==4)
                   {
                       flag++;  //如果格子状态表示红旗,那么红旗数目+1
                       if(isBomb[getX(x,i)][getY(y,i)])
                       {bomb++; }
                   }
               }   
           }
                         
    
                         //如果红旗和地雷吻合,则开图,不吻合就结束游戏,共2种情况***************************************        
                               if(bomb==nearBombNum[x][y]) //如果周围雷数和判断一样
                               {   
                                   for(int i=0;i<8;i++)   //周围8个格子,每个格子判断一次
                                       {
                                           if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&!isBomb[x][y])   //边界判断,而且不是地雷
                                           {
                                               changeBombIcon(button[getX(x,i)][getY(y,i)]);   //点击处左上角判断
                                            if(nearBombNum[getX(x,i)][getY(y,i)]==0&&!isBomb[getX(x,i)][getY(y,i)]) 
                                                 showBomb(button[getX(x,i)][getY(y,i)]);
                                           }
                                       }
                           
                               }
                         //如果红旗和地雷吻合,则开图,不吻合就结束游戏,共2种情况***************************************
                                
                             //如果标记的红旗下面不是地雷,那么游戏结束*********************************          
                               if ((bomb!=nearBombNum[x][y]&&flag>=nearBombNum[x][y]))            
                               {
                                   for(int i=0;i<20;i++)                              //找到所有的地雷
                                         for(int j=0;j<20;j++)
                                         { button[i][j].setStatus(1);                       //改变所有按钮的状态变量为1(翻转状态)
                                             if(isBomb[i][j]) button[i][j].setIcon(bombIcon);} //找到地雷并改变图标为bombIcon(地雷图标)                  
                                         JOptionPane.showMessageDialog(null, "游戏结束");    //弹出消息提示框,提示游戏结束
                               }
                    }     
                     
                    public void mouseEntered(MouseEvent e)                                
                    {
                       Mybutton btn=(Mybutton)e.getSource();                               //要强制转型
                       if(btn.status==0)   btn.setIcon(mouseOverIcon);                                //如果还没有翻转,那么改变按钮图案
                    
                     
                    public void mouseExited(MouseEvent e)
                    
                       Mybutton btn=(Mybutton)e.getSource();                               //要强制转型,得到事件源
                       if(btn.status==0)  btn.setIcon(InitialIcon);                                   //如果按钮还未翻转,那么改变按钮图案                  
                    }
                    public void mouseReleased(MouseEvent e)
                    {} 
                    public void mouseClicked(MouseEvent e)
                    {} 
                     
                };
              //*******************************************************************************************************
                 
              //绘制游戏界面************************************************************************************************
                    for(int i=0;i<20;i++)                                   //生成界面按钮20行20列
                      for(int j=0;j<20;j++)
                    {  
                       Mybutton jb=new Mybutton(i,j);          
                       jb.setPreferredSize(new Dimension(20,20));                     
                       jb.addMouseListener(mouseListener);                  //要将new mouselistener的代码放到前面这行代码才不会出错
                       button[i][j]=jb;                                     //通过这种方式就可以根据i,j唯一确定每个按钮
                       this.add(jb);                                        //界面添加按钮
                    }
                     
                    JLabel jl = new JLabel();                               //用来计时的标签
                    JLabel j2 = new JLabel("游戏计时:");   
                    this.add(j2);
                    this.add(jl);
                   //计时功能*********************************************
                    TimerTask task = new TimerTask()  
                     {   int n=0;
                        public void run()
                        {   jl.setText(""+n); n++;}                     //计时++
                    };
                     Timer timer = new Timer();
                     timer.schedule(task, 0, 1000);
                   //计时功能*********************************************
            
             //绘制游戏界面************************************************************************************************
           
 
           public void setBomb()                               //布雷
           {   for(int i=0;i<20;i++)                           //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
               for(int j=0;j<20;j++)                           //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
                   isBomb[i][j]=false;                             //遍历地图,将所有格子的地雷状态变量都初始化为0,0表示不是地雷
             int n=0;
              while(n<bombNum)                                 //当n<地雷数,就一直循环执行
              {   int x=new Random().nextInt(20);                         //随机产生行数
                  int y=new Random().nextInt(20);                         //随机产生列数
                   if(!isBomb[x][y]) {isBomb[x][y]=!isBomb[x][y];n++;}   //如果随机产生的位置原来的状态是没有地雷,将地雷状态改变,地雷数加1     
              }
           }
  
            public void findBomb()                              //找出地图中所有位置周围地雷的数目,保存在nearBombNum[x][y]中
           {    for(int x=0;x<20;x++)                           //遍历整个地图
                for(int y=0;y<20;y++)                                      
                   {
                    if(!isBomb[x][y])                         //只有当这个位置不是地雷的时候才执行查找周围地雷数的代码
                      {
                        int n=0;                                 //n记录周围地雷的数目
                      for(int i=0;i<8;i++)
                      {
                      if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&isBomb[getX(x,i)][getY(y,i)]) //边界判断
                       {
                          n++;
                       }
                      }
                       setNearBombNum(x,y,n);
                         
                      }
                    }
            }
        
             
             public void showBomb(Mybutton btn)                //点击后更改图标和开图功能
            
                 int x=btn.x, y=btn.y,k=nearBombNum[x][y];      //x,y用来表示当前按钮的坐标,k用来表示是按钮周围的地雷数    
                if(btn.status==0) btn.setStatus(1);                             //表示访问过了                
               if(k==0)                        //如果这个格子周围没有地雷
                  {  
                    
                   for(int i=0;i<8;i++)
                  {
                  if(new Mybutton(getX(x,i),getY(y,i)).locationLegalJudge()&&!isBomb[getX(x,i)][getY(y,i)]) //边界判断
                   {
                     changeBombIcon(button[getX(x,i)][getY(y,i)]);   //点击处左上角判断
                     if(nearBombNum[getX(x,i)][getY(y,i)]==0&&button[getX(x,i)][getY(y,i)].status==0) {
                       a.push(button[getX(x,i)][getY(y,i)]);
                       stackNum++;
                      }
                   }
                  }
 
                                     
                         while(stackNum>0)                           //深度优先遍历,先将所有空格加进去,再倒出来
                        { stackNum--;showBomb(a.pop());}
                   }    
                
               else   changeBombIcon(btn);                //如果点击的不是空格,那么直接改变按钮图案       
               }       
  
             public void changeBombIcon(Mybutton btn)                 //根据周围地雷数,改变按钮图标
             {
             int nearBombNumber=nearBombNum[btn.x][btn.y];                       //k用来表示是按钮周围的地雷数
              
             if(nearBombNumber==0){
                         btn.setIcon(mouseOverIcon);
                         if(isBomb[btn.x][btn.y]) 
                         {btn.setIcon(redFlagIcon);btn.setStatus(3);}   //如果是地雷,那么就改变图标
                                   }         
             else
             {
               btn.setIcon(BombNumberPicture[nearBombNumber-1]); btn.setStatus(1);
             }
             
             }
         //**************************************菜单栏*************************************************//
         public void Mymenu()
         {
          JMenu file,edit,help,nandu;//声明JMenu类对象
          JMenuItem newgame,exit,copy,chuji,zhongji,gaoji,author,wanfa;//声明menuitem类对象
         //初始菜单项
            
           
        
          newgame=new JMenuItem("新游戏",new ImageIcon("C:/Users/Administrator/Desktop/images/2.jpg"));  //创建menuItem对象         
           exit=new JMenuItem("关闭"){{b.dispose();}};      //创建menuItem对象
           copy=new JMenuItem("保存战绩"){     //创建menuItem对象
               { addActionListener(
                       e->{
                           JFileChooser a=new JFileChooser();                      //打开文件路径程序框
                              a.setDialogTitle("另存为");
                              a.showSaveDialog(null) ;                                //注意showSaveDialog和showOpenDialog的区别
                       });
               }};   
                
           author=new JMenuItem("作者"){     //创建menuItem对象
               { addActionListener(
                       e->JOptionPane.showMessageDialog(null,"游戏作者:贺思源     制作时间:2014.12.13"));
               }};   
                
           wanfa=new JMenuItem("玩法");      //创建menuItem对象
           chuji=new JMenuItem("初级");       //创建menuItem对象
           zhongji=new JMenuItem("中级");       //创建menuItem对象
           gaoji=new JMenuItem("高级");       //创建menuItem对象
     
            
           nandu=new JMenu("难度"){{add(chuji);add(zhongji);add(gaoji);}};      //创建menuItem对象
           help=new JMenu("帮助"){{add(author);add(wanfa); }};         //创建JMenu对象
           file=new JMenu("游戏(G)"){{setMnemonic('G');add(newgame);add(nandu);addSeparator();add(exit);}};       //创建JMenu对象
           edit=new JMenu("编辑"){{add(copy);}};
           JMenuBar menubar=new JMenuBar(){{add(file);add(help);add(edit);}};        //创建menubar对象
            
            
      
           chuji.addActionListener( e->
           {
               this.dispose();                                             //关闭旧窗体
                Main1213 s2=new Main1213();
                s2.setbombNum(30);
                s2.setBomb();             //布雷
                s2.Mymenu();              //添加菜单栏
                s2.init();                //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。            
                s2.setButton();           //在界面中添加按钮和监听事件      
           });
            
           zhongji.addActionListener( e->
           {
               this.dispose();                                             //关闭旧窗体
                Main1213 s2=new Main1213();
                s2.setbombNum(60);
                s2.setBomb();             //布雷
                s2.Mymenu();              //添加菜单栏
                s2.init();                //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。            
                s2.setButton();           //在界面中添加按钮和监听事件      
           });
            
           gaoji.addActionListener( e->
           {
               this.dispose();                                             //关闭旧窗体
                Main1213 s2=new Main1213();
                s2.setbombNum(90);
                s2.setBomb();             //布雷
                s2.Mymenu();              //添加菜单栏
                s2.init();                //setVisiable的位置很重要,a.Mymenu();a.init(); 顺序交换就看不到菜单栏了。            
                s2.setButton();           //在界面中添加按钮和监听事件      
           });
            
           exit.addActionListener(e-> this.dispose()); //关闭游戏
           this.setJMenuBar(menubar);             //设置menuBar
         }
         //********************************************************************************************//       
          
        public void setbombNum(int x)                      //设置地雷数目
        {  bombNum=x;}
 
        public Mybutton getButton(int x,int y) {
            return button[x][y];
        }
         
        //根据x坐标和index,得到周围第i个格子的x坐标
        public int getX(int x,int index) {
              int xLocation[]={x-1,x,x+1,x-1,x+1,x-1,x,x+1,};
            return xLocation[index];
        }
         
        //根据y坐标和index,得到周围第i个格子的y坐标
        public int getY(int y,int index) {
            int yLocation[]={y+1,y+1,y+1,y,y,y-1,y-1,y-1};
            return yLocation[index];
        }
 
        public int[][] getNearBombNum() {
            return nearBombNum;
        }
 
        public void setNearBombNum(int x,int y,int bombNumber) {
            nearBombNum[x][y]=bombNumber;
        }
}
 
2.Mybutton类
package s1213扫雷6;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;
 
public class Mybutton extends JButton {
 
    int status; // 0(未翻转),1(翻转),3(地雷),4(红旗)
    int x, y;
 
    ImageIcon i1 = new ImageIcon("E:/Michael/javaImage/扫雷图片/3.png"); // 初始图片
    EmptyBorder o = new EmptyBorder(2, 2, 0, 0); // 生成按钮边界对象
 
    Mybutton() { // 构造方法
        this.setIcon(i1); // 给按钮添加图标
        this.setBorder(o); // 改变按钮边界
    }
 
    Mybutton(int x, int y) { // 调用本类构造方法
        this();
        this.x = x;
        this.y = y;
    }
 
    public boolean locationLegalJudge() {
        return this.x >= 0 && this.x <=19 && this.y >= 0 && this.y <=19;
    }
 
 
    public void setStatus(int x) // 改变按钮的状态变量方法
    {
        this.status = x;
    }
 
    public int getStatus() {
        return status;
    }
}

[源代码打包下载]




网友评论    (发表评论)

共22 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...