java寫的坦克大戰
坦克大戰(Java版本)
實現一個java版本的坦克大戰遊戲
【功能提示】
1. 遊戲要有圖形使用者介面,介面能夠反映遊戲所有的細節。
2. 介面中要有坦克,牆,樹林,河流。
3. 介面中要有一個“家”,“家”被攻擊中則輸了遊戲。
4. 坦克分兩種,敵方和我方。
5. 牆也分為兩種,可以穿透的普通牆,不可以穿透的鐵牆。
6. 樹和河流均只有一種,樹林坦克可以通過。
7. 坦克可以發射子彈,敵我方的子彈屬性一樣。
8. 我方子彈可以殺死敵方坦克,敵方子彈也可以殺死我方坦克,但需要多槍子彈才可以殺死。
9. 敵方之間不可以殺死對方。
10. 子彈擊中坦克要有爆炸,但擊中牆不能爆炸。
11. 我方可以吃血包增加生命。
12. 遊戲可以暫停,重新開始,遊戲幫助等功能。具體如下圖:
13.
一、 題目分析與設計
n 需求分析
1. 設計一個圖形使用者介面,將所有遊戲的元素都能在此用於介面上表現出來,介面能夠接受使用者的操作,具有人機互動功能。使用者可以選擇重新開始遊戲,退出遊戲,暫停遊戲和查詢遊戲幫助。
2. 介面中包含坦克,樹,河流,阻擋牆和遊戲使用者所要保護的“家”。
3. 坦克:坦克分為兩種,敵方坦克和使用者控制的坦克。使用者方和敵方坦克均可以發射子彈,可以改變路徑的行走,且在行走過程中遇到牆等阻礙物和遊戲邊界時要改變方向,而不能一直頂著障礙物不放。坦克之間不能穿越,碰撞到後自動調換方向。
4. 樹:介面中要包括樹林,作為遮掩物體和修飾物體,以便增加遊戲的元素,使得遊戲更加貼切人性化。樹的數目不限,以遊戲整體介面清晰美觀來決定數目。
5. 河流:介面中要包括河流,河流作用與樹林相同,同樣河流的數目不限,以遊戲介面整體美觀度來決定數目。
6. 牆:牆體分為兩種,普通的牆和鐵牆,普通的牆在受到子彈襲擊時會損壞,而鐵牆可以阻礙子彈的穿越。兩方的坦克均不能穿越兩種牆體,但都可以摧毀普通牆體。普通牆體的數目配合其他元素合理安排,鐵牆則不宜過多,不然遊戲難度太低甚至因為坦克不能穿越鐵牆而使得遊戲無法進行下去。
7. “家”:使用者方除了有一輛自己的坦克外還有一個要保護的家,家由普通牆體包圍,家受到子彈攻擊後遊戲立即結束,使用者方則輸了本局遊戲。
8. 子彈:子彈可以由敵方和使用者方發射,且發射出去的子彈可以直線移動,直到碰到障礙物就消失,子彈可以穿越樹林和河流。敵方坦克受到一顆子彈攻擊會爆炸從而導致死亡,死亡後坦克消失。使用者方受到子彈攻擊後會減少壽命,且受到四次攻擊則死亡,此時如還有敵方坦克存在,則使用者方輸掉本次遊戲。
9. 爆炸:當子彈射擊到坦克身上時,要產生爆炸效果。
10. 方向:坦克和子彈都有方向,可以選擇上下左右四個方向,且子彈的方向從屬於坦克的方向。
n 具體設計
以下的論述均根據上面需求分析的順序來安排:
1. 圖形使用者介面
圖形使用者介面要用到Java課程裡的第六章的知識,需要用到抽象視窗工具集即AWT和Swing來設計實現,由於遊戲需要有功能按鍵來控制遊戲的重新開始,退出,暫停,幫助等,所以在實現過程中,設計選單項。
坦克,河流,樹,家,牆等都是呼叫各自類裡面的draw函式來畫出來,最後new一個圖形面板出來,把所有的元素都add進面板就可以了。介面的構造在程式中由TankClient類的構造方法來完成,即沒構造一個使用者類都會產生這樣一個包含各種遊戲元素在內的介面。由於畫面是靜止的,而我們遊戲的畫面要求是動態的,遊戲中的坦克和子彈都是在不斷的動,可穿透的普通牆體也在“動”,所以對於畫面,必須要不斷的更新,重畫才能產生動態的效果。
在程式中,此部分功能也是由TankClient類裡的update函式和framPaint函式共同實現,將“動”的元素進行重畫,而不動的元素如選單項就不用重畫,所以這也是為什麼把選單項設計進TankClient類的構造方法中。當然,圖形使用者介面中也包括對各種介面元素的大小,位置和顏色等設計,細節問題這裡就不贅述。
2. 介面中的元素
介面中的元素都是在構造介面的時候用介面例項物件的add方法加入進去的,且“動”的元素要不斷更新重畫。
3. 坦克
坦克主要由Tank類來實現。坦克的屬性:速度(有X軸和Y軸速度之分),坦克大小,坦克所在新的位置(X座標和Y座標),坦克是否還活著,行動方向等。所有的這些屬性都有一個初始化值,從而在遊戲一開始就可以執行。
在設計過程中,坦克出現的位置由座標而定。使用者方之後的位置由鍵盤監聽方向,按指定方向以恆定的速度前進——此速度為全域性靜態變數,當沒有接受到鍵盤的控制時,則保持靜止。敵方的坦克則是根據隨機數來控制隨機的方向和路徑的,當敵方坦克撞到阻礙物時,會轉回到前一步的位置,從而解決了坦克撞到阻礙物不回頭的問題,這個功能由Tank類裡的changToOldDir()方法實現。
坦克的方向和子彈發射以及遊戲的重新開始都是由鍵盤來控制的,所以在Tank類裡面必須要實現這些功能。
Tank類的keyPressed()方法用於接受鍵盤的按鍵監聽,接收到相應的鍵盤資訊後,如接收到F,則表示發射子彈,所以此時要呼叫Tank類裡的fire()方法,fire()方法不帶傳遞引數,因為子彈的方向總是從屬於坦克的方向和位置。
由於坦克在碰到牆,介面邊界和“家”等阻礙物時要改變方向,所以在Tank裡面必須對於每一種阻礙物要設計一個方法來作為應對策略,當然解決方法是把下一步的位置調整到上一步的位置。
使用者方Tank還可以吃紅心來增加自己的生命值,得到一個紅心,增加100生命值。所以在程式中坦克必須要有一個方法來判斷當坦克接觸到紅心時,生命值增加的方法。程式中用eat()方法來實現“吃”紅心並且增加生命值,當然,這其中要使得坦克的生命值不會超過自己生命的極限值200,所以判斷的時候,當生命小於等於100時,直接加100生命值,但是當生命值大於100時,就只能使生命值加滿到極限值200.當然,說到生命值,一定要在圖形使用者介面中顯示出來,所以在Tank類裡面一定要設計一個方法,來畫出生命的增減過程,在Tank類裡面是用DrawBloodbBar()來刻畫。
4. 樹林
樹林主要是用來做修飾物體的,具有不透明性。由一個Tree類來描述,Tree有兩個屬性,位置和長寬。樹的類裡有一個自己的構造方法,當然還有一個必不可少的draw()方法。
5. 河流
河流的作用與樹林類似,這裡不再贅述。
6. 牆體
牆體分為普通牆和鐵牆。普通牆可以被子彈損壞,而鐵牆則不會。
Ø 普通牆
普通牆有以下幾個屬性:牆的固定長度和寬度,牆的位置座標,牆體是由圖片加入到圖形使用者介面來表示的。程式中用CommonWall類來描述普通牆,此類裡有一個構造方法,用於傳遞引數,還有一個draw()方法,來畫指定位置的牆,另外還有個getRect()方法來構造長方形例項。
Ø 金屬牆
金屬牆的引數和普通牆完全類似,只不過金屬牆不能被子彈穿破,但這個屬性在接下來討論的子彈的屬性裡面,由於上面已經給出裡普通牆的屬性,所以這裡將不再贅述金屬牆的屬性了。
7. 家:
家是由Home類來抽象的,具體的屬性有:家的大小,家的位置,家的存活狀態,與樹林和河流一樣,家還有draw()和自己的構造方法,作用也和前面的一樣,但是家還有一些新的方法,因為可以在遊戲中重新開始遊戲,所以要有設定方法讓家重新“活”起來,當然,有時候要判斷家現在的存活狀態,所以就必須要isLive()和setLive()兩個方法了。除此之外,還要有一個遊戲結束介面的清理工作和提示工作,gameover()方法就是解決這個問題的。
8. 子彈:
子彈的屬性:子彈前進的X軸和Y軸的速度——初始速度都為10,子彈的長度和寬度——初始的長寬都為10,子彈的位置,子彈的方向,子彈是否live等。由於不同方向的子彈其實是圖片,所以這裡要考慮不同圖片的選擇用對應的方向來指定,所以要建立Map鍵值對,用String屬性的方向來指定不同的圖片。如:imgs.put("L", bulletImages[0]);
類裡面慣例有個構造方法,用來預設傳遞位置和方向,當然這裡用到了同構,另外一個建構函式來取得子彈的狀態和介面。darw()方法和move()方法來控制畫子彈和移動子彈
接下來就是要考慮到子彈打到個=各元素上的反應,敵方的子彈打到敵方時,不會殺死自己人,所以這裡只要直接return true就可以了,不用移除子彈碰到的坦克,更不用呼叫爆炸來顯示爆炸效果。
具體程式碼:
public boolean hitTanks(List<Tank> tanks) {//當子彈打到坦克時
for (int i = 0; i < tanks.size(); i++) {
if (hitTank(tanks.get(i))) { //對每一個坦克,呼叫hitTank
return true;
}
}
return false;
}
子彈打到其他坦克上時用hitTank(Tank t) 方法,子彈打到牆上時用hitWall(CommonWall w)方法,打到金屬牆上hitWall(MetalWall w),打到家hitHome(),當然在這些方法裡,都要作相應的操作來表示接受到子彈的後果,普通牆要移除對應的位置,所以在方法裡面又要呼叫remove()方法來移除,如打到家上,就要吧home的生命設定為false,從而結束遊戲。實現如下:
public boolean hitHome() { //當子彈打到家時
if (this.live && this.getRect().intersects(tc.home.getRect())) {
this.live = false;
this.tc.home.setLive(false); //當家接受一槍時就死亡
return true;
}
return false;
}
還有,當子彈射擊到對方(使用者方對敵方)時,當敵方射擊到使用者方,使用者方要減少生命值,沒接受一槍,就執行t.setLife(t.getLife() - 50); // 受一粒子彈壽命減少50,接受4槍就死,總生命值200,當然方法裡面還要做其他很多的判斷,如生命值是否小於0,如果是的話就執行t.setLive(false);從而結束遊戲。
9. 爆炸:
坦克的爆炸效果獨立出來用一個類來描述,爆炸的屬性:位置和存活狀態,另外,畫爆炸效果的時候要取得使用者介面控制,所以要定義private static Toolkit tk = Toolkit.getDefaultToolkit();其他的方法只能的大同小異。
10. 選單功能
選單功能包括遊戲的重新開始,暫停,退出等。這些功能的使用者介面放在了TankClient的構造方法裡,用到的是面板類和相應的監聽功能,實現出來很簡單。
n 類的介紹
a) Direction 是一個列舉類 有L, U, R, D, STOP表示左,上,右, 下和靜止五個狀態
b) River 描述河流的類
屬性:
riverWidth |
河流的寬度 |
riverLength |
河流的長度 |
x |
X軸座標 |
y |
Y軸座標 |
TankClient tc |
TankClient物件 |
riverImags |
河流的圖片 |
River(int x, int y, TankClient tc) |
河流的構造方法 |
draw(Graphics g) |
畫河流的方法 |
Rectangle getRect() |
長方形例項 |
int getX() |
取得x座標 |
void setX(int x) |
設定x座標 |
int getY() |
取得y座標 |
void setY(int y) |
設定y座標 |
int getRiverWidth() |
取得河流的寬度 |
int getRiverLength() |
取得河流的長度 |
c) Home 表示使用者方的家的類
屬性:
width=30 |
家的靜態全域性寬度 |
length=30 |
家的靜態全域性長度 |
x |
X軸座標 |
y |
Y軸座標 |
TankClient tc |
TankClient物件 |
homeImags |
家的圖片 |
boolean live |
初始存活狀態為true 表示家的存活狀態 |
Home(int x, int y, TankClient tc) |
家的構造方法 |
void draw(Graphics g) |
畫出家的方法 |
Rectangle getRect() |
長方形例項 |
void gameOver (Graphics g) |
遊戲結束方法,做清理工作和相應的提示 |
boolean isLive() |
判斷是否存活 |
void setLive(boolean live) |
設定存活狀態,以便從新開始遊戲 |
d) Tree 描述樹林的類
屬性:
width=30 |
樹林的靜態全域性寬度 |
length=30 |
樹林的靜態全域性長度 |
x |
樹林在介面中X軸座標 |
y |
樹林在介面中Y軸座標 |
TankClient tc |
TankClient物件 |
Toolkit tk |
取得介面的控制 |
treeImags |
樹林的圖片 |
Tree(int x, int y, TankClient tc) |
家的構造方法 |
void draw(Graphics g) |
畫出樹林的方法 |
e) Bullets 描述子彈的類
屬性:
speedX = 10 |
子彈的全域性靜態速度 x軸方向的 |
speedY = 10 |
子彈的全域性靜態速度 y軸方向的 |
width = 10 |
子彈的全域性靜態寬度 |
length = 10 |
子彈的全域性靜態長度 |
Direction diretion |
子彈的方向 |
x |
X軸座標 |
y |
Y軸座標 |
TankClient tc |
TankClient物件 |
bulletImages |
子彈的圖片 |
boolean live |
初始存活狀態為true 表示家的存活狀態 |
Bullets(int x, int y, Direction dir) |
子彈的構造方法,帶三個引數 |
Bullets(int x, int y, boolean good, Direction dir, TankClient tc) |
子彈的構造方法,帶五個引數的 |
void draw(Graphics g) |
畫出子彈的方法 |
move() |
刻畫子彈運動的方法 |
Rectangle getRect() |
長方形例項 |
void gameOver (Graphics g) |
遊戲結束方法,做清理工作和相應的提示的方法 |
boolean isLive() |
判斷是否存活 |
boolean hitTanks(List<Tank> tanks)· |
子彈打到地方自己的時候的方法 |
boolean hitTank(Tank t) |
子彈打到對方的方法 |
boolean hitWall(CommonWall w) |
子彈打到普通牆的方法 |
boolean hitWall(MetalWall w) |
子彈打到金屬牆的方法 |
boolean hitHome() |
子彈打到家的方法 |
f) GetBlood 血包描述類
屬性:
width=36 |
血包的靜態全域性寬度 |
length=36 |
血包的靜態全域性長度 |
x |
X軸座標 |
y |
Y軸座標 |
TankClient tc |
TankClient類例項化物件 |
Random r |
用於產生隨機數 |
Toolkit tk |
tk獲得使用者介面 |
bloodImags |
家的圖片 |
poition |
位置陣列 |
boolean live |
初始存活狀態為false 表示初始化時無血包 |
void draw(Graphics g) |
畫出血包的方法 |
void move() |
血包移動的方法 |
Rectangle getRect() |
長方形例項 |
boolean isLive() |
判斷是否存活,是否有血包 |
void setLive(boolean live) |
設定存活狀態,設定血包的存在 |
g) CommonWall 普通牆的類
屬性:
width=20 |
普通牆的靜態全域性寬度 |
length=20 |
普通牆的靜態全域性長度 |
x |
普通牆在介面中X軸座標 |
y |
普通牆在介面中Y軸座標 |
TankClient tc |
TankClient類例項化物件,因為畫牆要取得介面的控制權 |
Toolkit tk |
tk獲得使用者介面 |
wallImags |
普通的圖片 |
CommonWall(int x, int y, TankClient tc) |
普通牆的構造方法,用於傳遞牆的位置引數和TankClient |
void draw(Graphics g) |
畫出普通牆的的方法 |
Rectangle getRect() |
長方形例項 |
h) MetalWall 金屬牆的類
屬性:
width=30 |
金屬牆的靜態全域性寬度 |
length=30 |
金屬牆的靜態全域性長度 |
x |
金屬牆在介面中X軸座標 |
y |
金屬牆在介面中Y軸座標 |
TankClient tc |
TankClient類例項化物件 |
Toolkit tk |
tk獲得使用者介面 |
wallImags |
金屬牆的圖片 |
MetalWall(int x, int y, TankClient tc) |
金屬牆的構造方法,用於傳遞牆的位置引數和TankClient |
void draw(Graphics g) |
畫出金屬牆的的方法 |
Rectangle getRect() |
長方形例項 |
i) BombTank 坦克爆炸類
屬性:
x |
坦克爆炸效果在介面中X軸座標 |
y |
坦克爆炸效果在介面中Y軸座標 |
TankClient tc |
TankClient類例項化物件 |
Toolkit tk |
tk獲得使用者介面 |
Image[] imgs |
爆炸效果的圖片 |
BombTank(int x, int y, TankClient tc) |
爆炸效果的構造方法,用於傳遞爆炸效果的位置引數和TankClient |
void draw(Graphics g) |
畫出爆炸效果的的方法 |
j) Tank 描述Tank的類
屬性:
speedX = 6 |
坦克的全域性靜態速度 x軸方向的 |
speedY = 6 |
坦克的全域性靜態速度 y軸方向的 |
width = 35 |
坦克的全域性靜態寬度 |
length = 35 |
坦克的全域性靜態長度 |
Direction diretion |
坦克的狀態 ,初始化為靜止 |
Direction Kdirection |
坦克的方向,初始化為向上 |
Int x |
X軸座標 |
Int y |
Y軸座標 |
int oldX |
舊狀態的X軸座標 |
int oldY |
舊狀態的Y軸座標 |
boolean live |
坦克是否存活,初始化為活著的 |
TankClient tc |
TankClient物件 |
int life |
初始化生命值為200 |
Random r |
隨機數,用於控制坦克的方向 |
int step |
路徑 |
Image[] tankImags |
各個方向坦克的圖片陣列集合 |
Tank(int x, int y, boolean good) |
坦克的構造方法1 ,帶三個引數 |
Tank(int x, int y, boolean good, Direction dir, TankClient tc) |
坦克的構造方法2 ,帶五個引數的 |
void draw(Graphics g) |
畫出坦克的方法 |
move() |
描述坦克運動方向的方法 |
void changToOldDir() |
轉換到舊方向, |
void keyPressed(KeyEvent e) |
鍵盤監聽方法 |
void decideDirection() |
決定移動方向方法 |
void keyReleased(KeyEvent e) |
監聽鍵盤釋放方法 |
Bullets fire() |
坦克開火方法 |
Rectangle getRect() |
長方形例項的方法 |
boolean isLive() |
判斷是否存活的方法 |
void setLive(boolean live) |
設定坦克存活方法 |
boolean isGood() |
用於返回是否是good狀態 |
boolean collideWithWall(CommonWall w) |
坦克碰到普通牆的解決方法 |
boolean collideWithWall(MetalWall w) |
坦克碰到金屬牆的解決方法 |
boolean collideRiver(River r) |
坦克碰到河流的解決方法 |
boolean collideHome(Home h) |
坦克碰到家的解決方法 |
Boolean collideWithTanks(java.util.List <Tank> tanks) |
坦克撞到坦克的解決方法 |
int getLife() |
獲得坦克的生命狀態的方法 |
void setLife(int life) |
設定坦克的生命狀態的方法 |
boolean eat(GetBlood b) |
坦克吃紅心血包的方法 |
int getX() |
確定X的位置的get方法 |
int getY() |
確定Y的位置的get方法 |
k) TankClient 坦克使用者類,繼承Frame,實現ActionListener介面
例項化各個類的容器:
List<River> theRiver = new ArrayList<River>();
List<Tank> tanks = new ArrayList<Tank>();
List<BombTank> bombTanks = new ArrayList<BombTank>();
List<Bullets> bullets = new ArrayList<Bullets>();
List<Tree> trees = new ArrayList<Tree>();
List<CommonWall> homeWall = new ArrayList<CommonWall>(); // 例項化物件容器
List<CommonWall> otherWall = new ArrayList<CommonWall>();
List<MetalWall> metalWall = new ArrayList<MetalWall>();
下面列表只列出主要方法和變數
屬性:
int Fram_width |
遊戲使用者介面的全域性靜態變數寬度,初始化為800 |
int Fram_length |
遊戲使用者介面的全域性靜態變數長度,初始化為600 |
void update(Graphics g) |
圖形使用者介面的更新方法 |
void framPaint(Graphics g) |
畫圖形使用者介面的方法,需要重畫的介面元素都在這個方法裡面 |
void actionPerformed(ActionEvent e) |
監聽選單項的方法 |
static void main(String[] args) |
主函式,啟動整個程式 |
使用者類主要是綜合呼叫各個類來協作完成完成遊戲的設計。
n 程式流程邏輯圖
下圖是程式執行的邏輯流程圖,只是表示邏輯,並沒有具體到每一個細節:
流程圖:
n 開發環境:Myeclipse
二、 測試分析
n 闡述擴充套件包
本程式沒有用到SUM的擴充套件包,也未涉及到資料庫的建立
n 程式效果圖測試
1. 選單項測試
選單項可以選擇開始新遊戲,退出,暫停,繼續,幫助功能,對於開始新遊戲,退出兩個功能,要給出提示,使用者是否真的想繼續操作!
1) 選單效果圖:
2) 開始新遊戲功能測試:
當點選確認後開始新遊戲,當點選取消後恢復到原來的頁面。這裡不再附圖給出點選確定和取消後的效果。
3) 暫停功能測試:
4) 幫助模組測試圖:
5) 退出功能測試:
點選確認後將退出遊戲,點選取消後不會退出遊戲。
2. 遊戲資訊測試:
遊戲標題欄給出遊戲名稱和製作人相關資訊
3. 子彈射擊到對方坦克後爆炸效果測試:
圖中的紅色類似爆炸狀的影象是使用者方擊中地方坦克後的爆炸效果顯示
4. 子彈撞擊到普通牆後,會使得牆消失一塊的測試:
圖中畫紅箭頭的地方時受到子彈攻擊後的效果。牆體被破壞。
5. 金屬牆受到子彈攻擊的測試
如圖為子彈攻擊金屬牆體前:
如右圖為子彈攻擊金屬牆後的效果圖:
綜上兩個可以看出,金屬牆都到子彈的攻擊後不會被損毀,但是當在把程式中子彈碰撞金屬牆的語句改變後,會損毀金屬牆!如下:
原來的程式碼段: public boolean hitWall(MetalWall w) { //子彈打到金屬牆上
if (this.live && this.getRect().intersects(w.getRect())) {
this.live = false;
return true;
}
return false;
}
修改後的程式碼段:public boolean hitWall(MetalWall w) { //子彈打到金屬牆上
if (this.live && this.getRect().intersects(w.getRect())) {
this.live = false;
this.tc.metalWall.remove(w); //子彈可以穿越金屬牆了
return true;
}
return false;
}
修改後的效果:從下圖可以看出,修改後金屬牆也可以被摧毀!
6. 血包效果圖:血包會隨機的移動,以下是血包所在的兩次不同位置:
所在位置1:
所在位置2:
7. 坦克吃血包增加生命值測試;
沒有吃血包前:可以看出血包在使用者方附近,當用戶方去接近血包時,就可以增加生命值。
吃完血包後加滿生命值:
8. 當家被攻擊後結束遊戲:
遊戲結束是呼叫gameover()方法,在方法裡面會清除所有的頁面元素。
9. 快捷鍵的測試:
R鍵為重置遊戲:如下為重新開始後的頁面:
提示:由於上下左右和開火等快捷方式鍵都是動態的效果,所以這裡不方便給出,使用者可以自行測試!
10. 坦克撞擊邊緣的效果:
撞擊前:
撞擊後:
提示:這裡只給出撞擊邊緣的效果,其他坦克撞擊坦克,家,普通牆,金屬牆等效果使用者可以自行測試!
11. 使用者贏得遊戲後的效果測試:
註釋:由於坦克大戰的畫面都是動態的,所以不可能全部截圖來測試每一個功能,如有需要,使用者可以自行測試。
下面改變程式中的一些典型的資料,看修改後的效果:
n 典型資料測試:
1. 家的位置測試:由於程式中的介面位置是嚴格巢狀設計的,即家是剛好落在它外面的一層保護牆能,當修改家原來的位置引數Home home = new Home(373, 545, this);後,會走出達不到預期的效果:如下圖:
圖示為把373改為了450後的效果!
2. 坦克全域性靜態速度的改變:
坦克的全域性速度原來是x軸方向為6,y軸方向為6,修改後,坦克的前進速度會加快,當然這樣一來可以加大遊戲的難度,可以作為遊戲的擴充套件功能來實現,由於坦克的速度是動態的,這裡無法測試,使用者可以在Tank類裡修改speedX和speedY來測試。
子彈的速度的性質同坦克相同,這裡不再贅述。
3. 牆體的部分測試:
改變牆體的介面佈局:如改變普通牆的介面佈局,是介面中沒有普通牆,只要將程式中的如下程式碼遮蔽掉就可以了:
for (int i = 0; i < 32; i++) {
if (i < 16) {
otherWall.add(new CommonWall(220 + 20 * i, 300, this)); // 普通牆佈局
otherWall.add(new CommonWall(500 + 20 * i, 180, this));
otherWall.add(new CommonWall(200, 400 + 20 * i, this));
otherWall.add(new CommonWall(500, 400 + 20 * i, this));
} else if (i < 32) {
otherWall.add(new CommonWall(220 + 20 * (i - 16), 320, this));
otherWall.add(new CommonWall(500 + 20 * (i - 16), 220, this));
otherWall.add(new CommonWall(220, 400 + 20 * (i - 16), this));
otherWall.add(new CommonWall(520, 400 + 20 * (i - 16), this));
}
}
遮蔽後效果如下:
從圖中可以看出,沒了介面中的除開家以外的普通牆體了,其他的金屬牆體,樹林,河流等也是一樣的道理.
4. 子彈撞擊其他物體如坦克的改變:當改變子彈射擊坦克的方法時,如將子彈射擊到坦克,不將坦克的生命結束,則遊戲將永遠打下去,誰都打不死誰.改變Bullets類裡的hittank方法裡的t.setLive(false);語句,只要將這個語句中的false改為true就可以了,當然對於其他的hit*方法,也只要作相應的修改就可以了。
n 完善功能:
Ø 已完善的功能:
A. 血包可以讓我們知道還剩下多少生命值,但是有時候不是很直觀,所以在介面中加入一行資訊來實時更新使用者坦克的生命值,讓使用者有直觀的感覺。修改後的效果如下圖:
B. 遊戲級別的設定
遊戲的級別只做了簡單的級別設定,可以設定四個級別,級別1,級別2,級別3和級別4,預設進入遊戲是級別1,當然可以在遊戲的過程中切換級別。
級別的設定主要是把前面的Tank類和Bullets類的全域性靜態最終變數改成全域性靜態變數,利用監聽來設定坦克的速度和子彈的速度來設定遊戲的難度,從而形成了級別的設定。
修改後的畫面效果為:
Ø 還可以進一步完善的功能:
A. 可以為遊戲加入聲音,由於在嘗試的時候失敗了,所以程式中就沒有來實現這些功能。
B. 儲存遊戲結果。
C. 聯網功能等