天天看點

JAVA基礎小項目 - 坦克大戰

JAVA基礎小項目 - 坦克大戰

前言:

這個項目是之前備份電腦資料的時候看到的,不禁一陣感慨自己當初自學程式設計的心酸和淚水。是以分享一下自己當初寫的的垃圾代碼。雖然我不是任天堂忠實粉絲,但是對于90後來說坦克大戰基本是人人都玩過的一款小霸王遊戲機的遊戲。

這個項目對于已經入行的人來說沒有價值,分享出來主要是希望對于初學程式設計的人給一點 “吸引”吧,原來代碼可以做到這麼愉快的事情。這個坦克大戰也是自己跟着教育訓練機構的教學視訊邊看邊敲的。

花了一天左右的時間把代碼稍微整理了一下代碼同時寫了這份文檔,這裡分享出來。

對于入行程式設計的同學個人的建議如果要快速成長還是多練,多做。很多東西做多了之後,涉及自己的盲區會促使你不斷的學習和進步。

PS:代碼使用Eclipse寫的,這裡用IDEA整理了一下代碼

此代碼如果閱讀存在難度,建議看一下韓順平的JAVA基礎坦克大戰的課程。這裡的源代碼也是跟着課程敲的

真是一個好時代,當初這些資源還要網上翻半天

項目位址

後續文檔更新請看readme

項目簡介:

個人前幾年自學的時候從一個教學視訊的,韓順平老師的JAVA初級坦克大戰。個人跟着視訊邊學邊敲之後,對于程式設計的興趣大大的提升。後面越學越快樂。

所用技術

  1. JAVA GUI(遠古技術,千萬别深入,看看即可)
  2. JAVA

面向群體:

  1. 初學JAVA者,可以看看這個項目鍛煉動手能力
  2. 完全不了解什麼是面向對象
  3. 對于小遊戲有點興趣的
  4. 如果你厭惡枯燥的學習,做一個小遊戲或許能給你一點動力

項目截圖:

JAVA基礎小項目 - 坦克大戰
JAVA基礎小項目 - 坦克大戰
JAVA基礎小項目 - 坦克大戰

操作坦克的方法:

最後一版本有效,早起版本部分功能或者所有功能按鍵無效

  • WASD
  • J:為射出子彈

需求文檔(或許是):

由于當初是跟着視訊做的,雖然具體的記憶忘了,但是自己跟着敲的同時忘了做需求的更新,是以這裡有部分需求和思路斷了。如果有不同的,後續補充GIT的README文檔。

/*
 *    需求:
 *      坦克大戰:
 *      功能:
 *        1.畫出坦克,
 *
 *    思路:
 *      1.首先坦克想象由五個部件組成兩個矩形,一個長方形或者正方形,一個圓
 *        一條直線
 *
 *      2.畫坦克的時候需要使用到畫筆工具
 *        必須在構造函數初始化使用畫筆工具
 *
 *      3.在設定方向以及畫出不同方向的坦克
 *
 *      4.敵方坦克畫出來需要使用父類方法
 *        敵方坦克的坐标需要設定,
 *        使用一個集合儲存敵方坦克Vector集合便于删除和添加
 *
 *      5.發射子彈是一個線程
 *        具有線程的功能
 *        另外線程對與子彈方向運動軌迹不同
 *
 *      6.需要把子彈畫出來
 *        在按下J鍵的時候發射子彈
 *          實作連發使用集合存儲
 *
 *    更新:
 *      1.讓敵人能夠發射子彈
        解決方法
          1.敵人發射子彈是一個多線程方法,應當在敵人的run函數當中實作
          2.坦克發射子彈和移動都是坦克本身具有的功能
 *
 *      思路:
 *        1.在敵人類裡面需要添加一個射擊方法
 *          與我方一樣,但是敵人是自動射擊或者說每過幾秒射擊一次
 *
 *        2.我方坦克子彈連發
 *          使用一個集合儲存建立的對象,畫出子彈使用集合中的對象
 *          我方坦克子彈連發過快,需要限定
 *
 *        3.
 *          我方坦克擊中敵人坦克之後,敵人坦克就要消失
 *          需要擷取到敵人的一個定點坐标,然後界定一個範圍
 *          寫一個專門的函數判斷是否擊中敵人
 *
 *          在哪裡判斷是否擊中敵人
 * ·        因為每一顆子彈都要與所有的坦克比對,并且每一次比對都要
 *          雙重判斷每次都要進行建立對象
 *          圖檔問題沒有得到解決
 *
 *    更新
 *        1.需要實作敵人的坦克不斷的移動使用多線程的手段實作
 *
 *        2.需要實作敵人能夠發射子彈的功能
 *        實作方法:
 *          建立一個敵人的子彈集合
 *          如何敵人何時發射子彈?
 *          使用多重循環判斷是否需要添加薪子彈
 *
 *        3.實作自己被子彈擊中也會消失
 *          對于摧毀坦克進行更新
 *
 *        4.
 *          較難!
 *          實作坦克不覆寫運動,
 *          1.首先改判斷在坦克類中實作
 *          2.需要用到一個方法擷取到生成的坦克類
 *          3.對于地方其中一輛坦克的選擇,都要循環與其他所有坦克進行比對
 *            并且要事先判斷是否為我方坦克
 *          4.**對于點位的判斷要判斷兩個點,才能夠保證不會産生碰撞
 *
 *        5.實作選擇關卡的功能
 *          思路:
 *            1.可以建立一個選擇關卡的面闆
 *            2.暫時先實作不同的關卡敵人坦克的數量不同
 *            3.實作閃爍功能,使用多線程的方法,注意線程的關閉
 *            4.對于選項添加事件屬性,添加事件
 *
 *        5.畫出我方坦克擊中了多少輛地方坦克
 *          1.對于總體界面進行修改
 *          2.顯示敵人坦克的數量
 *          擴充:
 *            1.建立幫助文檔
 *          3.擴充:我方坦克的生命值,當生命值為0的時候遊戲結束
 *          4.記錄我方擊中了多少地方坦克
 *            使用檔案操作完成
 *
 *        6.實作重新開始的功能
 *
 *        7.實作存盤退出的功能
 *          思路:
 *            選在主界面增加兩個按鈕
 *            1.記錄所有坦克的坐标
 *
 *        8.實作暫停的功能
 *          思路:
 *            暫停功能可以通過一個布爾值進行判斷,當按下某個按鈕的時候就要進行布爾值的改變
 *            需要暫停的對象
 *              将多線程子彈的速度前進功能暫停
 *              敵人坦克無法轉向和前進
 *              我方坦克無法轉向和前進
 *
 *        9.實作播放音樂的功能
 *          自學 - 未實作
 *
 *
 *
 *
 * */      

版本疊代和介紹:

介紹:

代碼比較多,我會抽幾處了解起來比較難以了解的地方說明一下,其他的代碼需要看細節。如果有不懂的歡迎在issue提出,個人隻要有空一定給予答複。

第一個版本

版本概述:畫出坦克(version1)

我們的第一步是畫出我們的坦克,畫出我方坦克的方法還是非常簡單的。

*     思路:
 *      1.首先坦克想象由五個部件組成兩個矩形,一個長方形或者正方形,一個圓
 *        一條直線
 *
 *      2.畫坦克的時候需要使用到畫筆工具
 *        必須在構造函數初始化使用畫筆工具
 *
 *      3.在設定方向以及畫出不同方向的坦克      

擁有坦克的第一步是畫出坦克

JAVA基礎小項目 - 坦克大戰

畫出坦克的核心代碼如下:

/**
     * 畫坦克需要提取封裝
     * 1.畫出來之前先确定顔色,是敵人坦克還是我方坦克
     * 2.參數為坐标做,畫筆(重要),以及坦克類型和方向
     */
    private void paintMyTank(int x, int y, Graphics g, int direct, String type) {
        //畫之前先确定坦克的顔色
        switch (type) {
            case "mytank": {
                g.setColor(Color.red);
                break;
            }
            case "enemytank": {
                g.setColor(Color.cyan);
                break;
            }
        }
        //向上
        if (direct == 0) {//先畫出我的坦克
            //畫出左邊的矩形,先設定顔色
            g.fill3DRect(x, x, 5, 30, false);

            //畫出中間的長方形
            g.fill3DRect(x + 5, x + 5, 10, 20, false);

            //畫出中間圓圈,使用填充橢圓
            g.fillOval(x + 6, x + 9, 7, 7);

            //畫出一條直線
            g.drawLine(x + 10, x, x + 10, x + 15);

            //畫出另一邊矩形
            g.fill3DRect(x + 15, x, 5, 30, false);
        }

    }      

如果知道數字的意思,直接将數字修改大小就可以知道效果了

第二個版本

JAVA基礎小項目 - 坦克大戰

版本概述:畫出我方坦克不同形狀,敵方坦克(version2),我方坦克可以進行行動

在上個版本當中,我們發現我們的坦克隻有一個朝向,在這個版本中,增加了坦克的不同朝向。同時增加了敵人的坦克類。

由于敵人有很多個,是以用了一個集合來維護和設定。同時加入了坐标系統,可以實作不同的坦克挪到不同的位置。

這個版本的關鍵代碼,不是在畫坦克的上面,而是在于加入了鍵盤的監聽事件:

// version2.DrawTank.java 更多細節請檢視
public class DrawTank extends JPanel implements KeyListener {
    // 省略一大坨代碼


/**
     * 使用wsad進行控制
     * 也可以改為上下左右鍵
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) {
            this.mytank.setDirect(0);
            this.mytank.move_up();
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            this.mytank.setDirect(1);
            this.mytank.move_right();
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            this.mytank.setDirect(2);
            this.mytank.move_down();
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            //改變方向
            this.mytank.setDirect(3);
            this.mytank.move_left();
        }
    }
}      

實作KeyListener接口并且監聽對應的方法。

JAVA的GUI有一個事件監聽驅動模型,意思就是說我們實作對應的驅動接口,并且覆寫對應的方法,在代碼運作并且觸發相關事件的适合,模型就可以觸發我們實作定義好的代碼,這裡很明顯就是設計模式,有興趣可以去了解一下

第三個版本

從這個版本就開始變得稍微複雜一點了,用了多線程的内容,因為要讓我們的坦克和敵人的坦克“動”起來,其實讓坦克移動和我方坦克移動的道理都是一樣的:高速的擦寫和描繪。和我們的滑鼠以及計算機顯示畫面的本質都是一樣的。

JAVA基礎小項目 - 坦克大戰

這個版本中,比較核心的内容是如何發射子彈和讓子彈消失:

public class Bullet implements Runnable {

    /**
     * 定義子彈的xy坐标
     */
    private int x, y;
    /**
     * 子彈的顔色
     */
    int color;
    /**
     * 子彈的方向
     */
    int direct;
    /**
     * 子彈移動速度
     */
    int screed;
    /**
     * 判斷是否越界
     */
    boolean isOut = false;

    /**
     * 越界範圍
     */
    int outx = 400;
    /**
     * 越界範圍
     */
    int outy = 300;

    public Bullet(int x, int y, int direct) {
        this.x = x;
        this.y = y;
        this.direct = direct;
        this.screed = 1;
    }

    // 省略get/set

    @Override
    public void run() {
        //坦克一旦建立就要運動
        //因為移動的太快,需要減慢速度
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                //
                e.printStackTrace();
            }

            switch (this.direct) {
                case 0:
                    y -= screed;
                    break;
                case 1:
                    x += screed;
                    break;
                case 2:
                    y += screed;
                    break;
                case 3:
                    x -= screed;
                    break;
            }
            System.out.println(x + "..." + y);
            //碰到邊緣消失
            if (x < 0 || x > outx || y < 0 || y > outy) {
                isOut = true;
                break;
            }
        }
        // 子彈什麼時候消亡?
    }

    /**
     * 判斷是否越界
     */
    public void outLine() {
    }
}      
  1. 在坦克的内部維護一個變量isOut,判定有沒有越界
  2. 如果出現了越界,則flag進行設定

接着,在繪畫的方法裡面,判定有沒有越界:

/**
     * 繪畫方法
     * @param g
     */
@Override
public void paint(Graphics g) {
    super.paint(g);

    //畫出背景色
    g.fill3DRect(0, 0, 600, 400, false);
    //畫出自己的坦克
    paintMyTank(mytank.getX(), mytank.getY(), g, mytank.getDirect(), mytank.getColor());
    //畫出敵人的坦克
    paintEnemyTank(g);

    //畫出子彈并且确定沒有越界
    if (mytank.but != null && !mytank.but.isOut) {
        g.fill3DRect(mytank.but.getX(), mytank.but.getY(), 5, 5, false);
    }
}      

第四個版本:

從這一個版本開始,一個遊戲的簡單雛形已經有了,這一個版本實作了讓敵人移動的同時發射子彈的功能,同時我方的坦克射擊敵人的時候,可以讓敵人消失

怎麼樣讓敵人可以邊移動邊發射子彈:

我們需要在敵人的多線程run代碼裡面,然敵人進行間歇性的走動:

@Override
    //我們發現坦克在原地抽搐,我們要實作坦克的平穩運作
    //實作坦克運動不會越界
    public void run() {

        do {
            switch (this.direct) {
                case 0:
                    for (int i = 0; i < 30; i++) {
                        if (y > 0)
                            y -= sreed;
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {

                            e.printStackTrace();
                        }
                    }
                    break;
                case 1:
                    for (int i = 0; i < 30; i++) {
                        if (x < 500)
                            x += sreed;
                        try {
                            // 短暫的停頓
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2:
                    for (int i = 0; i < 30; i++) {
                        if (y < 400)
                            y += sreed;
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {

                            e.printStackTrace();
                        }
                    }
                    break;
                case 3:
                    for (int i = 0; i < 30; i++) {
                        if (x > 0)
                            x -= sreed;
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {

                            e.printStackTrace();
                        }
                    }
                    break;

            }
            //不同的方向移動的方向不同
            this.direct = (int) (Math.random() * 4);

        } while (this.isLive);
    }      

至于生成子彈,需要定時去輪詢所有的坦克,檢查坦克中組合的子彈集合是否存在子彈,如果小于一定的數量,需要生成對應的子彈對象同時加入到敵人的坦克當中。由于子彈建立就會開始執行線程進行

@Override
    public void run() {
        //限定一段時間重新繪制
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //判斷是否擊中
            for (int x = 0; x < mytank.vecs.size(); x++) {
                //每一顆子彈和每一個坦克比對
                //取出一顆子彈之前判斷是否有子彈
                buts = mytank.vecs.get(x);

                //判斷子彈是否有效
                if (buts.isOut()) {
                    continue;
                }
                //取出每一個坦克與它判斷
                for (int y = 0; y < vec.size(); y++) {
                    //判斷敵方坦克是否死亡
                    if (vec.get(y).isLive) {
                        en = vec.get(y);
                        //記性判斷是否擊中操作
                        hitTank(en, buts);
                    }
                }

            }

            //如果子彈數小于一定數目
            for (int x = 0; x < vec.size(); x++) {
                EnemyTank et = vec.get(x);
                //周遊每一輛坦克的子彈集合
                if (!et.isLive()) {
                    continue;
                }
                if (et.vecs.size() < 1) {
                    //對于不同的坦克方向生成子彈的方向也不同
                    Bullet enybut = null;
                    switch (et.getDirect()) {
                        case 0:
                            enybut = new Bullet(et.getX() + 10, et.getY(), 0);
                            //将建立的子彈加入到集合當中
                            et.vecs.addElement(enybut);
                            break;
                        case 1:
                            enybut = new Bullet(et.getX() + 30, et.getY() + 10, 1);
                            et.vecs.addElement(enybut);
                            break;
                        case 2:
                            enybut = new Bullet(et.getX() + 10, et.getY() + 30, 2);
                            et.vecs.addElement(enybut);
                            break;
                        case 3:
                            enybut = new Bullet(et.getX(), et.getY() + 10, 3);
                            et.vecs.addElement(enybut);
                            break;

                    }
                    new Thread(enybut).start();

                }
            }
            //重繪
            this.repaint();
        }
    }      

在子彈類當中進行不斷的數值改變:

下面的内容表示子彈的類

public class Bullet implements Runnable {
    //隐藏一大段代碼:

public void run() {

        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            switch (this.direct) {
                case 0:
                    this.y -= screed;
                    break;
                case 1:
                    this.x += screed;
                    break;
                case 2:
                    this.y += screed;
                    break;
                case 3:
                    this.x -= screed;
                    break;
            }
            //碰到邊緣消失
            if (x < 0 || x > outx || y < 0 || y > outy) {
                isOut = true;
                break;
            }

        }
    }
}      

第五個版本:

在第五個版本當中,我們實作了開始菜單的界面,同時視線菜單的不斷顯示:

界面會不斷的閃爍

接着,敵人增加了子彈可以摧毀我們的方法

JAVA基礎小項目 - 坦克大戰
JAVA基礎小項目 - 坦克大戰

接着,我們可以實作爆炸的效果:

由于爆炸的效果不好截圖,請看源代碼
JAVA基礎小項目 - 坦克大戰
/**
 * 實作閃爍功能
 * 重構坦克 - 第五版
 * @author zxd
 * @version 1.0
 * @date 2021/1/29 23:54
 */
class SelectIsSallup extends JPanel implements Runnable {
    /**
     * 時間屬性
     */
    int times = 0;

    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 600, 400);
        if (times % 2 == 0) {
            //畫出文字
            Font font1 = new Font("華文新魏", Font.BOLD, 20);
            //設定字型的顔色
            g.setColor(Color.yellow);
            g.setFont(font1);
            g.drawString("stage 1", 200, 150);
        }

    }

    @Override
    public void run() {

        while (true) {
            try {
                Thread.sleep(750);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
            if (times > 500)
                times = 0;
            times++;
            this.repaint();

        }
    }
}      

如何讓敵人的子彈對我們造成傷害:

/**
     * 建立一個方法,判斷是否産生碰撞
     * 是否攻擊了其他的坦克
     * @return
     */
    private boolean isTouchOther() {
        // 根據自己的方向進行選擇判斷
        switch (this.direct) {
            // 坦克向上走的時候
            case 0:
                // 取出所有的坦克對象
                for (int x = 0; x < enevec.size(); x++) {
                    EnemyTank et = enevec.get(x);
                    //如果不是自己的坦克
                    if (et != this) {
                        //如果敵人的坦克朝上或者朝下的時候
                        if (et.direct == 0 || et.direct == 2) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 20
                                    && this.y >= et.y && this.y <= et.y + 30) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20
                                    && this.y >= et.y && this.y <= et.y + 30) {
                                return true;
                            }
                        }
                        //如果敵人是朝左邊或者右邊的時候
                        if (et.direct == 1 || et.direct == 3) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 30
                                    && this.y >= et.y && this.y <= et.y + 20) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30
                                    && this.y >= et.y && this.y <= et.y + 20) {
                                return true;
                            }
                        }
                    }

                }
                break;
            //  坦克想右邊走的時候
            case 1:
                // 取出所有的坦克對象
                for (int x = 0; x < enevec.size(); x++) {
                    EnemyTank et = enevec.get(x);
                    //如果不是自己的坦克
                    if (et != this) {
                        //如果敵人的坦克朝上或者朝下的時候
                        if (et.direct == 0 || et.direct == 2) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20
                                    && this.y >= et.y && this.y <= et.y + 30) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20
                                    && this.y >= et.y && this.y <= et.y + 30) {
                                return true;
                            }
                        }
                        //如果敵人是朝左邊或者右邊的時候
                        if (et.direct == 1 || et.direct == 3) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30
                                    && this.y + 20 >= et.y && this.y <= et.y + 20) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30
                                    && this.y + 20 >= et.y && this.y <= et.y + 20) {
                                return true;
                            }
                        }
                    }

                }

                // 坦克想下的時候
            case 2:
                // 取出所有的坦克對象
                for (int x = 0; x < enevec.size(); x++) {
                    EnemyTank et = enevec.get(x);
                    //如果不是自己的坦克
                    if (et != this) {
                        //如果敵人的坦克朝上或者朝下的時候
                        if (et.direct == 0 || et.direct == 2) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 20
                                    && this.y + 30 >= et.y && this.y + 30 <= et.y + 30) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20
                                    && this.y + 30 >= et.y && this.y + 30 <= et.y + 30) {
                                return true;
                            }
                        }
                        //如果敵人是朝左邊或者右邊的時候
                        if (et.direct == 1 || et.direct == 3) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 30
                                    && this.y + 30 >= et.y && this.y + 30 <= et.y + 20) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30
                                    && this.y + 30 >= et.y && this.y + 30 <= et.y + 20) {
                                return true;
                            }
                        }
                    }

                }
                break;

            // 坦克向左移動的時候
            case 3:
                // 取出所有的坦克對象
                for (int x = 0; x < enevec.size(); x++) {
                    EnemyTank et = enevec.get(x);
                    //如果不是自己的坦克
                    if (et != this) {
                        //如果敵人的坦克朝上或者朝下的時候
                        if (et.direct == 0 || et.direct == 2) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 20
                                    && this.y >= et.y && this.y <= et.y + 30) {
                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 20
                                    && this.y + 20 >= et.y && this.y + 20 <= et.y + 30) {
                                return true;
                            }
                        }
                        //如果敵人是朝左邊或者右邊的時候
                        if (et.direct == 1 || et.direct == 3) {
                            //判斷邊界
                            //對于第一個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 30
                                    && this.y >= et.y && this.y <= et.y + 20) {

                                return true;
                            }
                            //對于第二個點進行判斷
                            if (this.x >= et.x && this.x <= et.x + 30
                                    && this.y + 20 >= et.y && this.y + 20 <= et.y + 20) {
                                return true;
                            }
                        }
                    }

                }
        }
        return false;

    }      

最終版本:

在最終的版本當中,一個坦克大戰的基本遊戲算是完成了,當然還有很多需要完成點。

//暫停功能
if(e.getKeyCode()==KeyEvent.VK_P)
{
    if(this.clickcount%2 == 0)
        mytank.setSuspend(false);
    else
        mytank.setSuspend(true);

    //利用循環将坦克類中的子彈速度變成0
    for(int x=0; x<vec.size(); x++)
    {
        en = vec.get(x);
        //敵方坦克移動速度歸于0

        //坦克不允許移動
        if(this.clickcount%2 == 0)
            en.setSuspend(false);
        else
            en.setSuspend(true);
        for(int y=0; y<en.vecs.size(); y++)
        {
            //子彈的速度變成0
            if(this.clickcount%2 == 0)
                en.vecs.get(y).setSuspend(false);
            else
                en.vecs.get(y).setSuspend(true);

        }
    }
    this.clickcount++;

}      

總結: