做者:陳偉 2011211927 0491101java
王延友 2011211834 0491102
編程
1、整體設計
多線程
1.1 具體設計框架
遊戲包括的範圍:本遊戲包括主類、坦克類、子彈類、爆炸類、牆類、血塊類。編程語言
需求函數 |
模塊學習 |
產生遊戲的屏幕this |
主類模塊spa |
將坦克大戰的過程呈如今屏幕上線程 |
|
畫出坦克 |
坦克類模塊 |
控制坦克的移動並讓坦克能夠攻擊 |
|
讓坦克不能夠穿越牆或別的坦克 |
|
添加坦克的圖片 |
|
畫出子彈 |
子彈類模塊 |
控制子彈的移動 |
|
各類子彈 |
|
讓子彈不能夠穿牆 |
|
添加子彈的圖片 |
|
子彈打牆的爆炸 |
爆炸類模塊 |
畫出爆炸的過程 |
|
控制坦克的爆炸 |
|
添加爆炸的圖片 |
|
畫出牆 |
牆類模塊 |
實現牆的功能 |
|
畫出血塊 |
血塊類模塊 |
讓血塊圍繞着固定的軌跡移動 |
|
實現血塊的功能 |
1.2 遊戲特色
咱們設計的這款坦克大戰和之前的區別我感受挺大的,主要區別以下:
1,在咱們設計的遊戲裏面坦克的炮筒更接近現實,那就是炮筒能夠旋轉。炮筒會指向鼠標所指的方向。
2,咱們不止是我一個坦克。咱們有隊友,隊友都是由電腦控制的坦克。
3,加血道具我方任一坦克都能吃,不僅是玩家控制的坦克能夠吃。
4,不論是敵方仍是我方都能發多種子彈。可是特殊子彈的數量有限。
5,咱們新添加了導彈,只有玩家控制的坦克才能夠吃導彈。
1.3 類的層次結構圖
1.3.1 坦克類的層次結構圖
1.3.2 道具類的層次結構圖
1.3.3 子彈類層次結構圖
1.3.4 爆炸類層次結構圖
1.3.5 坦克客戶端層次結構圖
1.3.6 牆類層次結構圖
1.4 系統流程圖
2、程序描述
2.1 主類模塊
主類是要畫出屏幕,而且要將坦克之間打鬥的全過程都呈現出來的,因此要先產生一個窗口,窗口產生以後應該要不停的刷新,不然屏幕會定格成畫面,用多線程來控制刷新的頻率,若是此時屏幕出現閃屏現象,應該用雙緩衝機制來畫出屏幕。雙緩衝機制是經過虛擬出一張圖片,將屏幕畫在這張虛擬的圖片上,再將這張虛擬的圖片呈如今屏幕上。
畫面重畫的類以下:
class RepaintThread implements Runnable // 畫面重畫線程 { public void run() { while (repaintFlag) { try { repaint(); ut.move(); // Tank定時移動 Shot tcShots = null; for (int i = 0; i < shotsList.size(); i++) // 界面上的子彈定時移動 { tcShots = shotsList.get(i); tcShots.move(); } Thread.sleep(33); } catch (InterruptedException e) { e.printStackTrace(); System.exit(-1); } } } }
2.2 坦克類模塊
該類實如今屏幕上畫出坦克,並控制坦克的移動,讓坦克能夠發射炮彈打對方等功能。
畫出坦克的方法以下:
public void draw(Graphics g) { if (!init) // 讀入炮筒圖片 { init = true; this.setTurretDir(new Point(turretDirx + 10, turretDiry + 10)); } if (isLive) { if (this.camp) { switch (tankDir) { case U: case D: { g.drawImage(imgMap1.get(tankDir), x - 18, y - 19, null); } break; case L: case R: { g.drawImage(imgMap1.get(tankDir), x - 19, y - 18, null); } break; default: { } break; } } else { switch (tankDir) { case U: case D: { g.drawImage(imgMap2.get(tankDir), x - 18, y - 19, null); } break; case L: case R: { g.drawImage(imgMap2.get(tankDir), x - 19, y - 18, null); } break; default: { } break; } } g.drawImage(bTurretImg, x - 32, y - 32, null); // 繪製大炮 this.tankHitPoint.draw(g); // 繪製出Tank的血量 } else { if (tankBomb != null) tankBomb.draw(g); // 繪出坦克爆炸 } }
2.3 子彈類模塊
該類實如今屏幕上畫出子彈和子彈的移動軌跡以及實現了坦克攻擊牆壁與攻擊敵方坦克的功能,並且咱們設計的是各類各樣的子彈,好比我方就有閃彈,敵方除了普通的子彈外還有可以穿牆的子彈。因爲代碼較長,我就不貼出來了。
2.4 爆炸類模塊
該類實現了在屏幕上畫出了坦克爆炸的情景,咱們採用了連續播放圖片的效果來體現爆炸,咱們的爆炸效果以下:
2.5 牆類模塊
遊戲裏面咱們的牆比較單一,這也能夠說是咱們遊戲的一點不足。咱們畫出的牆的效果以下:
2.6 血類模塊
血主要有兩種,一種是加血的道具,二是坦克自己的血量。加血道具咱們的設計就是,我方任一坦克吃了以後能回覆一點血量。而不一樣於之前的是否是隻有玩家操做的坦克才能吃加血道具。實現後效果以下:
三,功能演示
3.1 開始畫面:
遊戲的開始畫面咱們展現了玩家將要進入第一關,具體效果以下:
3.2 遊戲菜單
咱們的遊戲菜單有:開始遊戲,暫停遊戲,繼續遊戲,以及對遊戲的一些設置。效果以下:
3.3 遊戲畫面
具體的遊戲畫面以下:
屏幕左下方的60表明玩家坦克閃彈的剩餘數量,上面的五個小圓是導彈的剩餘數量。而右下角的愛心是加血道具,下面就是玩家能夠吃的兩枚導彈。
當咱們勝出後會提示是否進入下一關,效果以下:
4、實現時遇到的問題
在這個程序實現中咱們遇到的困難其實不少,由於程序過大,因此長期是一小點錯誤就會出現很奇怪的行爲。在這其中我列舉一下遇到的最大困難。
1:炮筒如何360度旋轉,這個問題開始咱們想了好久,到底該如何旋轉。轉到鼠標所指的方向,多是因爲數學功底太差。咱們沒有想到用數學的方式解決。最後咱們的解決辦法是用三角函數解決的,算出當前的角度就OK了。
2:就是開始菜單的使用,咱們這個開始遊戲開始一直不成功。開始時不成功主要是點了沒反應,咱們是加了監聽的。沒點開始遊戲就已經開始了。這個問題解決了以後又遇到了新的問題就是一點開始遊它就給你彈出一個新的窗口,不是在原來的窗口基礎之上開始遊戲。之因此出現這樣的問題是因爲個人界面不是一個panel類,而是一個方法。因此就添加了一個MyStartPanel extends JPanel類。而且實現Runnable接口,實現一閃一閃的界面效果。而後在開始遊戲監聽函數裏面,建立一個坦克客服端對象。調用啓動界面函數。就開始遊戲了。 這樣問題就解決了。
3:坦克之間的碰撞檢測。其實這個問題想起來這個問題蠻簡單,由於實際的坦克圖片是一個矩形框。只要兩個矩形框之間不要有交叉就能夠了。想法雖好,實現不易啊。開始咱們的方法很繁瑣,沒有寫一個統一的方法來判別。
其實困難重重,常常遇到很奇怪的問題。好比說子彈的發射問題之類的。因此我就列舉了主要的問題。
5、心得體會
陳偉心得體會:之因此想作坦克大戰是因爲我對坦克大戰有種感情吧,從小就是這個遊戲陪我度過個人童年。之前我都很好奇這個遊戲是怎麼作的,如今本身學了編程語言。因此有種很強烈的願望實現一下,而且加進本身的思想。一開始作的時候還很興奮。但是後來遇到各類問題個人興趣就會被打擊到。可是在這其中我獲得了一個對於我來講很重要的經驗。那就是遇到問題是要淡定,不要浮躁。只要你一直堅持研究這個問題的解決方法,到最後它必定會被解決的。其次,我也發現本身作這種大的項目還有不少不足。欠缺編程能力。因此編程能力確實有待提升。在這其中我以爲軟件工程的思想是很重要的,軟件工程學了仍是有很大用處,如今我對軟件工程的理解還不夠深刻,須要進一步的學習才行。
王延友的心得體會:此次的做業是要求完成一個遊戲的改進或者修改爲3D的。因爲我平時不怎麼玩大型遊戲,多3D遊戲瞭解得很少,在拿到這個題目時,的確不知道怎麼入手,恰好最近在觀看韓順平老師的java視頻。他裏面有一個案例是編寫坦克遊戲,因而想到不如我模仿這個遊戲吧,沒想到個人組員和我想到一塊兒去了。他也是計劃寫這方面的遊戲。咱們算是不謀而合。而後就是開始觀看視頻,按照那些方法開始編寫。可是往往都是看着簡單,要本身動手的時候就不是那麼簡單了。因爲咱們花了不少時間去設計和編寫元素類,因此界面不是很漂亮,並且還有些功能還不能實現。也說明個人能力還欠缺,還得好好努力。同時我也從隊友哪裏學到了思想的重要性,剛開始的時候不能太注意細節,先要考慮到總體的框架,否則就沒法開展工做了。後面纔是完善細節的時候。