关于java:JAVA基础小项目-坦克大战

9次阅读

共计 10856 个字符,预计需要花费 28 分钟才能阅读完成。

JAVA 根底小我的项目 – 坦克大战

前言:

这个我的项目是之前备份电脑材料的时候看到的,不禁一阵感叹本人当初自学编程的心酸和泪水。所以分享一下本人当初写的的垃圾代码。尽管我不是任天堂忠诚粉丝,然而对于 90 起初说坦克大战根本是人人都玩过的一款小霸王游戏机的游戏。

这个我的项目对于曾经入行的人来说没有价值,分享进去次要是心愿对于初学编程的人给一点“吸引”吧,原来代码能够做到这么欢快的事件。这个坦克大战也是本人跟着培训机构的教学视频边看边敲的。

花了一天左右的工夫把代码略微整顿了一下代码同时写了这份文档,这里分享进去。

对于入行编程的同学集体的倡议如果要疾速成长还是多练,多做。很多货色做多了之后,波及本人的盲区会促使你一直的学习和提高。

PS:代码应用 Eclipse 写的,这里用 IDEA 整顿了一下代码

此代码如果浏览存在难度,倡议看一下韩顺平的 JAVA 根底坦克大战的课程。这里的源代码也是跟着课程敲的。

https://www.bilibili.com/vide…

真是一个好时代,当初这些资源还要网上翻半天

<!– more –>

我的项目地址

https://github.com/lazyTimes/…

后续文档更新请看 readne

我的项目简介:

集体前几年自学的时候从一个教学视频的,韩顺平老师的 JAVA 高级坦克大战。集体跟着视频边学边敲之后,对于编程的趣味大大的晋升。前面越学越高兴。

所用技术

  1. JAVA GUI(远古技术,千万别深刻,看看即可)
  2. JAVA

面向群体:

  1. 初学 JAVA 者,能够看看这个我的项目锤炼入手能力
  2. 齐全不理解什么是面向对象
  3. 对于小游戏有点趣味的
  4. 如果你讨厌干燥的学习,做一个小游戏或者能给你一点能源

我的项目截图:

操作坦克的办法:

最初一版本无效,早起版本局部性能或者所有性能按键有效

  • 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. 在设置方向以及画出不同方向的坦克

领有坦克的第一步是画出坦克

画出坦克的外围代码如下:

/**
     * 画坦克须要提取封装
     * 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);
        }

    }

如果晓得数字的意思,间接将数字批改大小就能够晓得成果了

第二个版本

版本概述:画出我方坦克不同形态,敌方坦克(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 有一个事件监听驱动模型,意思就是说咱们实现对应的驱动接口,并且笼罩对应的办法,在代码运行并且触发相干事件的适宜,模型就能够触发咱们实现定义好的代码,这里很显著就是设计模式,有趣味能够去理解一下

第三个版本

从这个版本就开始变得略微简单一点了,用了多线程的内容,因为要让咱们的坦克和敌人的坦克“动”起来,其实让坦克挪动和我方坦克挪动的情理都是一样的:高速的 擦写和描述。和咱们的鼠标以及计算机显示画面的实质都是一样的。

这个版本中,比拟外围的内容是如何发射子弹和让子弹隐没:

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;
            }
           
        }
    }
}

第五个版本:

在第五个版本当中,咱们实现了开始菜单的界面,同时眼帘菜单的一直显示:

界面会一直的闪动

接着,敌人减少了子弹能够捣毁咱们的办法

接着,咱们能够实现爆炸的成果:

因为爆炸的成果不好截图,请看源代码

/**
 * 实现闪动性能
 * 重构坦克 - 第五版
 * @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;

    }

最终版本:

在最终的版本当中,一个坦克大战的根本游戏算是实现了,当然还有很多须要实现点。

这里次要提醒一下暂停这一个性能点:

暂停的次要思维是为坦克加一个状态去管制坦克的所有行为。让暂停的 flag 为 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++;

}

总结:

这个文档不是最终版本,如果有不懂的欢送提 issue,承诺给予回答然而不会再改变代码了。

正文完
 0