用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


还能输入: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、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。