`
hmeng
  • 浏览: 15775 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

扫雷小游戏的设计与实现

阅读更多
         完成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
分享到:
评论

相关推荐

    原生js实现扫雷小游戏

    【原生JS实现扫雷小游戏】是一篇关于利用JavaScript编程语言设计并实现经典电脑游戏“扫雷”的技术文章。在JavaScript的世界里,开发者可以利用HTML和CSS构建游戏界面,然后用JavaScript来处理游戏逻辑和交互。这篇...

    android studio 安卓扫雷小游戏源代码

    android studio 安卓扫雷小游戏源代码 运用Android 制作扫雷游戏,制作简单,没有复杂的代码,对于熟悉Android的页面布局,跳转有帮助理解=。这个扫雷还有点瑕疵,广大程序员们可以对其修改和完善。

    基于Java扫雷游戏的设计与实现

    Java扫雷游戏的设计与实现 摘 要 扫雷这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏变得越来越让人爱不释手了,简单的玩法在加上一个好看的游戏界面,每一处的细节都体现了扫雷的...

    python扫雷游戏设计(课程设计版)

    【Python扫雷游戏设计】是计算机科学与工程学院的一次课程设计任务,旨在培养学生面向对象程序设计的能力,提高代码质量和效率。在这个项目中,学生需要使用Python语言来实现经典的游戏——扫雷。通过这个设计,学生...

    毕业论文设计-基于C++的扫雷游戏设计与实现.doc

    "基于C++的扫雷游戏设计与实现" 本资源是关于基于C++的扫雷游戏设计与实现的毕业论文设计。扫雷游戏是一款经典的小游戏,广受欢迎。论文中详细介绍了游戏的设计与实现过程,包括游戏的总体分析与设计、扫雷游戏的...

    扫雷小游戏课程设计.pdf

    综上所述,扫雷小游戏课程设计涵盖了从需求分析到系统实现的完整流程,旨在培养学生的编程技能,同时提供一个具有挑战性和趣味性的休闲游戏。开发过程中,学生将学习到如何在Java环境下构建图形用户界面,处理用户...

    C++实现基于Qt的课程设计项目扫雷小游戏源码(高分项目).zip

    C++实现基于Qt的课程设计项目扫雷小游戏源码(高分项目).zipC++实现基于Qt的课程设计项目扫雷小游戏源码(高分项目).zipC++实现基于Qt的课程设计项目扫雷小游戏源码(高分项目).zipC++实现基于Qt的课程设计项目...

    C语言扫雷小游戏简单实现

    【标题】"C语言扫雷小游戏简单实现"揭示了这个项目是使用C语言编写的一款经典游戏——扫雷的简易版本。扫雷游戏的目标是通过逻辑推理和试错,找出雷区中的所有非雷格子,避免触雷。在这个C语言实现的版本中,开发者...

    Java课程设计报告-扫雷小游戏

    1.1•扫雷小游戏的基本要求………………………………………. 1.2 需求实现的主要功能…………………………………………... 2•需求分析………………………………………………………….. 2.1 扫雷区域的布局设计……...

    html实现扫雷小游戏

    html实现扫雷小游戏源码,实现windows系统的扫雷的基本功能,直接点击index.html运行。具体效果展示地址:https://blog.csdn.net/weixin_43151418/article/details/127886480

    C语言结合Easyx库实现扫雷小游戏

    通过以上分析,我们可以看到,用C语言结合Easyx库实现扫雷小游戏,既是对C语言编程能力的锻炼,也是对游戏逻辑设计和图形界面开发的综合实践。这样的项目不仅提升了编程技巧,还培养了问题解决和项目管理的能力。...

    基于Java的扫雷小游戏的设计与实现

    基于Java的扫雷小游戏的设计与实现

    C语言课程设计扫雷小游戏

    本课程设计是采用C/C++语言开发扫雷游戏,该系统运行在MS-DOS命令行模式下。本课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力...

    android studio 扫雷小游戏

    运用Android 制作扫雷游戏,制作简单,没有复杂的代码,对于熟悉Android的页面布局,跳转有帮助理解=。这个扫雷还有点瑕疵,广大程序员们可以对其修改和完善。

    仿windows扫雷小游戏java完整实现.zip

    “仿Windows扫雷小游戏Java完整实现.zip”是一个使用Java编程语言开发的项目,旨在重现经典的扫雷游戏。这个项目不仅提供了一个实践平台,让开发者学习如何用面向对象编程的方法设计和实现一个具有用户交互性的游戏...

    C语言实现扫雷小游戏-扫雷.zip

    《C语言实现扫雷小游戏详解》 ...总的来说,"C语言实现扫雷小游戏"是一个既有趣又有挑战性的学习资源,它将理论知识与实际应用相结合,帮助初学者在实践中提高技能,为今后的编程生涯奠定坚实基础。

    学习c#,模仿做的一个 扫雷小游戏

    "学习c#,模仿做的一个 扫雷小游戏" 这个标题表明了这个项目是一个基于C#编程语言开发的扫雷游戏,是作者为了学习C#而进行的一个实践项目。扫雷游戏是一款经典的逻辑推理游戏,通过在网格中标记雷区来完成挑战,通常...

    vb扫雷游戏的设计与开发毕业论文

    【标签】"vb 扫雷游戏毕业论文设计+答辩ppt+源代码"进一步强调了这个项目的关键组成部分,即VB编程、游戏设计和开发过程的记录。VB是一种流行的事件驱动编程语言,非常适合初学者学习和快速开发用户界面丰富的应用,...

    资源专区-课程设计-编程作业-Java扫雷游戏的设计与实现

    Java扫雷游戏的设计与实现

    Java扫雷游戏的设计与实现.rar

     玩家就需要通过这些数字来判断雷的位置,将是雷的格子标记为小红旗。若玩家认为已标记的格子时错误的,可以再次右击该格子来取消标记。  当某一格子被标记时,对于该格子的单击操作是无效的(防止玩家误点击导致...

Global site tag (gtag.js) - Google Analytics