?? mi.java
字號:
/**
* @(#)迷宮.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 + -