?? mazegame.java
字號:
}
/**
* 遍歷迷宮,遍歷完成后就能找到主路徑:checks[i][j]為Check.main的方格都在主路徑上
*
* @param i1
* 原方格所在行數(shù)
* @param j1
* 原方格所在列數(shù)
* @param i2
* 目標(biāo)方格所在行數(shù)
* @param j2
* 目標(biāo)方格所在列數(shù)
* @return 找到從起點到終點路徑則返回true;否則返回false
*/
private boolean traverse(int i1, int j1, int i2, int j2) {
boolean done = false;
if (i1 == 0 && j1 == 0)// 起點
checks[i1][j1] = Check.main;
if (valid(i1, j1, i2, j2)) {
checks[i2][j2] = Check.notMain;// 先設(shè)定為notMain表示不在主路徑上
if (i2 == this.height - 1 && j2 == this.width - 1)
done = true; // 到達(dá)終點
else {
done = traverse(i2, j2, i2 + 1, j2); // down
if (!done)
done = traverse(i2, j2, i2, j2 + 1); // right
if (!done)
done = traverse(i2, j2, i2 - 1, j2); // up
if (!done)
done = traverse(i2, j2, i2, j2 - 1); // left
}
if (done) // 若done為true說明這個方格在主路徑上
checks[i2][j2] = Check.main;
}
return done;
}
/**
* 開啟解答:迷宮中將會顯示解答
*/
public void solveOn() {
solve = true;
repaint();
}
/**
* 關(guān)閉解答:迷宮中將不顯示解答
*/
public void solveOff() {
solve = false;
repaint();
}
/**
* 玩家移動(當(dāng)然,有墻阻擋就走不了那個方向)
*
* @param direction
* 1--向左走,2--向上走,3--向右走,4--向下走
* @return 成功走了一步則返回true;否則返回false
*/
public boolean move(int direction) {
boolean succeed = false;
switch (direction) {
case 1:
if (playerColumn != 0
&& vertical[playerRow][playerColumn] == Wall.notExist) {
playerColumn -= 1;
succeed = true;
}
break;
case 2:
if (playerRow != 0
&& horizontal[playerRow][playerColumn] == Wall.notExist)// 不在第一行且沒有墻阻擋
{
playerRow -= 1;
succeed = true;
}
break;
case 3:
if (playerColumn != this.width - 1
&& vertical[playerRow][playerColumn + 1] == Wall.notExist) {
playerColumn += 1;
succeed = true;
}
break;
case 4:
if (playerRow != this.height - 1
&& horizontal[playerRow + 1][playerColumn] == Wall.notExist) {
playerRow += 1;
succeed = true;
}
break;
}
repaint();// 走完一步不要忘記重畫!
return succeed;
}
/**
* 開啟追趕者
*/
public void chaseOn() {
this.chase = true;
timer.start();
repaint();
}
/**
* 關(guān)閉追趕者
*/
public void chaseOff() {
this.chase = false;
timer.stop();
repaint();
}
/**
* 玩家拆墻,若超過了限制次數(shù)或本來就沒墻的則拆墻無效
*
* @param direction
* 1--拆玩家當(dāng)前方格位置的左墻,2--拆上墻,3--拆右墻,4--拆下墻
*/
public void tearDown(int direction) {
boolean succeed = false;
if (this.tearDownAllowed != 0) {// 若小于0則說明玩家設(shè)定拆墻不限次數(shù),若大于0則說明還可以拆墻
switch (direction) {
case 1:
if (vertical[playerRow][playerColumn] == Wall.exist) {
vertical[playerRow][playerColumn] = Wall.notExist;
succeed = true;
}
break;
case 2:
if (horizontal[playerRow][playerColumn] == Wall.exist) {
horizontal[playerRow][playerColumn] = Wall.notExist;
succeed = true;
}
break;
case 3:
if (vertical[playerRow][playerColumn + 1] == Wall.exist) {
vertical[playerRow][playerColumn + 1] = Wall.notExist;
succeed = true;
}
break;
case 4:
if (horizontal[playerRow + 1][playerColumn] == Wall.exist) {
horizontal[playerRow + 1][playerColumn] = Wall.notExist;
succeed = true;
}
break;
}
if (this.tearDownAllowed != -1 && succeed)
this.tearDownAllowed--;// 是限制次數(shù)且成功拆了一個墻
}
repaint();// 拆完墻不要忘記重畫!
}
/**
* 獲取當(dāng)前可拆墻剩余次數(shù)
*
* @return 當(dāng)前可拆墻剩余次數(shù)
*/
public int tearDownAllowedTimes() {
return tearDownAllowed;
}
/**
* 可變范圍拆墻,拆除一個矩形區(qū)域內(nèi)的所有墻:以玩家當(dāng)前位置為中心方格,以width為寬度半徑,以height為高度半徑
* 注意:若給定矩形區(qū)域不完全在迷宮區(qū)域內(nèi)則拆墻無效
*
* @param widthHalf
* 矩形寬度半徑
* @param heightHalf
* 矩形高度半徑
*/
public void variableTearDown(int widthHalf, int heightHalf) {
boolean notBeyond;
notBeyond = playerRow - heightHalf >= 0
&& playerRow + heightHalf + 1 <= this.height
&& playerColumn - widthHalf >= 0
&& playerColumn + widthHalf + 1 <= this.width;
if (notBeyond) {// 未超出迷宮范圍
// 矩形區(qū)域內(nèi)的水平墻全拆除
for (int i = playerRow - heightHalf; i <= playerRow + heightHalf
+ 1; i++)
for (int j = playerColumn - widthHalf; j <= playerColumn
+ widthHalf; j++)
horizontal[i][j] = Wall.notExist;
// 矩形區(qū)域內(nèi)的豎直墻全拆除
for (int i = playerRow - heightHalf; i <= playerRow + heightHalf; i++)
for (int j = playerColumn - widthHalf; j <= playerColumn
+ widthHalf + 1; j++)
vertical[i][j] = Wall.notExist;
}
repaint();// 再次強(qiáng)調(diào):拆完墻不要忘記重畫!
}
/**
* 保護(hù)生效:玩家四面是墻;保護(hù)失效:玩家四面無墻
*
* @param protect
* true為保護(hù)生效;false為保護(hù)失效
*/
public void protectEnabled(boolean protect) {
if (protect) {
horizontal[playerRow][playerColumn] = Wall.exist;
horizontal[playerRow + 1][playerColumn] = Wall.exist;
vertical[playerRow][playerColumn] = Wall.exist;
vertical[playerRow][playerColumn + 1] = Wall.exist;
} else {
horizontal[playerRow][playerColumn] = Wall.notExist;
horizontal[playerRow + 1][playerColumn] = Wall.notExist;
vertical[playerRow][playerColumn] = Wall.notExist;
vertical[playerRow][playerColumn + 1] = Wall.notExist;
}
repaint();
}
/**
* 返回當(dāng)前的游戲結(jié)果(考慮到玩家不動卻被追趕成功的情況,不推薦在每次玩家移動時作出判斷)
* (建議在外部類中定義一個定時器,每隔10毫秒就判斷一次玩家的輸贏狀態(tài),方便處理)
*
* @return 返回-1表示當(dāng)前玩家輸了(追趕者為"開"且玩家碰到追趕者)
* 返回0表示當(dāng)前迷宮游戲仍在進(jìn)行中;返回1表示當(dāng)前玩家贏了(玩家到達(dá)終點且此刻并沒有碰到追趕者)
*/
public int currentResult() {
boolean chased = false;// 判斷是否被追到
for (Chaser chaser : chasers)
if (chase == true && playerRow == chaser.row
&& playerColumn == chaser.column)
chased = true;
if (chased)// 追趕者為"開"且玩家碰到追趕者
currentResult = -1;
else if (playerRow == this.height - 1 && playerColumn == this.width - 1)// 玩家到達(dá)終點且此刻并沒有碰到追趕者
currentResult = 1;
return currentResult;
}
/**
* 當(dāng)前提示,會根據(jù)玩家在迷宮的當(dāng)前位置給出提示 (考慮到玩家不動卻被追趕成功的情況,不推薦在每次玩家移動時給出提示)
* (建議在外部類中定義一個定時器,每隔10毫秒就調(diào)用一次本方法返回當(dāng)前提示)
*
* @return 當(dāng)前提示,會根據(jù)玩家在迷宮的當(dāng)前位置給出提示.
*/
public String currentTip() {
String tip = "暫 無 提 示";
boolean chaserNear = false;// 判斷追趕者是否在附近
for (Chaser chaser : chasers)
if (Math.abs(playerRow - chaser.row) < 2
&& Math.abs(playerColumn - chaser.column) < 2)
chaserNear = true;
if (playerRow == 0 && playerColumn == 0)// 玩家在起點
tip = "你 在 起 點";
else if (this.currentResult() == 1)// 玩家到達(dá)終點
tip = "恭 喜 到 達(dá) 終 點!";
else if (chaserNear)// 追趕者和玩家相差幾個方格
tip = "當(dāng) 心! 追 趕 者 似 乎 很 接 近 了!";
else if (checks[playerRow][playerColumn] == Check.notMain) // 玩家當(dāng)前位置不在主路徑上
tip = "你 走 的 路 似 乎 不 對";
else if (checks[playerRow][playerColumn] == Check.main)// 玩家當(dāng)前位置在主路徑上
tip = "你 走 的 路 似 乎 是 正 確 的";
return tip;
}
/**
* 幫助信息:迷宮的規(guī)則.注意:按鍵功能由外部類定義并告訴玩家.
*
* @return 幫助信息:迷宮的規(guī)則
*/
public String help() {
String help;
help = "規(guī) 則 : 玩 家 是 藍(lán) 點, 終 點 在 右 下 角. 碰 到 紅 點 就 輸.";
return help;
}
/**
* 追趕者的定時移動
*
* @author 山
*
*/
private class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (Chaser chaser : chasers)
// 追趕者追趕玩家
chaser.chase();
repaint();// 追趕者移動后不要忘記重畫!
}
}
/**
* 定義一個追趕者以及其追趕操作
*
* @author 山
*
*/
private class Chaser {
public int row, column;// 追趕者的所在方格的行數(shù)和列數(shù),可在Maze類中訪問
/**
* 新的追趕者
*
* @param row
* 新建追趕者所在方格的行數(shù)
* @param column
* 新建追趕者所在方格的列數(shù)
*/
private Chaser(int row, int column) {
this.row = row;
this.column = column;
}
/**
* 以追趕者為中心,玩家的方位有8個:上,左上,右等,追趕者就是根據(jù)這些來追趕
*/
private void chase() {
if (playerRow == this.row && playerColumn < this.column)// 玩家在追趕者左邊
this.move(8);
else if (playerRow == this.row && playerColumn > this.column)// 玩家在追趕者右邊
this.move(4);
else if (playerRow < this.row && playerColumn == this.column)// 玩家在追趕者上面
this.move(2);
else if (playerRow > this.row && playerColumn == this.column)// 玩家在追趕者下面
this.move(6);
else if (playerRow < this.row && playerColumn < this.column)// 玩家在追趕者左上方
this.move(1);
else if (playerRow < this.row && playerColumn > this.column)// 玩家在追趕者右上方
this.move(3);
else if (playerRow > this.row && playerColumn < this.column)// 玩家在追趕者左下方
this.move(7);
else if (playerRow > this.row && playerColumn > this.column)// 玩家在追趕者右下方
this.move(5);
}
/**
* 追趕者移動
*
* @param direction
* 1--左上方,2--上方,3--右上方,4--右方,5--右下方,6--下方,7--左下方,8--左方
* @return 成功走了一步則返回true;否則返回false
*/
private boolean move(int direction) {
boolean succeed = false;
switch (direction) {
case 1:
succeed = this.move(8);
if (!succeed)
succeed = this.move(2);
break;
case 2:
if (row != 0 && horizontal[row][column] == Wall.notExist)// 不在第一行且沒有墻阻擋
{
row -= 1;
succeed = true;
}
break;
case 3:
succeed = this.move(4);
if (!succeed)
succeed = this.move(2);
break;
case 4:
if (column != width - 1
&& vertical[row][column + 1] == Wall.notExist) {
column += 1;
succeed = true;
}
break;
case 5:
succeed = this.move(4);
if (!succeed)
succeed = this.move(6);
break;
case 6:
if (row != height - 1
&& horizontal[row + 1][column] == Wall.notExist) {
row += 1;
succeed = true;
}
break;
case 7:
succeed = this.move(8);
if (!succeed)
succeed = this.move(6);
break;
case 8:
if (column != 0 && vertical[row][column] == Wall.notExist) {
column -= 1;
succeed = true;
}
break;
}
return succeed;
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -