📄 engine.java
字号:
try {
canvas.imgBg = Image.createImage(
"/images/bg1.png");
canvas.imgMain = Image.createImage(
"/images/main.png");
canvas.imgItem = Image.createImage(
"/images/item.png");
}
catch (IOException ex1) { System.out.println("level up pics loaded error");}
}
else if(animationFrame==21){
animationFrame=0;
level++;//升一级
state=LEVEL_PREPARE;
}
*/
break;
case GAME_OVER://过关
break;
} //switch(state)
System.gc();
} //while(true)
}
/**
* reFire 重新燃烧灭掉的楼层。困难模式下还将会判断是否把火
*
* @param level int 当前关数
*/
public void refire(int level) {
for(int i=0;i<7;i++){
if(fireState[i]<10){//已经灭
if((System.currentTimeMillis()-fireStateChanged[i])>3000L){ //灭掉的火3秒后重新燃烧
fireState[i]=10;
fireStateChanged[i]=System.currentTimeMillis();
}
}
else if(difficulty==1&&fireState[i]<20){//小火,困难模式
if((System.currentTimeMillis()-fireStateChanged[i])>10000L){ //小火10秒后变为大火
fireState[i]=20;
fireStateChanged[i]=System.currentTimeMillis();
alert=true;//警报标志
}
}
}
}
/**
* generateLevel根据游戏模式和难度和当前关数产生下一级关卡。
* 主要是调整map数组内容。!!!注意使每关开局时无法生成路径
* 记录当前开始时间、剩余时间为200,开局分数(为保存使用)
*
* @param level int需要产生的下一级关数
*/
public void generateLevel(int level) {
leftTime = 200;
leftFires=9+level;
for (int i = 0; i < 7; i++) {//产生火焰(无或小)
fireState[i] = Math.abs(rnd.nextInt()) % 20;
fireStateChanged[i]=System.currentTimeMillis();
}
}
/**
* public void scanMap()
* 扫描地图
*/
public void scanMap() {
int i,j;
Pipe temp;
boolean gotPath = false;
for(i=0;i<7;i++){//清空上次搜索信息
for(j=0;j<7;j++){
map[i][j].state=1;
map[i][j].atPathDepth=0;
}
}
Stack stack = new Stack();
path.removeAllElements(); //先将上次搜索的清空
for (i = 0; i < 7; i++) { //从水管方向开始找通路,经过时将pipe状态置为2,如果找到,将经过的pipe放入path中
System.out.println("Searching Water Start at "+i+",0");
gotPath = findPath(stack, i, 0, 1, 2);
if (gotPath) { //找到一条可通路径,则将stack中的pipe取出,放在path中
while (!stack.isEmpty()) {
temp = (Pipe) stack.elementAt(0);
if (!path.contains(temp)) { //防止重复加入
path.addElement(temp);
}
stack.removeElementAt(0);
}
}
else { //未找到一条可通路径
stack.removeAllElements(); //此次stack置空
}
}
for (i = 0; i < 7; i++) { //从火的方向找路(其实只是剩余未通的火),经过时将pipe状态置为3
if(map[i][6].state==1){
System.out.println("Searching Fire Start at " + i + ",6");
findPath(stack, i, 6, 1, 3);
}
}
stack = null;
mapscanned = true; //扫描过后置标志
}
/**
* public boolean findPath(int i, int j, int depth,int state)
* 根据不同的起始点搜索可通路径:如果找到可达路径,返回true
* 从map[i][0]水管处开始递归搜索可到达map[i][6]火的路径,搜索到的话返回true
* 搜索不到的话会置经过的路径状态为state=2连接水管
* 从火开始搜索路径,经过的路径会置state=3连接火
*
* @param stack java.util.Stack 此次搜索用到的栈
* @param i int 此次搜索起始点i
* @param j int 此次搜索起始点j
* @param depth int 当前搜索火路深度
* @param state int 从什么状态开始搜索的。2表示从水开始的,3表示从火开始的
* @return boolean 如果找到可通路径,返回true
*/
public boolean findPath(Stack stack, int i, int j, int depth, int state) {
System.out.println("---step in "+i+","+j);
int nexti = 0, nextj = 0;
boolean[] gotPath = new boolean[4];
map[i][j].state = state; //当前节点传染新状态
map[i][j].atPathDepth = depth; //当前节点在路径中的深度
stack.addElement(map[i][j]); //当前节点入栈
if (map[i][j].type == 5&&state!=3) { //如果当前节点是火,直接搜索结束,找到了路径
return true;
}
for (int d = 0; d < 4; d++) { //四个方向挨个找
switch (d) { //每个方向的下一个与之连接pipe的位置
case Pipe.UP:
nexti = i - 1;
nextj = j;
break;
case Pipe.LEFT:
nexti = i;
nextj = j - 1;
break;
case Pipe.DOWN:
nexti = i + 1;
nextj = j;
break;
case Pipe.RIGHT:
nexti = i;
nextj = j + 1;
break;
}
if (isConnect(i, j, d, nexti, nextj)) {
gotPath[d] = findPath(stack, nexti, nextj, depth + 1, state);
}
}
return gotPath[0] || gotPath[1] || gotPath[2] || gotPath[3]; //如果有任意方向找到通路就会返回true
}
/**
* public boolean isConnect(int i, int j, int d, int nexti, int nextj)
* 测试从map(i,j)到map(nexti,nextj)是否可达
* 包括nexti,nextj的越界检查,和map(nexti,nextj)是否depth较小,是否未遍历过
* 遍历过就不再走回头路了
* 当前depth较小的话可以改写pipe原本depth。因为也许从另一个水源到达本pipe较近
*
* @param i int
* @param j int
* @param d int map(i,j)的探测方向
* @param nexti int
* @param nextj int
* @return boolean 合法且可达,返回true
*/
public boolean isConnect(int i, int j, int d, int nexti, int nextj) {
if (nexti < 0 || nexti > 6 || nextj < 0 || nextj > 6) { //越界直接返回false
return false;
}
int nextd = (d + 2) % 4; //得到和当前方向相连接的方向
if (map[i][j].path[d] && map[nexti][nextj].path[nextd]) { //是否连通
if (map[nexti][nextj].atPathDepth == 0) { //还没扫描过
return true;
}
else { //对应块已经扫描过
//判断当一个水源连到另一个水源时,是否需要根据pipe离水源的最近距离改写depth
if ((map[i][j].state==3)||(map[i][j].atPathDepth + 1 >= map[nexti][nextj].atPathDepth)) {
return false;//如果是由火出发或者depth较大,不改写
}
else {
return true;
}
}
}
else { //不连通
return false;
}
}
/**
* initGame初始化map矩阵、mapState矩阵和fireState数组。并载入以下图片:
* canvas.imgBg
* canvas.imgMain
* canvas.imgItem
*/
public void initGame() {
int i, j;
rnd = new Random();
if (map == null) {
map = new Pipe[7][7];
}
for (i = 0; i < 7; i++) {//初始化map,注意应该放在generateLevel中
for (j = 0; j < 7; j++) {
map[i][j] = new Pipe();
if (j == 0) { //水龙头
map[i][0].type = 4; //水龙头
map[i][0].path[Pipe.RIGHT] = true; //右=true
map[i][0].rotate = 0;
}
else if (j == 6) { //火
map[i][6].type = 5; //火
map[i][6].path[Pipe.LEFT] = true; //左
map[i][6].rotate = 0;
}
else {
map[i][j].create();
}
map[i][j].x=29 + j * 12;
map[i][j].y=32 + i * 12;
}
}
if (fireState == null) { //火状态
fireState = new int[7];
}
if(fireStateChanged==null){
fireStateChanged=new long[7];
}
if (path == null) {
path = new Vector();
}
try {
if (canvas.imgBg == null) {
canvas.imgBg = Image.createImage("/images/bg1.png");
}
if (canvas.imgMain == null) {
canvas.imgMain = Image.createImage("/images/main.png");
}
if (canvas.imgItem == null) {
canvas.imgItem = Image.createImage("/images/item.png");
}
}
catch (IOException ex) {}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -