[筆記]基於java的坦克大戰游戲實現思路


游戲說明:

玩家可以操縱自己的坦克,通過發射子彈擊毀敵機,敵機用同樣的方式擊毀玩家的坦克。    

基於java版的坦克大戰實現思路:

1.0:游戲界面設計

         --游戲的界面采用JPanel 游戲的主要活動區在這個JPanel上進行

         --游戲的界面素材采用java代碼的paint方法繪制坦克 炸彈效果導入外部圖片素材

 

首先常見一個JPanel,繪制出坦克和子彈,主意,坦克的繪制必須確定一個基准點,此后坦克的位置依賴與此坐標。

因此,現在需要一個MyPanel類來承載游戲的界面可視化區域。該類繼承自JPanel類。

MyPanel類的paint()方法可以很有效的繪制出坦克和子彈,注意到repaint()方法可以很方便的執行paint()方法,游戲的核心就是讓顯示器不停的刷新當前頁面。通過repaint()很方便能做到這點。

而讓MyPanel是很有必要的,游戲開始之后,我們讓repaint()可以自動的運行,而不是通過響應某種事件。

現在,有了坦克和子彈之后,下一步就是讓JFrame能監聽到玩家按下空格鍵,這個很容易可以實現,當監聽到玩家的事件之后,監視器馬上執行發射子彈行為。這個行為是由坦克自身發出的,並且考慮到所有的坦克都有發射子彈的功能,為此,需要先寫我們的Tank類。這個類是敵人坦克和我方坦克共有的,其余兩者均繼承自(Class) Tank類。

這個類的設計思路如下

該類定義的坦克的初始速度,方向,子彈的速度,並且具有發射子彈的功能。代碼如下:

public class Tank {

   

    int positionX;        //坦克的初始位置x

    int positionY;        //坦克的初始位置y

    int direct;           //坦克的方向

    int speed;            //坦克速度

    int bulletSpeed=10;  //子彈速度

   

   

    public int getPositionX() {

       return positionX;

    }

    public void setPositionX(int positionX) {

       this.positionX = positionX;

    }

    public int getPositionY() {

       return positionY;

    }

    public void setPositionY(int positionY) {

       this.positionY = positionY;

    }

    public int getDirect() {

       return direct;

    }

    public void setDirect(int direct) {

       this.direct = direct;

    }

    public int getSpeed() {

       return speed;

    }

    public void setSpeed(int speed) {

       this.speed = speed;

    }

 

 

 

 

    //坦克上移

    public void moveUp()

    {

      

    }

    //坦克向右

    public void moveRight(){

    }

    //坦克下移

    public void moveDown(){

      

    }

    //坦克左移

    public void moveLeft(){

    }

   

 

 

    //坦克射擊子彈行為

    public void shout()

    {  

}

注意到shout這個方法,在用戶按下空格鍵之后,通過監視器調用而發射子彈,但注意,子彈發射出去之后便不再受控制,為此,需要將每一個子彈都做成一個線程。出於這個緣故,並且考慮到子彈仍舊有屬於自己的特性,比如速度、方向、初始位置等,需要將子彈單獨做成一個類,這個類實現Runnable接口(為了后面產生其他武器,這里通過接口實現線程而不是繼承而來)。當一個子彈杯創建之后,應當馬上啟動子彈的線程。

 

現在可以讓我方的子彈在按下空格之后實現發射一個子彈,下一步是讓玩家可以通過上下左右鍵控制坦克的方向。當玩家敲下相應的鍵之后,監視器馬上調用繼承自Tank的MTank(我方坦克)。這點很容易就試下,代碼類似地: 

//坦克上移

    public void moveUp()

    {  

if(this.positionY>0) //保證用戶不出界

       this.positionY-=this.speed;

      

    }

下面的任務是讓敵人也可以發射子彈,注意,敵人的子彈是不受玩家控制的,並且要求敵人子彈不能連發,也就是說,敵人的一個子彈在死亡之前,是不容許在產生新的子彈的,為了讓敵人自動發射子彈,我們改變思路,找一個容器來存放敵人的子彈,在paint里面,通過遍歷容器里面的子彈來模擬自動發射,注意:一旦程序執行,paint總是在不停的調用,因為JPanel已經是個線程,在它的run()函數中,用while循環來保證paint永遠運轉。

 

考慮到線程的安全問題,采用Vector 向量來存放子彈,

    Vector<Bullet> bullets=new Vector<Bullet>();

注意,每輛坦克都有自己的子彈容器,它是Tank類的一個屬性。下一步,讓坦克動起來,理所當然地,將敵方坦克做成一個線程,該線程讓坦克自動運行,類似地在線程run中這樣做:      

while(true){

    try{

Thread.sleep(30);

       }

    catch(Exception e){

}

    this.aotoMove();

           }

 

到目前為止:我方的坦克可以通過控制自由移動並發射子彈,敵人的坦克也實現了自由移動並自動發射子彈。

下面要做的就是,當我方坦克擊中敵人坦克之后,敵人坦克消失,反之亦然。

實現這一切比想象中的還要容易,只需要在paint中加入碰撞檢測。

hitTest()函數將提供檢測機制。當我方的坦克發射的子彈落在敵人坦克所在的區域,我們應該讓敵方的坦克消失。

為了統一並實現該要求,需要定義一個Vector存放這個游戲中所有的敵方坦克,這樣在paint繪制的時候,只需要讀取Vector向量來動態的產生坦克。

 

下面,開始具體碰撞檢測:

注意:

一旦檢測到我方的坦克的子彈落在敵方坦克的區域,執行某操作,產生擊毀效果。

一旦檢測道敵方坦克的子彈落在我方坦克的區域,執行某操作,產生擊毀效果。

一旦檢測到子彈飛出游戲區域,執行某操作,從向量中移除該子彈

一旦檢測到敵人的坦克互相碰撞或者遇到牆壁,執行某操作,改變方向

碰撞檢測的過程必須要注意的是,由於碰撞檢測放在paint類,執行速度過快,在檢測完畢改變方向之后,一定要有一個延遲,不能馬上判斷,否則會出現“無頭坦克”,到處亂撞。

解決的方法有:在坦克移動的時候,用for循環+Thread.sleep來控制坦克在一次移動中必須走完指定的路線。

2:在改變方向后,有一個小小的延遲,保證在此期間,坦克有一個微小的掙脫力來掙脫碰撞帶來的困擾。

 

 

最后,在增加游戲開始的畫面:新建一個JPanel,當游戲開始的時候顯示這個界面,通過times%2的方法讓這個界面的字符串有個閃的過程。

將MyPanel的創建放到一個合適的邏輯中。而不是一開始就。當執行MyPanel的時候,記得先移除新建的JPanel。

截止目前:游戲的基本功能已經完結。V_1.0

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM