扫雷小游戏的设计与实现

         完成JAVA版扫雷的基本实现后,其实发现这并不难,做这个小游戏,也是希望自己能有一些收获,以及看看自己能做什么。到现阶段,暂且总结下自己的成果和心得。
       代码还是有些繁琐,算法是完全自己设计的,坦诚地说,基本都是比较简单的实现,算法和模块构建仍可进一步地优化。
       要进一步完善功能,代码的模块构建还是非常重要的。
       总体感受就是,通过自己的努力得到了基本的预期成果,同时拿了这个作品去参加了一个小竞赛,尽管还有不足,对自己的付出,还是值得肯定的。
(1)接口部分
public interface Common {
	
	public static final int ROW=10;//横线数目
	public static final int LIST=10;//纵线数目
	public static final int X=6;//起始坐标
	public static final int Y=10;
	public static final int SIZE=30;//大小
	public static final int MineArea[][]=new int [ROW-1][LIST-1];//二维雷区数组存储
	public static final RecordList RL=new RecordList();//利用数组队列进行记录已显示图片的位置
	public static final int Flag[][]=new int[ROW-1][LIST-1];
	public static final RecordList FlagList=new RecordList();//利用数组队列进行记录已显示標記图片的位置
	public static final int Score=0;
	public static final Flag f=new Flag();

		

}

(2)界面实现部分,雷区按钮是采用直接绘制的方法,菜单栏的监听器方法是对雷区进行初始化,用二维数组存储雷区的信息,使用随机类对象产生随机不重复的类的位置,遍历剩余位置设置相应的数字。

public class MineFrame extends JFrame implements Common{
	public static int combs=10;//地雷数
	private int []mine=new int [40];//地雷位置
	private JTextField jt=new JTextField();
	private Graphics g;
	
	//实例化一个事件处理方法为属性
    private MineListener ml=new MineListener();	
	private static MineFrame mf;
	//主函数部分
	public static void main(String[] args) {
		mf=new MineFrame();
		mf.Sweepuint();
	
	}
	
	//创建雷区面板为属性
		private	JPanel jp = new JPanel(){
				//重写paint方法(重绘)
				public void paint(Graphics g){
					super.paint(g);	
					//画横线
					for(int i=0;i<LIST;i++){
						g.drawLine(X, Y+SIZE*i,X+SIZE*(LIST-1),Y+SIZE*i );
					}//画纵线
					for(int i=0;i<ROW;i++){
						g.drawLine(X+SIZE*i, Y, X+SIZE*i, Y+SIZE*(ROW-1));
					}
					//遍历雷区
					for(int i=0;i<9;i++)
					    for(int j=0;j<9;j++){
					    	//给每个方格画出3D按钮效果
					        for(int k=0;k<5;k++){
			                     Color c=new Color(100+15*k,100+15*k,100+15*k);
			                     g.setColor(c);
			                     g.drawRect((X+SIZE*j)+k, (Y+SIZE*i)+k, SIZE-2*k, SIZE-2*k);
			                   
					        }
					}
					//重绘游戏进程	
				   if(RL.size()>0){
					  for(int i=0;i<RL.size();i++){
						    //获取数组队列中的值
					        Mine m=(Mine)RL.get(i);					        
					        int r=m.getRow();
					        int l=m.getList();
					        //实例化绘制图片的类
			    	        Picture p=new Picture(g);
			    	        //调用绘制图片的方法
			    	        p.drawPicture(r,l);	
					    }
					}
				   //画标志
				   if(FlagList.size()>0){
						  for(int i=0;i<FlagList.size();i++){
							    //获取数组队列中的值
						        Mine m=(Mine)FlagList.get(i);					        
						        int r=m.getRow();
						        int l=m.getList();
						        //实例化绘制图片的类
				    	        Picture p=new Picture(g);
				    	        //调用绘制图片的方法
				    	        p.drawFlag(r,l);	
						    }
						}
	
					
				}
				
			};
		
    //创建扫雷窗体的方法
	public void Sweepuint() {
		//设置窗体属性
		this.setTitle("扫雷soldier");
		this.setSize(new Dimension(300,400));
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(3);
		//调用创建菜单栏的方法
		this.menu();
		//调用创建北边面板的方法
		this.northPanel();
		//添加中间雷区面板
		this.add(jp);
		//设置面板颜色
		jp.setBackground(Color.LIGHT_GRAY);
		//显示窗体
		this.setVisible(true);
		
		g=jp.getGraphics();	
		System.out.print("取得画布!");
		
		this.setDefaultCloseOperation(3);
		System.out.println(" Main frame is visible !");
	
		ml.sendPanel(jp, g,mf);
		f.sendPanel(jp, g);
	}
	
	
	
	//创建北边面板的方法
	private void northPanel() {
		//实例化一个面板对象
		JPanel jp=new JPanel();	
		//设置面板属性
		jp.setPreferredSize(new Dimension(0,50));
		jp.setBackground(Color.ORANGE);
		
		//jp.setLayout(null);
		//设置面板位置
		this.add(jp,BorderLayout.NORTH);
		
		ImageIcon im =new ImageIcon("images/001.jpg");
		//实例化一个按钮对象
		JButton jp1=new JButton(im);
		jp1.setPreferredSize(new Dimension(39,39));
		jp.add(jp1);
		//设置显示框属性
		jt.setPreferredSize(new Dimension(50,40));
		jp.add(jt);
		

	}
	//创建菜单栏的方法
	private void menu() {
		//实例化一个菜单栏对象
		JMenuBar jmb=new JMenuBar();
		String []array={"新开","标记","帮助","排行榜"};
		String [][]item={{"初级","中级","高级","闯关"},{"标记开","标记关"},{"说明","版权"},{"查看"}};
		//遍历数组
		for(int i=0;i<array.length;i++){
			//实例化菜单选项对象
			JMenu jm=new JMenu(array[i]);
			jmb.add(jm);
			for(int j=0;j<item[i].length;j++){
			    //实例化菜单子选项对象
			    JMenuItem jmt=new JMenuItem(item[i][j]);
			    //添加监听器方法
			    jmt.addActionListener(l);
			    jm.add(jmt);
			}	
		}
		this.setJMenuBar(jmb);
	}
	
	
	//针对菜单栏的匿名内部类
	private ActionListener l=new ActionListener(){
		// MineFrame mf=new MineFrame();
		public void actionPerformed(ActionEvent e) {
			String s=e.getActionCommand();
			if(s.equals("初级")){
				combs=10;
				System.out.println("=======>"+combs);
				newPlay(s);
			}else if(s.equals("中级")){
				combs=15;
				System.out.println("=======>"+combs);
				newPlay(s);
			}else if(s.equals("高级")){
				combs=20;
				System.out.println("=======>"+combs);
				newPlay(s);
				
			}else if(s.equals("闯关")){
				combs=10;
				System.out.println("=======>"+combs);
				newPlay(s);
			}else if(s.equals("标记开")&&f.getSign()==0){	
				//画出绿色矩形框
			    g.setColor(Color.GREEN);
			    for(int k=0;k<4;k++){
			        g.drawRect(X-k,Y-k ,X+(ROW-1)*SIZE,Y+(LIST-1)*SIZE-2*k);
			    }
			    System.out.println("ml remove and f add");
				jp.removeMouseListener(ml);				
				//给面板添加监听器方法
				jp.addMouseListener(f);	
				f.setSign(1);
			}else if(s.equals("标记关")&&f.getSign()==1){		
				 g.setColor(Color.LIGHT_GRAY);
				 for(int k=0;k<4;k++){
					 g.drawRect(X-k,Y-k ,X+(ROW-1)*SIZE,Y+(LIST-1)*SIZE-2*k);
				    }
				 System.out.println("ml add and f remove");
				 jp.removeMouseListener(f);				
				 //给面板添加监听器方法
				 jp.addMouseListener(ml);
				 f.setSign(0);
			}

			else if(s.equals("指南")){
				JOptionPane.showMessageDialog(null, "游戏指南:\n点击“新开”菜单,选择游戏难易级别,开始游戏\n" +
						"点击非雷位置,会显示提示图片,表示其周围8个位置的雷数,直至最后找出所有雷,则胜利\n" +
						"点击“标志”菜单,选择是否开启标志,开启则可以用小红旗标志记录雷的位置,关闭标志后继续游戏");
				
			}else if(s.equals("版权")){
				JOptionPane.showMessageDialog(null,"版权所有:胡梦");
				
			}else if(s.equals("查看")){
				
			}
						
		}
	
	};	
		//重新开局的方法
		public void newPlay(String s){
			jt.setText(""+combs);
			//清空一次二维数组
			for(int i=0;i<9;i++)
				for(int j=0;j<9;j++)
					MineArea[i][j]=0;
			//清空数组队列
			if(RL.size()>0){
			    for(int i=RL.size();i>=0;i--)
				    RL.remove(i);
			}
		   
			
			if(FlagList.size()>0){
			    for(int i=FlagList.size();i>=0;i--)
				    FlagList.remove(i);
			}
			 //初始化面板
			jp.paint(g);
			//创建雷的位置
			produceMines();
		
			//根据产生的雷确定整个雷区其余的数字
			setData();
			
			//给面板添加监听器方法
		    jp.addMouseListener(ml);
		    jp.addMouseMotionListener(ml);
            ml.setNew(s);
		   
		}
		
		//初始化雷的位置的方法
		public void produceMines(){
			//创建雷所在的位置,产生不重复的随机数
			Random ran=new Random();
			for(int i=0;i<combs;i++){
				Boolean flag=true;
			    int temp=ran.nextInt(81);   
		        for(int j=0;j<i;j++){     
			    	if(mine[j]==temp){
			    		flag=false ;	
			    		break;
			    	}  
		        }
		        if(flag){
		        	mine[i]=temp;
		        }
		        else 
			      i--;
			 }			
			for(int i=0;i<combs;i++){
				System.out.println(mine[i]);
			}
		}
		
		//设置雷周围的数字的方法
		public void setData(){
			for(int i=0;i<combs;i++){
				//计算每个雷所在的横纵行位置,用二维数组存储雷位置
			    int x=mine[i]/9;
			    int y=mine[i]-9*x;
			    MineArea[x][y]=100;		
			}		
			for(int i=0;i<9;i++)
				for(int j=0;j<9;j++){
					if(MineArea[i][j]==0){
						int count=0;
						if(i>0 && i<8 && j>0 && j<8){
							//对其周围8个位置进行检查
							if(MineArea[i-1][j-1]==100)
								count++;
							if(MineArea[i-1][j]==100)
								count++;
							if(MineArea[i-1][j+1]==100)
								count++;
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i][j+1]==100)
								count++;
							if(MineArea[i+1][j-1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
							if(MineArea[i+1][j+1]==100)
								count++;						
						}
						else if(i==0 && j==0){
							//对3个位置进行检查
							if(MineArea[i][j+1]==100)
								count++;
							if(MineArea[i+1][j+1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
						}
						else if(i==0 && j==8){
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i+1][j-1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
						}
						else if(i==8 && j==0){
							if(MineArea[i-1][j]==100)
								count++;
							if(MineArea[i-1][j+1]==100)
								count++;
							if(MineArea[i][j+1]==100)
								count++;
						}
						else if(i==8 && j==8){
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i-1][j-1]==100)
								count++;
							if(MineArea[i-1][j]==100)
								count++;
							
						}
						else if(i==0 && j>0 && j<8){
							//对5个方向位置进行检查
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i+1][j-1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
							if(MineArea[i+1][j+1]==100)
								count++;
							if(MineArea[i][j+1]==100)
								count++;
						}
						else if(i==8 && j>0 && j<8){
							//对5个方向位置进行检查
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i-1][j-1]==100)
								count++;
							if(MineArea[i-1][j]==100)
								count++;
							if(MineArea[i-1][j+1]==100)
								count++;
							if(MineArea[i][j+1]==100)
								count++;
						}
						else if(j==0 && i>0 && i<8){
							//对5个方向位置进行检查
							if(MineArea[i-1][j]==100)
								count++;
							if(MineArea[i-1][j+1]==100)
								count++;
							if(MineArea[i][j+1]==100)
								count++;
							if(MineArea[i+1][j+1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
						}
						else if(j==8 && i>0 && i<8){
							//对5个方向位置进行检查
							if(MineArea[i-1][j]==100)
								count++;
							if(MineArea[i-1][j-1]==100)
								count++;
							if(MineArea[i][j-1]==100)
								count++;
							if(MineArea[i+1][j-1]==100)
								count++;
							if(MineArea[i+1][j]==100)
								count++;
						}
						System.out.println("array["+i+"]"+"["+j+"]="+count);
						MineArea[i][j]=count;
					}
						
				}
		}

}


(3)雷区监听器处理方法。
   根据点击的位置所存储的值设置显示相应的图片。点击雷位置则结束游戏,点击数字则显示提示图片,点击空白要显示一片连续的提示,使用递归嵌套的方法设置。将已点击的位置记录到一个数组队列中,借此可判断是否赢了以及实现重绘。
   增加了一个随鼠标移动显示图片的功能,在鼠标移动方法中设置记录当前位置作为下一个位置的前一位置,当鼠标移动,移除前一位置的图片,画出当前位置的图片。
public class MineListener extends MouseAdapter implements Common{
	private Graphics g;
    private JPanel jp;
    private int r;
    private int l;
    private String newCommand="";
    private int tr=0;
    private int tl=0;
    private MineFrame mf;
    
    public MineListener(){   	
    }
    public void setNew(String s){
	    newCommand=s;
    }
    
    public void sendPanel(JPanel jpl,Graphics g,MineFrame mf){
    	jp=jpl;
    	this.g=g;
    	this.mf=mf;
    	System.out.println(" here is get graphics from panel...");
    }
    
	public void mousePressed(MouseEvent e){
		int x=e.getX();		
	    int y=e.getY();
	   //计算行列
	   l=(x-X)/SIZE;
	   r=(y-Y)/SIZE;		
	   System.out.println("r="+r+"   l="+l);		
	}
	public void mouseReleased(MouseEvent e){
	
		int temp=MineArea[r][l];	
		System.out.println("temp="+temp);
		//点击的位置是否在雷的位置
		this.click(temp);
	    //检查是否赢了
		this.win();
			 	    										
	}	
    public void mouseMoved(MouseEvent e){
    	
    	if(f.getSign()==0){
    	    //获取当前行和列  	
    	   int x=e.getX();
    	   int y=e.getY();
    	   int ll=(x-X)/SIZE;
 	       int rr=(y-Y)/SIZE;
 	      // System.out.println("ll="+ll+"rr="+rr);
 	 
    	 //实例化绘制图片的类
	        Picture p=new Picture(g);
    	    if(tr==rr && tl==ll  && ll<9 &&rr<9){    	   
    	    //调用绘制图片的方法
    	        p.drawSoldier(rr,ll);
    	    
    	   
    	    }else if(( tr!=rr || tl!=ll  )&& ll<9 &&rr<9){
    		//把上一个位置移除
    		 p.remove(tr, tl);
    		//把当前位置改为下一个位的前一位置
    		tr=rr;
    	    tl=ll;
    	    //绘制当前位置的图片
    	    p.drawSoldier(rr,ll);
    		}
    	
    	}
    }
	
	//判断赢的方法
	public void win(){
		System.out.println("RL.size="+RL.size());
		if(RL.size()==81-MineFrame.combs){
			for(int i=0;i<9;i++)
				for(int j=0;j<9;j++){
					if(MineArea[i][j]==100){						
						//实例化绘制图片的类
				    	Picture p=new Picture(g);
				    	//调用绘制图片的方法
				    	p.drawFlag(i,j);					    	
				    	//记录已显示过的位置
						Mine m=new Mine(i,j);
						RL.add(m);
						if(!FlagList.check(m))
						    FlagList.add(m);
					}
				}	
			if(newCommand.equals("闯关")){
				JOptionPane.showMessageDialog(null,"进入第二关!!!");
				MineFrame.combs=15;
				mf.newPlay("闯关");
		    	jp.removeMouseListener(this);	
				jp.removeMouseListener(f);
			}else {
	            	JOptionPane.showMessageDialog(null,"You are winner!!!");
			    	jp.removeMouseListener(this);	
					jp.removeMouseListener(f);
			}
			    
		}
			
	}
	
	//根据点击的位置显示图片的方法
	public void click(int t){
		if(t==100){
			
			System.out.println("踩雷啦!!!!!!!");


			//清空标志队列
			if(FlagList.size()>0){
		    for(int i=FlagList.size();i>=0;i--)
			    FlagList.remove(i);
		}	
						
			//显示所有图片并保存数组位置到数组队列
			for(int i=0;i<9;i++)
			    for(int j=0;j<9;j++){
			    	Mine m=new Mine(i,j);
			    	//if(!RL.check(m)){
			    	System.out.println("i="+i+" j="+j);
						   RL.add(m);
						  //实例化绘制图片的类
					      Picture p=new Picture(g);
					      //调用绘制图片的方法
					      p.drawPicture(i,j);	
						//}	
			}
			
			JOptionPane.showMessageDialog(null,"踩雷!Game Over!!!");
			jp.removeMouseListener(this);
			jp.removeMouseListener(f);
		}
		
		//若点击的不是雷的位置则显示数字
		else if(t==1 ||t==2 ||t==3 ||t==4 ||t==5 ||t==6 ||t==7){
			System.out.println("数字");						
			//记录已显示过的位置
			Mine m=new Mine(r,l);
			System.out.println("Check:"+RL.check(m));
			if(!RL.check(m)){
			   RL.add(m);
			  //实例化绘制图片的类
		      Picture p=new Picture(g);
		      //调用绘制图片的方法
		      p.drawPicture(r,l);	
			}
			
		}
		//若点击位置为空白
		else if(t==0){
			this.searchAround(r, l);		
		}
	}
	
	//检查该位置周围的8个位置的情况的方法
	public void searchAround(int x,int y){
			System.out.println("====>search");
			Mine m=new Mine(x,y);
			//实例化绘制图片的类
		    Picture p=new Picture(g);
		    //若该位置没有画过图片则画出图片
	    	if(!RL.check(m)){
				   RL.add(m);				  
			      //调用绘制图片的方法
			      p.drawPicture(x,y);	
			}
	    	else if (RL.check(m))
	    		return;
		    //对该位置的周围进行判断是否为空,是则显示并检查8个位置的周围是否为空!递归	
			//若已经显示图片则不遍历
			//左上角
		    if(x-1>-1 && x-1<9 && y-1>-1 && y-1<9 && MineArea[x-1][y-1]==0)				    
			    this.searchAround(x-1,y-1);    	
			else if(x-1>-1 && x-1<9 && y-1>-1 && y-1<9 &&MineArea[x-1][y-1]!=0 && MineArea[x-1][y-1]!=100){
				Mine m1=new Mine(x-1,y-1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x-1,y-1);	
					}	
		
			}
		    //正上方	
		    if(x-1>-1 && x-1<9 && y>-1 && y<9 && MineArea[x-1][y]==0)
			    this.searchAround(x-1,y); 
			else if(x-1>-1 && x-1<9 && y>-1 && y<9 && MineArea[x-1][y]!=0 && MineArea[x-1][y]!=100){
				Mine m1=new Mine(x-1,y);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x-1,y);	
					}	
			}
            //右上角
		    if(x-1>-1 && x-1<9 && y+1>-1 && y+1<9 && MineArea[x-1][y+1]==0)
			    this.searchAround(x-1,y+1);
		    else if(x-1>-1 && x-1<9 && y+1>-1 && y+1<9 &&MineArea[x-1][y+1]!=0 && MineArea[x-1][y+1]!=100){
		    	Mine m1=new Mine(x-1,y+1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x-1,y+1);	
					}	
		    }
		    //正右方
		    if(x>-1 && x<9 && y+1>-1 && y+1<9 && MineArea[x][y+1]==0)
		    	this.searchAround(x,y+1);
		    else if(x>-1 && x<9 && y+1>-1 && y+1<9 && MineArea[x][y+1]!=0 && MineArea[x][y+1]!=100){
		    	Mine m1=new Mine(x,y+1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x,y+1);	
					}	
		    }
		    //右下角
		    if(x+1>-1 && x+1<9 && y+1>-1 && y+1<9 && MineArea[x+1][y+1]==0)
			    this.searchAround(x+1,y+1);
			else if(x+1>-1 && x+1<9 && y+1>-1 && y+1<9 && MineArea[x+1][y+1]!=0 && MineArea[x+1][y+1]!=100){
				Mine m1=new Mine(x+1,y+1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x+1,y+1);	
					}	
			}
	        		
		    //正下方
		    if(x+1>-1 && x+1<9 && y>-1 && y<9 && MineArea[x+1][y]==0)
     			this.searchAround(x+1,y);
		    else if(x+1>-1 && x+1<9 && y>-1 && y<9 && MineArea[x+1][y]!=0 && MineArea[x+1][y]!=100){
		    	Mine m1=new Mine(x+1,y);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x+1,y);	
					}	
		    }
	        	
		    //左下角
		    if(x+1>-1 && x+1<9 && y-1>-1 && y-1<9 && MineArea[x+1][y-1]==0)
				this.searchAround(x+1,y-1);
		    else if(x+1>-1 && x+1<9 && y-1>-1 && y-1<9 && MineArea[x+1][y-1]!=0 && MineArea[x+1][y-1]!=100){
		    	Mine m1=new Mine(x+1,y-1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x+1,y-1);	
					}	
		    }
	        	
		    //正左方
    	    if(x>-1 && x<9 && y-1>-1 && y-1<9 && MineArea[x][y-1]==0)
    			this.searchAround(x,y-1);
   	        else if(x>-1 && x<9 && y-1>-1 && y-1<9 && y-1<9 && MineArea[x][y-1]!=0 && MineArea[x][y-1]!=100){
   	        	Mine m1=new Mine(x,y-1);
				//若该位置没有画过图片则画出图片
		    	if(!RL.check(m1)){
					   RL.add(m1);				  
				      //调用绘制图片的方法
				      p.drawPicture(x,y-1);	
					}	
   	        }
	        		
		 
	}
}

(4)标记功能部分,移除游戏监听,对雷区进行标记监听。点击标记开,可作标记,点击标记关,继续游戏,这个功能设置主要是为安卓版扫雷服务的,手机触控是部分左右键的。
public class Flag extends MouseAdapter implements Common{
	 private Graphics g;
	 private JPanel jp;
	 private int fr;
	 private int fl;
	 private  int sign=0;
	 
	 public int getSign(){
		 return sign;
	 }
	 public void setSign(int t){
		  sign=t;
	 }
	 
	 public Flag(){
	 }
	 public void sendPanel(JPanel jpl,Graphics g){
	    	jp=jpl;
	    	this.g=g;
	    	System.out.println(" here is get graphics from panel...");
	    	
     }
	 public void mousePressed(MouseEvent e){
		 int x=e.getX();		
		 int y=e.getY();
		   //计算行列
		 fl=(x-X)/SIZE;
		 fr=(y-Y)/SIZE;		
		 System.out.println("fr="+fr+"   fl="+fl);	
		 
	 }
	 public void mouseReleased(MouseEvent e){
		 Picture p=new Picture(g);
		   Mine m=new Mine(fr,fl);
		   if(!FlagList.check(m)&&!RL.check(m)){	    
		     //画出标志
		     p.drawFlag(fr, fl);
		     //记录已标记的位置
             FlagList.add(m);
		     
		 }else if(FlagList.check(m)){
			//取消标志
		     p.removeFlag(fr, fl);
		     //记录已标记的位置
		     FlagList.remove(m);
		 }
			 
	 }

	  
}

(5)画图片的方法
public class Picture implements Common {
	private Graphics g;
	
	private ImageIcon im =new ImageIcon("images/s雷.jpg");
	private ImageIcon icn=new ImageIcon("images/s旗.jpg");
	private ImageIcon icn2=new ImageIcon("images/slme.png");
	private ImageIcon icon0 = new ImageIcon("images/s00.jpg");
	private ImageIcon icon1 = new ImageIcon("images/s01.jpg");
	private ImageIcon icon2 = new ImageIcon("images/s02.jpg"); 
	private ImageIcon icon3 = new ImageIcon("images/s03.jpg");
	private ImageIcon icon4 = new ImageIcon("images/s04.jpg");
	private ImageIcon icon5 = new ImageIcon("images/s05.jpg"); 
	private ImageIcon icon6 = new ImageIcon("images/s06.jpg"); 
	private ImageIcon icon7 = new ImageIcon("images/s07.jpg"); 
		
	public Picture (Graphics g){
		this.g=g;	
		//System.out.println("画出图片");
	}
	public void drawSoldier(int x,int y){
		if(y<9)
		g.drawImage(icn2.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
	}
	
	public void drawFlag(int x,int y){
		
		g.drawImage(icn.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		
	}
	//对雷区游戏监听时,移除图片的方法
	public void remove(int x,int y){
		//给每个方格画出3D按钮效果
        for(int k=0;k<5;k++){
             Color c=new Color(100+15*k,100+15*k,100+15*k);
             g.setColor(c);
             g.drawRect((X+SIZE*y)+k, (Y+SIZE*x)+k, SIZE-2*k, SIZE-2*k);
        }
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect((X+SIZE*y)+5, (Y+SIZE*x)+5, SIZE-9, SIZE-9);
      //重绘游戏进程	
		   if(RL.size()>0){
			  for(int i=0;i<RL.size();i++){
				    //获取数组队列中的值
			        Mine m=(Mine)RL.get(i);					        
			        int r=m.getRow();
			        int l=m.getList();		
	    	        //调用绘制图片的方法
	    	        drawPicture(r,l);	
			    }
			}
		   if(FlagList.size()>0){
				  for(int i=0;i<FlagList.size();i++){
					    //获取数组队列中的值
				        Mine m=(Mine)FlagList.get(i);					        
				        int r=m.getRow();
				        int l=m.getList();		
		    	        //调用绘制图片的方法
		    	        drawFlag(r,l);	
				    }
				}

     
	}
	//对雷区标记监听时,移除标记的方法
	public void removeFlag(int x,int y){
		//给每个方格画出3D按钮效果
        for(int k=0;k<5;k++){
             Color c=new Color(100+15*k,100+15*k,100+15*k);
             g.setColor(c);
             g.drawRect((X+SIZE*y)+k, (Y+SIZE*x)+k, SIZE-2*k, SIZE-2*k);
        }
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect((X+SIZE*y)+5, (Y+SIZE*x)+5, SIZE-9, SIZE-9);
      //重绘游戏进程	
		   if(RL.size()>0){
			  for(int i=0;i<RL.size();i++){
				    //获取数组队列中的值
			        Mine m=(Mine)RL.get(i);					        
			        int r=m.getRow();
			        int l=m.getList();		
	    	        //调用绘制图片的方法
	    	        drawPicture(r,l);	
			    }
			}
        
	}
	
	public void drawPicture(int x,int y){
		int t=MineArea[x][y];
		if(t==1){
			
			g.drawImage(icon1.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==2){
			
			g.drawImage(icon2.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==3){
			
			g.drawImage(icon3.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==4){
			
			g.drawImage(icon4.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==5){
			
		g.drawImage(icon5.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==6){
			
		g.drawImage(icon6.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==7){
			
		g.drawImage(icon7.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==0){
		
			g.drawImage(icon0.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}
		else if(t==100){
			g.drawImage(im.getImage(), (X+SIZE*y+1), (Y+SIZE*x+1), null);
		}

		 
	}

}

(6)雷区位置的类,用作存储已显示图片的位置的数据
public class Mine {
	int row;
	int list;
	
	public Mine(int row,int list){
		this.row=row;
		this.list=list;
	}
	
	public int getRow(){
		return row;
	}
	
	public int getList(){
		return list;
	}

}


(7)记录雷区位置的数组队列
public class RecordList {
	private int size=0;
	private Mine []array;
	
	public RecordList(){
		array=new Mine[0];
	}
	public RecordList(int length){
		array=new Mine[length];
	}
	//添加元素的方法
	public void add(Mine stu){
		//實例化一個學生數組長度為原數組加1
		Mine []tempArray=new Mine[size+1];
		//把原數組中的元素賦給新數組
		for(int i=0;i<size;i++){
			tempArray[i]=array[i];
		}
		//把新的元素繼續賦值
		tempArray[size]=stu;
		array=tempArray;
		size++;
		
	}
	public void add(Mine stu,int index){
		if(index>=0 && index<size){
		//實例化一個學生數組長度為原數組加1
		Mine []tempArray=new Mine[size+1];
		//把原數組中的元素賦給新數組
		for(int i=0;i<index;i++){
			tempArray[i]=array[i];
		}
		tempArray[index]=stu;
		//繼續把原數組中的元素賦給新數組
		for(int i=index+1;i<size+1;i++){
			tempArray[i]=array[i-1];
		}
		array=tempArray;
		size++;	
		}
	}
	
	//更新元素
	public Object set(Mine stu,int index){
		if(index>=0 && index<size){
			Mine s=array[index];
			//實例化一個學生數組長度為原數組長度
			Mine []tempArray=new Mine[size];
			//把原數組中的元素賦給新數組
			for(int i=0;i<index;i++){
				tempArray[i]=array[i];
			}
			tempArray[index]=stu;
			//繼續把原數組中的元素賦給新數組
			for(int i=index+1;i<array.length+1;i++){
				tempArray[i]=array[i];
			}
			array=tempArray;
			return s;
			}
		else 
			return null;	
		
	}
	//删除元素
	public Object remove(Mine stu){
		int t=0;
		//實例化一個學生數組長度為原數組減1
		Mine []tempArray=new Mine[size-1];
		//查找原數組中的元素為stu的位置
		for(int i=0;i<size;i++){
			if(array[i].equals(stu)){
				t=i;
				break;		
			}
		}//把原數組中的元素賦給新數組
		if(t>0){
		for(int i=0;i<t;i++){
	    	tempArray[i]=array[i];	
		}
		
		//繼續把原數組中剩餘的元素賦給新數組
		for(int i=t;i<size-1;i++){
			tempArray[i]=array[i+1];
		}
		}
			
		array=tempArray;
		size--;
		return null;
	}
	//移除元素的方法
	public Object remove(int index){
		if(index>=0 && index<size){
			Mine s=array[index];
			//實例化一個學生數組長度為原數組減1
			Mine []tempArray=new Mine[size-1];
			//把原數組中的元素賦給新數組
			for(int i=0;i<index;i++){
				tempArray[i]=array[i];
			}
			//繼續把原數組中剩餘的元素賦給新數組
			for(int i=index;i<size-1;i++){
				tempArray[i]=array[i+1];
			}
			array=tempArray;
			size--;	
			return s;
			}
		else 
			return null;
	}
	//检查元素是否存在
	public boolean check(Mine c){
		int cnt=0;
		for(int i=0;i<size;i++)
			if(array[i].getRow()==c.getRow() && array[i].getList()==c.getList()){
				cnt=1;
				break;
			}
		if(cnt==0)
		    return false;
		else 
			return true;
								
	}
	//获取元素
	public Object get(int index){
		return array[index];
		
	}
	//获取元素总数
	public int size(){
		return size;
	}
}


界面效果截图:



  • 大小: 96.2 KB
  • 大小: 77.6 KB
  • 大小: 112.9 KB
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值