⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mi.java

📁 迷宫,它会自动认路且玩家可以控制等级,如果玩家迷路
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * @(#)迷宫.java
 *
 * Sample Applet application
 *
 * @aut  ******************************************hor 
 * @version 1.00 08*********************       ******************* /04/26
 */
 
 import javax.swing.JApplet.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.Timer;
 import java.util.*;
 


public class Mi extends JApplet implements KeyListener {
	Button 加,减,产生迷宫,提示,演示,停止;
	int n=10,width=45,key,peoplex=1,peopley=1,keylist=0,原点i=0,原点j=0,nn=10;
	char[][] 标记;
	int[][] mark;
	Image grass,people,grassUP,grassRight,grassFloor,offScreen;
    Image updirection,downdirection,leftdirection,rightdirection;
	Graphics drawoffScreen;
	Graphics2D page_2d;
	Label label;
	Panel panel;
	int count=0,delay=300;
	按钮监听器 监听器;
    int purpose=0;
    int direction=0,是否提示=0;
    Timer timer;
	
	
	//---------------------------------------------------------------------------
	//以下为init()方法
	//
	//--------------------------------------------------------------------------
	public void init() {
		grass=getImage(getCodeBase(),"grass.gif");
		grassUP=getImage(getCodeBase(),"grassUP.gif");
		grassRight=getImage(getCodeBase(),"grassRight.gif");
		people=getImage(getCodeBase(),"people.gif");
		grassFloor=getImage(getCodeBase(),"grassFloor.gif");
        updirection=getImage(getCodeBase(),"updirection.gif");
        downdirection=getImage(getCodeBase(),"downdirection.gif");
        leftdirection=getImage(getCodeBase(),"leftdirection.gif");
        rightdirection=getImage(getCodeBase(),"rightdirection.gif");
        
        
		label=new Label("关数:"+(nn-9));   //此标签用于显示谜宫的复杂度
		加=new Button("增加关数");
		减=new Button("降低关数");
		产生迷宫=new Button("产生迷宫");
        提示=new Button("方向提示");
        演示=new Button("自动行走");
        停止=new Button("行走停止");
        
        
        Listen演示 listen演示=new Listen演示();//生成下面的timer演示的监听器
        timer=new Timer(delay,listen演示);
       
		
		加.addKeyListener(this);           //各按钮添加键盘事件,当发生键盘事件时就会接收到
		产生迷宫.addKeyListener(this);
		减.addKeyListener(this);
        提示.addKeyListener(this);
        演示.addKeyListener(this);
        停止.addKeyListener(this);
        
		
		
		监听器=new 按钮监听器();  //此为下面各按钮的按钮监听器,因为按钮处于容器的最前面,因此按钮能监听添得到
		加.addActionListener(监听器);
		减.addActionListener(监听器);
		产生迷宫.addActionListener(监听器);
        提示.addActionListener(监听器);
        演示.addActionListener(监听器);
        停止.addActionListener(监听器);
        
		
		panel=new Panel();        //生成一个面板,主要用于加入加,减,产生迷宫,提示,演示,停止的按钮
		panel.setPreferredSize(new Dimension(50,60));
	
		setLayout(new BorderLayout());//设置边界布局方法
		add(panel,BorderLayout.EAST); //把面板放置在右边
		
		加.setBackground(Color.yellow);  //各按钮加上颜色
		减.setBackground(Color.yellow);
		产生迷宫.setBackground(Color.yellow);
		提示.setBackground(Color.pink);
		演示.setBackground(Color.cyan);
		停止.setBackground(Color.cyan);		
		
		panel.add(label);  //分别加入标签与按钮 
		panel.add(加);
		panel.add(减);
		panel.add(产生迷宫);
		panel.add(new Label());
		panel.add(提示);
		panel.add(new Label());
		panel.add(演示);
		panel.add(停止);
		
		offScreen=createImage(1000,1000);  //生成一个次画面
		drawoffScreen=offScreen.getGraphics();
	
		生成迷宫();    //调用该方法可以自动生成一个初始化的谜宫
		
		
		
	}
	
	
	//-------------------------------------------------------------------------
	//这里是paint()方法,用于画图
	//
	//---------------------------------------------------------------------------

	public void paint(Graphics g)
	 {
		drawoffScreen.clearRect(0,0,(100+2)*width,(50+2)*width);
		                               //clearRect方法用于清除次画面里面的内容
		drawoffScreen.setColor(Color.white);
		drawoffScreen.fillRect(0,0,(100+2)*width,(50+2)*width);
		                                                    //使次画面变白
		画出迷宫(drawoffScreen);                            //画出迷宫
		画出人(drawoffScreen);                              //画出人所在处
        提示方向(drawoffScreen);
        调整(drawoffScreen);  /*"调整"方法,是用于使镜头始对应着小人,
                                 就算小人出了视野,也可以通过此方法
                                 能看到它的所在处*/ 
                                                              
		g.drawImage(offScreen,0,0,this);//把次画面"贴上"原主画面上
		
	 }
	 
	 
	 
	 
	 
    //------------------------------------------------------------------------
    //按钮事件监听器
    //
    //--------------------------------------------------------------------------
    private class 按钮监听器 implements ActionListener
      {
    	public void actionPerformed(ActionEvent event){
    		Object source=event.getSource();//得到按钮的事件源
    		
    		if(source==加)  //当按钮"加"被按时,就令n增一,增加复杂度,然后在标签里显示出
    		   {
    		   	if(nn<=40)nn++; 
    		   	     /*nn主要用存储通过按钮或者通过游戏自动升级后的级数,避免在
    	              游戏过程中突然改变级数变量n而出现程序运行错误,通过这种方法只有
    	              当按了"生成迷宫"按钮后才能改变n的值,增加程序的安全性
    	              */
    	        label.setText("关数:"+(nn-9));
    		   }
    		if(source==减)  
    		   {
    		   	if(nn>10)nn--;
    		    label.setText("关数:"+(nn-9));
    		   }
    		if(source==产生迷宫) 
    		   生成迷宫();
    		   
            if(source==提示)   
                   {
                   	for(int i=1;i<=n;i++)    
                   	   for(int j=1;j<=n;j++)
                   	   mark[i][j]=0;
                   	   
                    purpose=0;  //purpose=0表示还没有找到目标,当purpose=1时,就表示已经找到目标了
                    direction=1;//direction表示方向,当direction=0时就表示初始化,没有方向
                                //direction=1,2,3,4分别表示向上,下,左,右
                    find(peoplex,peopley);//从人物当前的位置做起,进行递归
                    是否提示=1; //用"是否提示"来控制提示是否显示出来,当为1时,就显示出来,否则就不显示出
                    repaint();
                    }
            if(source==演示)
                  timer.start();
                  
            if(source==停止)
                  timer.stop();
    	}
    }
    
    
    
    
    //----------------------------------------------------------------------------
    //生成迷宫
    //
    //--------------------------------------------------------------------------
    private void 生成迷宫(){
    	int Si,Sj,Ei,Ej;
    	
    	n=nn;        /*nn主要用存储通过按钮或者通过游戏自动升级后的级数,避免在
    	              游戏过程中突然改变变量n而出现程序运行错误,通过这种方法只有
    	              当按了"生成迷宫"按钮后才能改变n的值,增加程序的安全性
    	              */
    	             
		timer.stop();//主要防止玩家操作错误,保证当生成一个迷宫数组时,机械猫是保持不动的
		peoplex=peopley=1;//此为人所在之处的坐标
    	Si=Sj=1;
    	Ei=Ej=n;
    	标记=new char[n+2][n+2];  //标记数组主要是否记录迷宫哪些地方是边界,哪些地方在哪一个方向上有通路
    	mark=new int[n+2][n+2];   //存在加2的原因是因为画面上包括了边界的原因
    	
    	for(int i=0;i<=n+1;i++)
    	  for(int j=0;j<=n+1;j++)
    	  { 
    	    int mm=n+1;
    	    
    	  	if(i==0||j==0||i==mm||j==mm)     
    	  	   {//边界处用字母w表示,并且用mark数组标记为1,此后在画出迷宫的方法中将在相对应的坐标点画上边界
    	  	   	标记[i][j]='w';mark[i][j]=1;
    	  	   }
    	  	else 
    	  	   {
    	  	   	标记[i][j]='o';mark[i][j]=0;//如果不是边界的,则用字母o标示,
    	  	   	                            //此后在画出迷宫的方法中将在相对应的坐标点画上"上墙与右墙"
    	  	   }
    	  }
       标记[Ei][Ej]='r';//此处为坐标(n,n)处,r表示没有右墙,这是合理的,因为它是出口,自然没有右墙
       genmaze(Ei,Ej);  //递归生成迷宫数组"标记"
       标记[Ei+1][Ej]='e';//此处为坐标(n+1,n)处,为出口通道,标记为e,即表示上,右墙都没有
       
       
       repaint();
    }
    
    //--------------------------------------------------------------------------
    //此方法为genmaze()方法,产生递归,生成一个迷宫数组
    //
    //---------------------------------------------------------------------------
    private void genmaze(int i,int j){
    	int k;
    	mark[i][j]=1;//迷宫数组中已经遍历过的地方用mark[i][j]=1标记
    	
    	while(mark[i][j+1]==0||mark[i][j-1]==0
    	    ||mark[i-1][j]==0||mark[i+1][j]==0) 
    	     {//--------------------------------------------------------------
    	      //如果坐标(i,j)处或上,或下,或左,或右尚没有遍历,则执行下列程序
    	      //-----------------------------------------------------------------
    	     k=(int)(4*Math.random()+1);       //生成一个1,2,3,4之间的随机数 
    	     
    	     if(k==1&&mark[i][j-1]==0) //当指示向上走且坐标的上面没有遍历时,则向上走
    	        {
    	         if(标记[i][j]=='o')   
    	           {//-----------------------------------------------------------
    	           	//当当前位置不能通向上边或者右边时,则标记为u,表示此处可以通向上面,拆掉上墙
    	           	//--------------------------------------------------------
    	           	标记[i][j]='u';
    	           }  
    	         else 
                    {//---------------------------------------------------------
                     //当当前位置没有右墙(r表示不存在右墙)时,则标记为e,即表示上,右墙都没有
                     //---------------------------------------------------------
                     if(标记[i][j]=='r')标记[i][j]='e';
                    }
    	          genmaze(i,j-1);//往上遍历
    	         } 
    	         
    	     if(k==2&&mark[i][j+1]==0)//向下走
    	        {
    	        标记[i][j+1]='u';  //因为要往下走,因此要把坐标(i,j+1)处的上墙拆掉
    	        genmaze(i,j+1);     //往下遍历
    	        }
    	        
    	        
    	     if(k==3&&mark[i-1][j]==0)//向左走
    	        {
    	        标记[i-1][j]='r';    //因为要向左走,因此要把坐标(i-1,j)处的右墙拆掉
    	         genmaze(i-1,j);      //向左遍历
    	        }
    	        
    	        
    	     if(k==4&&mark[i+1][j]==0)//向右走
    	        {
    	        if(标记[i][j]=='o')标记[i][j]='r';  //如果上右墙都有,则拆右墙
    	         else 
    	           {
    	           	if(标记[i][j]=='u')标记[i][j]='e';
    	           	   //如果没有上墙,则标记e,表示上右墙都没有
    	           }
    	         genmaze(i+1,j);//向右遍历
    	        }
    	      
    	      
    	     }
    }
    
    
    
    //-------------------------------------------------------------------------------
    //以下为 画出迷宫()方法
    //
    //-------------------------------------------------------------------------------
    
    public void 画出迷宫(Graphics page)
    {  
        page.clearRect(0,0,(100+2)*width,(50+2)*width);
    	//---------------------------------------------
    	//在已经生成迷宫的数组的基础上,画出相对应的迷宫图
    	//--------------------------------------------------- 
    	 
        for(int i=0;i<=n+1;i++)
          for(int j=0;j<=n+1;j++)
            {
             int x=i*width;
             int y=j*width;
             
             if(标记[i][j]=='r')
                {page.drawImage(grassUP,x,y,width,width,this);//如果是右走,则画上墙
                }
             if(标记[i][j]=='u')
                {page.drawImage(grassRight,x,y,width,width,this);//如果是上走,则画右墙
                }
             if(标记[i][j]=='o')
                {page.drawImage(grassFloor,x,y,width,width,this);//上右墙都有,则画上,右墙
                }
             if(标记[i][j]=='w')
                {page.drawImage(grass,x,y,width,width,this);////如果是外墙,则画上边界墙
                } 
            }
       
    }
    
    
    //---------------------------------------------------------------------------
    //以下为键盘事件的方法
    //
    //--------------------------------------------------------------------------
    public void keyTyped(KeyEvent e){};
    public void keyReleased(KeyEvent e){};
    public void keyPressed(KeyEvent e)
       {
       	key=e.getKeyCode();//getKeyCode方法得到按键事件源
       
        if(key==KeyEvent.VK_RIGHT)
           {
           	if(向右()) //向右方法是处理右边是否存在通道而设的,存在通道的话就返回true
               peoplex++;//人的横坐标向右增一,即peoplex自增1
           }
        if(key==KeyEvent.VK_LEFT)//向左走
           {
           	if(向左())
               peoplex--;
           }
        if(key==KeyEvent.VK_UP)//向上走

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -