📄 maze.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
import javax.swing.*;
public class Maze extends Applet implements Runnable,KeyListener,
MouseWheelListener,
MouseListener,
MouseMotionListener{
static int X=0,Y=0;//控制地图的移动
int key;//保存键盘的输入键
int MOUSE_POSITION;//鼠标按下的位置(0:按钮区 1:其他区)
int MOUSE_PRESSED_START;//记录鼠标是在哪按下的(0:按钮区 1:其他区)
int appletWidth,appletHeight;
int gridX,gridY;//迷宫格数
int array[][];//迷宫数组
int outX,outY;//出口位置
int imageWidth,imageHeight;//角色图象的宽和高
int floorW;
int imageX,imageY;//角色的坐标
int sx;//从图片中切角色的横坐标
static int size=1;//控制地图的大小
int bw,bh;//按钮的长宽
boolean gameStart=false;//游戏开始的标志,在按下创建迷宫数组之后设置为true
boolean canMove;//角色能否移动的标志
boolean isMoveCharacter=true;//用于判断移动地图还是角色
boolean isDead=false;//判断是否死亡,时间到就死了
boolean isPass=false;//判断是否过关
boolean isStart=false;//判断显示开始画面还是开始游戏
Image b1,b2;//模拟按钮
Image currentImage;//选择绘制哪个按钮图片
Image block1,block2,character;//障碍物
Image floor;
Image cursor;//自定义光标的图片
Image menu;//最小化图标中的图像
Cursor myCursor;
Toolkit toolkit;
Image offScreen,startOffScreen;
Graphics drawoffScreen,drawStartOffScreen;
MediaTracker MT;
//Button newBtn;//产生新地图的按钮
char direction='R';//角色的方向
Thread thread;//动画线程
Sprite sprite;//角色对象
time t;//测试时间类
StartScreen start;/**//*******************************/
Panel p_north,p_center;
JFrame frame;
public void init(){
addKeyListener(this);//加入键盘的操作
addMouseWheelListener(this);
addMouseListener(this);
addMouseMotionListener(this);
toolkit=getToolkit();//获得此组件的工具包
cursor=getImage(getDocumentBase(),"cursor.jpg");
setBackground(Color.white);
appletWidth=getSize().width;
appletHeight=getSize().height;
array=new int[1000][1000];//设大点免得越界了
gridX=11;gridY=11;
sx=0;//把开始切图位置设置为0
block1=getImage(getDocumentBase(),"BLOCK1.GIF");
block2=getImage(getDocumentBase(),"BLOCK2.GIF");
floor=getImage(getDocumentBase(),"FLOOR.JPG");
character=getImage(getDocumentBase(),"CHARACTER.GIF");
b1=getImage(getDocumentBase(),"b1.jpg");
b2=getImage(getDocumentBase(),"b2.jpg");
menu=getImage(getDocumentBase(),"menu.gif");
currentImage=b1;//按钮开始设置为弹起
offScreen=createImage(appletWidth,appletHeight);
drawoffScreen=offScreen.getGraphics();
startOffScreen=createImage(500,400);
drawStartOffScreen=startOffScreen.getGraphics();
MT=new MediaTracker(this);
MT.addImage(block1,0);
MT.addImage(block2,0);
MT.addImage(floor,0);
MT.addImage(character,0);
MT.addImage(b1,0);
MT.addImage(b2,0);
MT.addImage(cursor,0);
MT.addImage(menu,0);
try{
showStatus("图片加载中...");
MT.waitForAll();
}catch(InterruptedException e){}
//创建自己的光标
try{
myCursor=toolkit.createCustomCursor(cursor,new Point(0,0),"cursor");
}catch(IndexOutOfBoundsException e){}
//设置自己的光标,如果要在点击时改变光标的形态
//就在鼠标的一些事件中使用setCursor()方法
setCursor(myCursor);
floorW=floor.getWidth(this);//在加载之前是获取不了的,所以只有在加载之后获取这些数据
imageWidth=character.getWidth(this)/3;//因为角色图象是放在一起的的所以要分别除以3,4
imageHeight=character.getHeight(this)/4;
//角色的开始位置(但是要注意它不是绘制在数组中的入口(所谓入口就是数值为4的位置))
//它只是让人看到角色的脚是在入口位置
imageX=floorW+floorW;
imageY=floorW/3+floorW;
bw=b1.getWidth(this)/size;
bh=b1.getHeight(this)/size;
//初始化角色
sprite=new Sprite(imageX,imageY,imageWidth,imageHeight,array);
t=new time(this);
start=new StartScreen(this,block1,block2,character,floor,floorW,
imageWidth,imageHeight);/**//***********************/
frame=new JFrame("迷宫岛");
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(menu);
frame.setLayout(new BorderLayout());
p_north=new Panel();
p_north.add(t.l_time);
p_center=new Panel(new CardLayout());
p_center.add(this,"maze");
frame.add(p_north,"North");
frame.add(p_center,"Center");
frame.setSize(appletWidth,appletHeight);
frame.show(true);
}
public void start(){
thread=new Thread(this);
thread.start();
}
public void stop(){
thread=null;
}
public void update(Graphics g){
paint(g);
}
//产生迷宫数组
public void newarray(int i,int j){
array[i][j]=4;//把此位置设定为可通行的
int next;
//当还有没设定的就一直循环
while(array[i][j+2]==1||array[i+2][j]==1||array[i][j-2]==1||array[i-2][j]==1||
array[i][j+2]==2||array[i+2][j]==2||array[i][j-2]==2||array[i-2][j]==2){
next=(int)(Math.random()*4+1);//随即的走动方向
switch(next){
//往右
case 1:if(array[i][j+2]==1||array[i][j+2]==2){//如果右边没设定
array[i][j+1]=4;//把往右走的障碍物清除
array[i][j+2]=4;
newarray(i,j+2);
}break;
//往下
case 2:if(array[i+2][j]==1||array[i+2][j]==2){
array[i+1][j]=4;
array[i+2][j]=4;
newarray(i+2,j);
}break;
//往左
case 3:if(array[i][j-2]==1||array[i][j-2]==2){
array[i][j-1]=4;
array[i][j-2]=4;
newarray(i,j-2);
}break;
//往上
case 4:if(array[i-2][j]==1||array[i-2][j]==2){
array[i-1][j]=4;
array[i-2][j]=4;
newarray(i-2,j);
}break;
}
}
}
public void paint(Graphics g){
if(isStart){
g.drawImage(offScreen,0,0,this);
if(isDead){
paintString("Time Over",g);
try{
Thread.sleep(3000);
}catch(InterruptedException ie){}
t.allTime-=20;
sprite=new Sprite(imageX,imageY,imageWidth,imageHeight,array);
initializeGame();
isDead=false;
}
//当走到出口时显示祝贺词,并且进入下一关
if(sprite.indexI==gridX-3&&sprite.indexJ==gridY-2){
System.out.println("新建");
isPass=true;//游戏过关
paintString("Congratulation",g);
try{
Thread.sleep(3000);
}catch(InterruptedException ie){}
gridX+=10;
gridY+=10;
sprite=new Sprite(imageX,imageY,imageWidth,imageHeight,array);
initializeGame();
}
}
else {
start.paintScreen(drawStartOffScreen);
g.drawImage(startOffScreen,0,0,this);
}
}
public void run(){
//floorW/=size;//如果是在这改变尺寸就回等下面的while循环执行完了才改变
//bw/=size;//也就是在结果中所看到的它不会马上改变,在把窗口最小化后还原才改变
//bh/=size;//因为在最小化后它会重新执行所有的程序也就会执行到它了
//刚刚开始我在init()方法中想试图改变它但是不管怎样它都不会改变
//我想是因为init()只执行一次的原因
while(true){
if(isStart){
drawoffScreen.clearRect(0,0,appletWidth,appletHeight);
drawoffScreen.drawImage(currentImage,0,0,bw/size,bh/size,this);//绘制按钮
//如果角色在左上角,就移动角色。否则就移动地图
if(isMoveCharacter){
paintMap(X,Y);
//绘制角色
switch(direction){
//如果按键是往右,就选择图中第一排的来绘制(也就是下面的sx后面的0,它表示第一排)
//而随着sx的变化绘制的角色也就看起来在动了
case 'U':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,0,
sx+sprite.SizeW,sprite.SizeH,this);break;
case 'D':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,sprite.SizeH*2,
sx+sprite.SizeW,sprite.SizeH*3,this);break;
case 'L':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,sprite.SizeH*3,
sx+sprite.SizeW,sprite.SizeH*4,this);break;
case 'R':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,sprite.SizeH,
sx+sprite.SizeW,sprite.SizeH*2,this);break;
}
repaint();
//让角色看起来在走动
sx+=sprite.SizeW;
if(sx>sprite.SizeW*2){
sx=0;
}
try{
Thread.sleep(200);//每隔200毫秒重绘一次
}catch(InterruptedException e){}
}
//移动地图(要往反方向移动)
else {
paintMap(X,Y);
//绘制角色
switch(direction){
//如果按键是往右,就选择图中第一排的来绘制(也就是下面的sx后面的0,它表示第一排)
//而随着sx的变化绘制的角色也就看起来在动了
case 'U':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,0,
sx+sprite.SizeW,sprite.SizeH,this);break;
case 'D':drawoffScreen.drawImage(character,sprite.LcX/size,sprite.LcY/size,
(sprite.LcX+sprite.SizeW)/size,(sprite.LcY+sprite.SizeH)/size,sx,sprite.SizeH*2,
sx+sprite.SizeW,sprite.SizeH*3,this);break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -