目標:生成飛機大戰的基本模型。對象有我的飛機,敵機,子彈。

下面說我當時的步驟:首先是做我的飛機,然後讓他可以監聽鍵盤事件從而改變運動方向。然後做敵機,然後做他們碰撞的程序,然後做子彈,然後做子彈和敵機碰撞的程序,然後加上重新開始,暫停,和繼續的功能按鈕,最後加上一首背景音樂。

這是我當時的思路,然後如果想做的話也可以按照這個思路來,基本上寫十個備份程序左右就可以結束了。

現在來說一下我最後的程序的思路。我的飛機我沒有創建對象,而是直接畫圖片,然後處理好傳參就行了,我這裡的飛機的坐標就是用數組的地址來傳的,試了那麼多,就這個最好用。然後敵機和子彈都分別創建了一個類,也創建了兩個數組隊列來裝這兩個類。然後事件監聽也單獨做了一個類,然後有個參考意見就是事件監聽可以和主函數放在同一個類中,這樣主類和事件監聽類之間的傳參就省去了。還有一個線程類,加上主類,事件監聽類,子彈類,敵機類就一共寫了五個類。

現在來分析每個類的功能和結構。主類就調用了兩個方法,一個顯示界面,一個播放背景音樂。顯示界面裡面有三個按鈕,開始遊戲,暫停,繼續。還添加了一份背景圖片。接著是添加一些事件監聽,然後把窗體等有用的參數傳遞到監聽類中。

監聽類主要是監聽來自鍵盤的事件,讓鍵盤的上下左右鍵控制我的飛機的坐標移動,還有來自按鈕的事件,控制遊戲的開始,暫停和繼續。然後就是把坐標和窗體等有用的參數傳到線程類中。

線程類主要是接收信息控制暫停,繼續,然後控制好敵機,子彈的生成,然後就是把所有的對象和圖片都顯示出來,當然包括背景圖片。這裡用到了一個雙緩衝技術,用於解決繪製畫面時產生的圖片閃爍問題。

敵機類和子彈類都差不多,只要思考好裡面該有的屬性和方法和傳遞的參數就好了。

還有就是飛機大戰的那些飛機子彈都是一些圖片,這些圖片從網上搜一下就有一大堆了。

現在來細說一下我的代碼中的關鍵點:

1,這次我的button都是用的button,不是jbutton,一直顯示在那裡效果很不錯。

2.設置背景圖片:JAVA如何在為窗口設置背景圖片 - 我的IT技術 - 博客園這個鏈接不錯,我的也是從這裡參考的,只不過把裡面的圖片的地址改了一下

this.getClass().getResource("jc.jpg") 我是把圖片直接在eclipse上複製粘貼上去的,感覺這個最直接了。然後圖片要大一點,不然就不會滿屏。感覺不太好看。

3.設置背景音樂:Java代碼添加背景音樂 - Seraphjin - 博客園 我是參考這個鏈接的,就把music函數和前面定義的變數複製過來就行了,然後把那個音樂的地址改變了。

f = new File("D:\ring.wav"); 這是我寫的,注意這裡是根目錄,是兩條斜槓。還有要注意的是Java只支持WAV格式,即無損音樂。

4. ImageIcon image= new ImageIcon(this.getClass().getResource("GreenPlane.png"));

這是我添加定義圖片的代碼,然後圖片也是直接複製進包裏的。

5.鍵盤監聽中有個非常值得注意的地方,就是你的鍵盤有一個焦點,我的鍵盤應該是對窗體進行操作的,可是當運行程序的時候他卻可能會把焦點聚集在按鈕上。所以這裡需要有個聚焦的操作,在每個按鍵按下去後加上this.jf.requestFocus();這個jf就是從主類中傳過來的窗體。這樣就可以在每次按下鍵之後都可以對飛機的坐標進行操作。

6.然後就是重複再次提醒下參數的傳遞,最好都用volatile這個關鍵詞修飾,額,有個小知識,就是在線程類中的開始如果你加上個延時或者輸出語句,然後再去訪問這些多線程共享變數的話就不會出錯,因為這裡給了足夠多的事件給計算機把數據整合好。

7.建議剛開始寫鍵盤監聽的同學先單獨寫一個程序來測試一下鍵盤監聽是怎麼用的,這樣就能在保證各個模塊正常工作的情況下保證系統的正常工作。這裡提一下裡面的keytyped監聽方法,這個只對a,,b,1,3這些鍵有效,對ctrl,alt這些鍵無效,所以一般都不用這個方法,其他兩個方法就足夠了。

8.記得標誌位啥的在達到目的之後要回歸本位,不然下次出現這種情況就不能有效的檢測了。

9.雙緩衝技術:在線程運行的最開始加上下面這段代碼

BufferedImage buff=new BufferedImage(jf.getWidth(), jf.getHeight(),BufferedImage.TYPE_INT_RGB);

Graphics buffg=buff.getGraphics();

線程的最開始最好加延時,然後加這個。對了,記得線程裡面都是在一個while(true)裡面執行程序的啊,不然程序一跑完這個線程就結束了。所以畫圖的這個線程都是在不斷重複執行的。 然後回到雙緩衝,上面第一個語句是新建一個緩衝圖片的窗體,然後獲取這個窗體的畫筆對象。這個窗體是在後臺運行的,是我們看不到的。然後獲取這個畫筆之後,線程後面的用到畫筆的都用這個緩衝的畫筆去畫,最後再加上g.drawImage(buff, 0, 0, null);就是把這個緩衝的窗體用前臺顯示的畫筆直接畫出來。這樣出現在我們眼前的就不是畫筆畫完這個畫那個的閃爍的情況了。總之原理就是,先把所有的圖片緩存好成一張圖片,最後一次性把這張圖片畫出來。

10.這裡貼一段子彈把敵機打掉的代碼

for(int j=0;j<al.size();j++)

{

ammo jAmmo2=al.get(j);

for(int i=0;i<bl.size();i++)

{

ball ball = bl.get(i);

double dist=Math.sqrt((ball.x-jAmmo2.x)*(ball.x-jAmmo2.x)+(ball.y-jAmmo2.y)*(ball.y-jAmmo2.y));

if(dist<=50)

{

al.remove(jAmmo2);

bl.remove(ball);

}

}

jAmmo2.drawammo(buffg);

}

jAmmo2是子彈對象,ball是敵機對象(直接複製前面寫的彈球的對象,哈哈),思路就是先把子彈從隊列中都取出來,然後每個子彈都要和敵機測一下距離,如果小於某個限定值,就同時把這個敵機和子彈對象刪掉(這裡可以添加一個爆炸的畫面),如果沒事就正常把子彈畫入緩存的窗體中。然後就這樣了。

11.注意,在緩存的窗體中要先畫背景圖片,再畫飛機子彈,不然就會顯現不出飛機。

12.飛機和子彈出現的時間的控制,這裡我簡單的加了個循環次數標誌位,當標誌位大於某個數時就新建飛機對象。這個是比較草的方法,最好是新建一個線程類來專門控制他們的間隔時間。在開始遊戲的時候再新建一個另外的線程,在這個線程里加上延時和創建飛機對象。

13.額,感覺就這樣了。我寫的時候可沒有那麼邏輯,當時是一步一步改過來的,那些變數的的傳遞也是看到需要什麼傳什麼的,所以第一次寫的時候比較混亂,到處再改,然後還時不時出現空指針,不合邏輯啥的。這個時候就在感覺出問題的地方加上輸出,去看程序的運行過程,就這樣一步一步走過來。

請大家多多指教!


推薦閱讀:
相關文章