暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java实现坦克大战小游戏

java小哥 2021-11-03
581

主要内容

使用Java面向对象思想设计并开发一个有GUI界面的小游戏坦克大战,允许玩家与电脑玩家进行对战,玩家使用键盘操控坦克,人机具有一定的移动和开火逻辑。

实现功能

1.有游戏图像界面,让玩家能看到游戏给出反馈;

2.有人机交互功能,完成能操控指定游戏元素;

3.不同阵营的坦克,具备不同外观,可分别敌我;

4.敌我坦克皆能移动和开关。

游戏界面

主菜单

游戏界面

项目结构

app包下的GameMain类是游戏的入口函数。img目录下存放游戏的静态资源。

tank包

该包下的类是tank的实体类,tank类分为我方坦克MyTank类、敌方坦克EnemyTank类。两个坦克类都继承了坦克父类tank类。

tank.class

    /**
    * 坦克类的属性
    */
    public abstract class Tank {

    //坦克前进的四个方向
    public static final int DIR_UP = 0;
    public static final int DIR_DOWN = 1;
    public static final int DIR_LEFT = 2;
    public static final int DIR_RIGHT = 3;

    //坦克的半径
    public static final int RADIUS = 30;

    //默认速度
    public static final int DEFAULT_SPEED = 10;

    //坦克状态
    public static final int STATE_STAND = 0;
    public static final int STATE_MOVE = 1;
    public static final int STATE_DIE = 2;

    //坦克的初始生命值
    public static final int DEFAULT_HP = 1000;

    private int x, y;
    private int hp = DEFAULT_HP;
    private int atk;//攻击力
    private int speed = DEFAULT_SPEED;
    private int dir;//标识坦克的方向
    private int state = STATE_STAND;//标识坦克的状态
    private Color color;
    private boolean isEnemy = false;//标识是否是敌人
    get/set...
    }

    tank类的方法

      //使用ArrayList容器管理子弹
      private List<Bullet> bullets = new ArrayList();

      //使用ArrayList容器管理爆炸效果
      private List<Explode> explodes = new ArrayList<>();

      public Tank(int x, int y, int dir) {
      this.x = x;
      this.y = y;
      this.dir = dir;
      color = MyUtil.getRandomColor();
      }

      /**
      * 绘制坦克
      *
      * @param g
      */
      public void draw(Graphics g) {

      logic();//调用坦克逻辑处理方法,包括move方法

      drawTankImg(g);

      drawBullet(g);//调用绘制子弹的方法

      }

      /**
      * 使用图片的方法绘制坦克
      *
      * @param g
      */
      public abstract void drawTankImg(Graphics g);

      /**
      * 使用系统的方法绘制坦克
      *
      * @param g
      */
      private void drawTank(Graphics g) {
      g.setColor(color);

      //绘制坦克圆
      g.fillOval(x - RADIUS, y - RADIUS, RADIUS << 1, RADIUS << 1);
      //绘制坦克炮管
      //炮管的坐标
      int endX = x;
      int endY = y;
      switch (dir) {
      case DIR_UP:
      endY = y - RADIUS * 2;
      break;
      case DIR_DOWN:
      endY = y + RADIUS * 2;
      break;
      case DIR_LEFT:
      endX = x - RADIUS * 2;
      break;
      case DIR_RIGHT:
      endX = x + RADIUS * 2;
      break;
      }
      g.drawLine(x, y, endX, endY);
      }

      //坦克逻辑处理
      private void logic() {
      switch (state) {
      case STATE_STAND:
      break;
      case STATE_MOVE:
      move();
      break;
      case STATE_DIE:
      break;
      }
      }

      //坦克移动的功能
      private void move() {
      switch (dir) {
      case DIR_UP:
      y -= speed;
      if (y < RADIUS + GameFrame.titleBarH) {
      y = RADIUS + GameFrame.titleBarH;
      }
      break;
      case DIR_DOWN:
      y += speed;
      if (y > Constant.FRAME_HEIGHT - RADIUS - GameFrame.titleBarH) {
      y = Constant.FRAME_HEIGHT - RADIUS - GameFrame.titleBarH;
      }
      break;
      case DIR_LEFT:
      x -= speed;
      if (x < RADIUS) {
      x = RADIUS;
      }
      break;
      case DIR_RIGHT:
      x += speed;
      if (x > Constant.FRAME_WIDTH - RADIUS - GameFrame.titleBarH) {
      x = Constant.FRAME_WIDTH - RADIUS - GameFrame.titleBarH;
      }
      break;
      }
      }

      /**
      * 坦克发射炮弹的方法
      * 创建一个子弹实例,并将子弹加入到子弹容器中
      */
      public void fire() {
      int bulletX = x;
      int bulletY = y;

      switch (dir) {
      case DIR_UP:
      bulletY -= RADIUS;
      break;
      case DIR_DOWN:
      bulletY += RADIUS;
      break;
      case DIR_LEFT:
      bulletX -= RADIUS;
      break;
      case DIR_RIGHT:
      bulletX += RADIUS;
      break;
      }
      // Bullet bullet = new Bullet(bulletX, bulletY, dir, atk, color);
      Bullet bullet = BulletPool.get();//从池塘中获取子弹
      bullet.setX(bulletX);
      bullet.setY(bulletY);
      bullet.setDir(dir);
      bullet.setAtk(atk);
      bullet.setColor(color);
      bullet.setVisible(true);
      bullets.add(bullet);
      }

      /**
      * 绘制出容器里的子弹
      *
      * @param g
      */
      private void drawBullet(Graphics g) {
      for (Bullet bullet : bullets) {
      bullet.draw(g);
      }

      //遍历所有子弹,并将超出frame的子弹还原到对象池
      for (int i = 0; i < bullets.size(); i++) {
      Bullet bullet = bullets.get(i);
      if (!bullet.isVisible()) {//如果当前子弹超出frame,则还原到对象池
      Bullet remove = bullets.remove(i);
      BulletPool.theReturn(remove);
      i--;
      }
      }
      }

      /**
      * 坦克与敌方子弹的碰撞检测
      *
      * @param bullets
      */
      public void collideBullet(List<Bullet> bullets) {
      //遍历集合的所有的子弹,依次进行碰撞检测
      for (Bullet bullet : bullets) {
      int bulletX = bullet.getX();
      int bulletY = bullet.getY();
      if (MyUtil.isCollide(x, y, RADIUS, bulletX, bulletY)) {
      //子弹消失
      bullet.setVisible(false);

      //添加爆炸效果
      Explode explode = ExplodePool.get();
      explode.setX(x + RADIUS * 2);
      explode.setY(y + RADIUS 2);
      explode.setVisible(true);
      explode.setIndex(0);
      explodes.add(explode);
      }
      }
      }

      /**
      * 绘制当前坦克的爆炸效果
      *
      * @param g
      */
      public void drawExplodes(Graphics g) {
      for (Explode explode : explodes) {
      explode.draw(g);
      }

      for (int i = 0; i < explodes.size(); i++) {
      Explode explode = explodes.get(i);

      if (!explode.isVisible()) {
      Explode remove = explodes.remove(i);
      ExplodePool.theReturn(remove);
      i--;
      }
      }
      }

      我方坦克MyTank.class

        public class MyTank extends Tank {

        private static Image[] tankImg;

        static {
        tankImg = new Image[4];
        tankImg[0] = getImage("img/p1tankU.gif");
        tankImg[1] = getImage("img/p1tankD.gif");
        tankImg[2] = getImage("img/p1tankL.gif");
        tankImg[3] = getImage("img/p1tankR.gif");


        }

        public MyTank(int x, int y, int dir) {
        super(x, y, dir);
        }

        @Override
        public void drawTankImg(Graphics g) {
        g.drawImage(tankImg[getDir()], getX() - RADIUS, getY() - RADIUS, null);
        }
        }

        敌方坦克EnemyTank.class

        敌方坦克为电脑控制,有简单的AI,可自动移动开火。

          public class EnemyTank extends Tank {

          private static Image[] enemyImg;

          static {
          enemyImg = new Image[4];
          enemyImg[0] = getImage("img/p2tankU.gif");
          enemyImg[1] = getImage("img/p2tankD.gif");
          enemyImg[2] = getImage("img/p2tankL.gif");
          enemyImg[3] = getImage("img/p2tankR.gif");
          }

          //记录ai开始运行的时间
          private long aiTime;

          public EnemyTank(int x, int y, int dir) {
          super(x, y, dir);

          //敌人一旦开始创建就计时
          aiTime = System.currentTimeMillis();
          }

          //创建一个敌人的坦克
          public static Tank createEnemy() {
          int x = MyUtil.getRandomNumber(0, 2) == 0 ? RADIUS : Constant.FRAME_WIDTH - GameFrame.titleBarH;
          int y = GameFrame.titleBarH + RADIUS;
          int dir = DIR_DOWN;
          Tank enemy = new EnemyTank(x, y, dir);
          enemy.setEnemy(true);
          enemy.setState(STATE_MOVE);
          return enemy;
          }

          public void drawTankImg(Graphics g) {
          ai();
          g.drawImage(enemyImg[getDir()], getX() - RADIUS, getY() - RADIUS, null);
          }

          /**
          * 敌人的AI
          */
          private void ai() {

          //间隔五秒切换一个状态
          if (System.currentTimeMillis() - aiTime > Constant.ENEMY_AI_INTERVAL) {

          //五秒随机一个方向
          setDir(MyUtil.getRandomNumber(DIR_UP, DIR_RIGHT + 1));

          //五秒随机一个状态
          setState(MyUtil.getRandomNumber(0, 2) == 0 ? STATE_STAND : STATE_MOVE);

          //重新计时
          aiTime = System.currentTimeMillis();
          }

          //设置开火逻辑
          if (Math.random() < Constant.ENEMY_AI_PERCENT) {
          fire();
          }
          }
          }

          game包

          game包下的类是关于绘制可视化图像,使用Graphics类绘制游戏窗口。

          控制子弹效果 Bullet.class

            /***
            * 控制子弹效果
            */
            public class Bullet {

            //子弹的默认速度是坦克的两倍
            private static final int DEFAULT_SPEED = Tank.DEFAULT_SPEED << 1;

            //子弹的半径
            private static final int RADIUS = 4;

            private int x, y;
            private int speed = DEFAULT_SPEED;
            private int dir;
            private int atk;
            private Color color;
            private boolean visible = true;//子弹是否可见,默认可见

            public Bullet(int x, int y, int dir, int atk, Color color) {
            this.x = x;
            this.y = y;
            this.dir = dir;
            this.atk = atk;
            this.color = color;
            }

            /**
            * 默认无参的构造方法,给对象池使用
            */
            public Bullet() {

            }

            /**
            * 绘制炮弹的方法
            *
            * @param g
            */
            public void draw(Graphics g) {
            if (!visible) {
            return;
            }
            logic();
            g.setColor(color);
            g.fillOval(x - RADIUS, y - RADIUS, RADIUS << 1, RADIUS << 1);
            }

            /**
            * 炮弹的逻辑处理方法
            */
            private void logic() {
            move();
            }

            /**
            * 炮弹的运动方法
            *
            * @return
            */
            private void move() {
            switch (dir) {
            case Tank.DIR_UP:
            y -= speed;
            if (y < 0) {
            visible = false;
            }
            break;
            case Tank.DIR_DOWN:
            y += speed;
            if (y > Constant.FRAME_HEIGHT) {
            visible = false;
            }
            break;
            case Tank.DIR_LEFT:
            x -= speed;
            if (x < 0) {
            visible = false;
            }
            break;
            case Tank.DIR_RIGHT:
            x += speed;
            if (x > Constant.FRAME_WIDTH) {
            visible = false;
            }
            break;
            }
            }
            }

            控制爆炸效果Explode.class

              /**
              * 用于控制爆炸效果的类
              */
              public class Explode {
              //爆炸帧数的个数
              private static final int EXPLODE_FRAME_COUNT = 4;

              //爆炸图片
              private static Image[] boom_img;
              private static int explodeWidth;//爆炸图片的宽
              private static int explodeHeight;//爆炸图片的宽

              static {
              boom_img = new Image[EXPLODE_FRAME_COUNT];
              boom_img[0] = getImage("img/blast1.gif");
              boom_img[1] = getImage("img/blast2.gif");
              boom_img[2] = getImage("img/blast3.gif");
              boom_img[3] = getImage("img/blast4.gif");
              }

              //爆炸属性
              private int x, y;//坐标
              private int index;//当前图片帧数下标【0-3】
              private boolean visible = true;//是否可见

              public Explode(int x, int y) {
              this.x = x;
              this.y = y;
              index = 0;
              }

              public Explode() {
              index = 0;
              }

              //绘制爆炸效果
              public void draw(Graphics g) {

              if (explodeHeight <= 0) {
              explodeWidth = boom_img[0].getWidth(null);
              explodeHeight = boom_img[0].getHeight(null) >> 1;
              }
              if (!visible) {
              return;
              }
              g.drawImage(boom_img[index], x - explodeWidth, y - explodeHeight, null);
              index++;

              //播放到最后一帧,设置为不可见
              if (index >= EXPLODE_FRAME_COUNT) {
              visible = false;
              }
              }
              }

              游戏主窗口GameFrame.class

                /**
                * 游戏主窗口
                */
                public class GameFrame extends Frame implements Runnable {

                /**
                * 双缓冲技术解决屏幕闪烁问题
                * 1.定义一个与屏幕大小一致的图片
                * 2.获取图片的画笔
                * 3.使用图片画笔将元素绘制到图片中
                * 4.使用系统画笔将图片绘制到窗口中
                */
                private BufferedImage bufImg = new BufferedImage(FRAME_WIDTH, FRAME_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);

                //游戏状态
                public static int gameState;

                //菜单指向
                private static int menuIndex;

                //定义坦克对象
                private Tank myTank;

                //定义敌人坦克
                private List<Tank> enemies = new ArrayList<>();

                //标题栏的高度
                public static int titleBarH;

                //对窗口进行初始化
                public GameFrame() {
                initFrame();
                initEventListener();

                //启动刷新窗口的线程
                new Thread(this).start();
                }

                //对游戏进行初始化
                public void initGame() {
                gameState = STATE_MENU;
                }

                //对窗口属性进行初始化
                private void initFrame() {

                setTitle(GAME_TITLE);
                //设置窗口可见
                setVisible(true);

                setSize(FRAME_WIDTH, FRAME_HEIGHT);

                setLocation(FRAME_X, FRAME_Y);

                setResizable(false);

                titleBarH = getInsets().top;

                }


                /**
                * 该方法负责绘制所有在屏幕中显示的内容,继承Frame类
                * 该方法不能主动调用,只能通过repaint方法回调该方法
                *
                * @param graphics
                */
                @Override
                public void update(Graphics graphics) {
                //实例化图片画笔g
                Graphics g = bufImg.getGraphics();
                //使用画笔g绘制元素
                g.setFont(GAME_FONT);
                switch (gameState) {
                case STATE_MENU:
                drawMenu(g);
                break;
                case STATE_HELP:
                drawHelp(g);
                break;
                case STATE_ABOUT:
                drawAbout(g);
                break;
                case STATE_RUN:
                drawRun(g);
                break;
                case STATE_OVER:
                drawOver(g);
                break;
                }
                //使用系统画笔将bufImg绘制到frame中
                graphics.drawImage(bufImg, 0, 0, null);
                }

                private void drawOver(Graphics g) {
                }

                private void drawAbout(Graphics g) {
                }

                /**
                * 绘制游戏状态的内容
                *
                * @param g
                */
                private void drawRun(Graphics g) {
                //绘制背景
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);

                //绘制敌方坦克
                drawEnemy(g);

                //绘制我方坦克
                myTank.draw(g);

                //绘制爆炸效果
                drawExplodes(g);

                //子弹与坦克的碰撞检测
                bulletCollideTank();
                }

                /**
                * 绘制敌人
                *
                * @param g
                */
                private void drawEnemy(Graphics g) {
                for (int i = 0; i < enemies.size(); i++) {
                Tank enemy = enemies.get(i);
                enemy.draw(g);
                }
                }

                private void drawHelp(Graphics g) {
                }

                /**
                * 绘制菜单的方法
                *
                * @param g
                */
                private void drawMenu(Graphics g) {

                //绘制背景
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);

                //菜单栏行间距和选项宽度
                final int DIS = 50;
                final int STR_WIDTH = 76;

                //菜单栏坐标
                int x = FRAME_WIDTH - STR_WIDTH >> 1;
                int y = FRAME_HEIGHT 3;

                for (int i = 0; i < MENUS.length; i++) {
                if (i == menuIndex) {
                g.setColor(Color.RED);
                } else {
                g.setColor(Color.WHITE);
                }
                g.drawString(MENUS[i], x, y + DIS * i);
                }
                }

                //初始化窗口事件监听
                private void initEventListener() {

                //注册窗口监听事件
                addWindowListener(new WindowAdapter() {

                //点击关闭按钮时该方法会被自动调用
                @Override
                public void windowClosing(WindowEvent e) {
                System.exit(0);//结束虚拟机
                }
                });

                //注册窗口监听事件
                addKeyListener(new KeyAdapter() {

                //监听按键被按下的事件
                @Override
                public void keyPressed(KeyEvent e) {

                //捕获按下的键值
                int keyCode = e.getKeyCode();

                //不同的游戏状态给出不同的处理
                switch (gameState) {
                case STATE_MENU:
                keyPressedEventMenu(keyCode);
                break;
                case STATE_HELP:
                keyPressedEventHelp(keyCode);
                break;
                case STATE_ABOUT:
                keyPressedEventAbout(keyCode);
                break;
                case STATE_RUN:
                keyPressedEventRun(keyCode);
                break;
                case STATE_OVER:
                keyPressedEventOver(keyCode);
                break;
                }
                }


                //监听按键被松开的事件
                @Override
                public void keyReleased(KeyEvent e) {
                //捕获按下的键值
                int keyCode = e.getKeyCode();
                if (gameState == STATE_RUN) {
                keyReleasedEventRun(keyCode);
                }
                }
                });
                }

                //按键松开时,游戏处理的方法
                private void keyReleasedEventRun(int keyCode) {
                switch (keyCode) {
                case KeyEvent.VK_UP:
                case KeyEvent.VK_W:
                case KeyEvent.VK_DOWN:
                case KeyEvent.VK_S:
                case KeyEvent.VK_LEFT:
                case KeyEvent.VK_A:
                case KeyEvent.VK_RIGHT:
                case KeyEvent.VK_D:
                myTank.setState(Tank.STATE_STAND);
                break;
                }
                }

                private void keyPressedEventOver(int keyCode) {

                }

                private void keyPressedEventHelp(int keyCode) {

                }

                /**
                * 游戏进行中的按键处理
                *
                * @param keyCode
                */
                private void keyPressedEventRun(int keyCode) {
                switch (keyCode) {
                case KeyEvent.VK_UP:
                case KeyEvent.VK_W:
                myTank.setDir(Tank.DIR_UP);
                myTank.setState(Tank.STATE_MOVE);
                break;
                case KeyEvent.VK_DOWN:
                case KeyEvent.VK_S:
                myTank.setDir(Tank.DIR_DOWN);
                myTank.setState(Tank.STATE_MOVE);
                break;
                case KeyEvent.VK_LEFT:
                case KeyEvent.VK_A:
                myTank.setDir(Tank.DIR_LEFT);
                myTank.setState(Tank.STATE_MOVE);
                break;
                case KeyEvent.VK_RIGHT:
                case KeyEvent.VK_D:
                myTank.setDir(Tank.DIR_RIGHT);
                myTank.setState(Tank.STATE_MOVE);
                break;
                case KeyEvent.VK_SPACE:
                myTank.fire();
                break;
                }
                }

                private void keyPressedEventAbout(int keyCode) {

                }

                //菜单状态下的按键处理
                private void keyPressedEventMenu(int keyCode) {
                switch (keyCode) {
                case KeyEvent.VK_UP:
                case KeyEvent.VK_W:
                menuIndex--;
                if (menuIndex < 0) {
                menuIndex = MENUS.length - 1;
                }
                break;
                case KeyEvent.VK_DOWN:
                case KeyEvent.VK_S:
                menuIndex++;
                if (menuIndex > MENUS.length - 1) {
                menuIndex = 0;
                }
                break;
                case KeyEvent.VK_ENTER:
                //TODO
                newGame();
                break;
                }
                }

                private void newGame() {

                gameState = STATE_RUN;

                //创建坦克对象
                myTank = new MyTank(400, 200, Tank.DIR_DOWN);

                //生产敌方坦克的线程
                new Thread() {
                @Override
                public void run() {
                while (true) {
                if (enemies.size() < ENEMY_MAX_COUNT) {
                Tank enemy = EnemyTank.createEnemy();
                enemies.add(enemy);
                }
                try {
                Thread.sleep(ENEMY_BORN_INTERVAL);
                } catch (InterruptedException e) {
                e.printStackTrace();
                }
                }
                }
                }.start();
                }

                @Override
                public void run() {
                while (true) {
                repaint();
                try {
                Thread.sleep(REPAINT_INTERVAL);
                } catch (InterruptedException e) {
                e.printStackTrace();
                }
                }
                }

                /**
                * 碰撞检测
                */
                private void bulletCollideTank() {
                //我方子弹与所有敌人的碰撞检测
                for (Tank enemy : enemies) {
                enemy.collideBullet(myTank.getBullets());
                }
                //敌坦克与我方子弹碰撞
                for (Tank enemy : enemies) {
                myTank.collideBullet(enemy.getBullets());
                }
                }

                /**
                * 绘制坦克效果
                *
                * @param g
                */
                private void drawExplodes(Graphics g) {
                //绘制敌方坦克
                for (Tank enemy : enemies) {
                enemy.drawExplodes(g);
                }
                //绘制我方坦克
                myTank.drawExplodes(g);
                }
                }

                utils包

                该包下有工具类、爆炸对象池、子弹对象池、游戏常量对象

                工具类MyUtil.class

                  /*
                  * 工具类
                  * */
                  public class MyUtil {
                  private MyUtil() {
                  }//构造方法私有化,将该类进行封装

                  /**
                  * 得到指定区间的随机数
                  *
                  * @param min
                  * @param max
                  * @return
                  */
                  public static final int getRandomNumber(int min, int max) {
                  return (int) (Math.random() * (max - min) + min);
                  }

                  /**
                  * 获取随机颜色
                  *
                  * @return
                  */
                  public static final Color getRandomColor() {
                  int red = getRandomNumber(0, 256);
                  int green = getRandomNumber(0, 256);
                  int blue = getRandomNumber(0, 256);
                  return new Color(red, green, blue);
                  }

                  /**
                  * 获取图片对象
                  *
                  * @param image_path
                  * @return
                  */
                  public static Image getImage(String image_path) {
                  ImageIcon imageIcon = new ImageIcon(MyUtil.class.getClassLoader().getResource(image_path));
                  return imageIcon.getImage();
                  }

                  /**
                  * 求坦克和子弹是否碰撞
                  *
                  * @param rectX 坦克的坐标
                  * @param rectY
                  * @param radius 坦克的边长
                  * @param pointX 子弹的坐标
                  * @param pointY
                  * @return
                  */
                  public static final boolean isCollide(int rectX, int rectY, int radius, int pointX, int pointY) {

                  //坦克中心点和子弹的xy轴距离
                  int disX = Math.abs(rectX - pointX);
                  int disY = Math.abs(rectY - pointY);
                  if (disX < radius && disY < radius) {
                  return true;
                  }
                  return false;
                  }

                  }

                  爆炸效果对象池

                    /**
                    *爆炸效果对象池
                    */
                    public class ExplodePool {
                    //默认的爆炸效果数量
                    public static final int DEFAULT_POOL_SIZE = 200;

                    //最大爆炸效果容量
                    public static final int POOL_MAX_SIZE = 300;

                    //用于保存所有爆炸的对象池
                    private static List<Explode> pool = new ArrayList<>();

                    //在类加载时将爆炸效果对象添加到容器中
                    static {
                    for (int i = 0; i < DEFAULT_POOL_SIZE; i++) {
                    pool.add(new Explode());
                    }
                    }

                    /**
                    * 从爆炸效果对象池中取出一颗爆炸效果
                    *
                    * @return
                    */
                    public static Explode get() {
                    Explode explode = null;

                    //当对对象池中无爆炸效果时,new一个新的爆炸效果对象
                    if (pool.size() == 0) {
                    explode = new Explode();
                    } else {
                    explode = pool.remove(0);
                    }
                    return explode;
                    }

                    /**
                    * 当爆炸效果被销毁时,归还爆炸效果
                    *
                    * @param
                    */
                    public static void theReturn(Explode explode) {
                    if (pool.size() == POOL_MAX_SIZE) {
                    return;
                    }
                    pool.add(explode);
                    }
                    }

                    子弹对象池

                      /**
                      * 子弹对象池
                      */
                      public class BulletPool {
                      //默认的子弹数量
                      public static final int DEFAULT_POOL_SIZE = 200;

                      //最大子弹容量
                      public static final int POOL_MAX_SIZE = 300;

                      //用于保存所有子弹的对象池
                      private static List<Bullet> pool = new ArrayList<>();

                      //在类加载时将子弹对象添加到容器中
                      static {
                      for (int i = 0; i < DEFAULT_POOL_SIZE; i++) {
                      pool.add(new Bullet());
                      }
                      }

                      /**
                      * 从子弹对象池中取出一颗子弹
                      *
                      * @return
                      */
                      public static Bullet get() {
                      Bullet bullet = null;

                      //当对对象池中无子弹时,new一个新的子弹对象
                      if (pool.size() == 0) {
                      bullet = new Bullet();
                      } else {
                      bullet = pool.remove(0);
                      }
                      return bullet;
                      }

                      /**
                      * 当子弹被销毁时,归还子弹
                      *
                      * @param bullet
                      */
                      public static void theReturn(Bullet bullet) {
                      if (pool.size() == POOL_MAX_SIZE) {
                      return;
                      }
                      pool.add(bullet);
                      }
                      }

                      游戏常量类

                        /**
                        * 游戏常量类
                        */
                        public class Constant {

                        /****************游戏窗口相关属性*********************/
                        public static final String GAME_TITLE = "坦克大战";

                        public static final int FRAME_WIDTH = 1000;
                        public static final int FRAME_HEIGHT = 900;

                        //获取系统屏幕的宽高
                        public static final int SCREEN_W = Toolkit.getDefaultToolkit().getScreenSize().width;
                        public static final int SCREEN_H = Toolkit.getDefaultToolkit().getScreenSize().height;

                        //游戏窗口顶点坐标
                        public static final int FRAME_X = SCREEN_W - FRAME_WIDTH >> 1;
                        public static final int FRAME_Y = SCREEN_H - FRAME_HEIGHT >> 1;

                        /****************游戏菜单相关属性********************************/

                        public static final int STATE_MENU = 0;
                        public static final int STATE_HELP = 1;
                        public static final int STATE_ABOUT = 2;
                        public static final int STATE_RUN = 3;
                        public static final int STATE_OVER = 4;

                        public static final String[] MENUS = {
                        "开始游戏",
                        "继续游戏",
                        "游戏帮助",
                        "游戏相关",
                        "退出游戏"
                        };

                        public static final Font GAME_FONT = new Font("宋体", Font.BOLD, 24);

                        //窗口刷新间隔
                        public static final int REPAINT_INTERVAL = 30;

                        //最大敌人数量
                        public static final int ENEMY_MAX_COUNT = 10;

                        //敌方坦克生产间隔
                        public static final int ENEMY_BORN_INTERVAL = 5000;

                        //敌方坦克状态切换的间隔
                        public static final int ENEMY_AI_INTERVAL = 1000;

                        //敌方坦克每帧发射子弹的概率
                        public static final double ENEMY_AI_PERCENT = 0.10;
                        }
                        Size().width;
                        public static final int SCREEN_H = Toolkit.getDefaultToolkit().getScreenSize().height;

                        //游戏窗口顶点坐标
                        public static final int FRAME_X = SCREEN_W - FRAME_WIDTH >> 1;
                        public static final int FRAME_Y = SCREEN_H - FRAME_HEIGHT >> 1;

                        /****************游戏菜单相关属性********************************/

                        public static final int STATE_MENU = 0;
                        public static final int STATE_HELP = 1;
                        public static final int STATE_ABOUT = 2;
                        public static final int STATE_RUN = 3;
                        public static final int STATE_OVER = 4;

                        public static final String[] MENUS = {
                        "开始游戏",
                        "继续游戏",
                        "游戏帮助",
                        "游戏相关",
                        "退出游戏"
                        };

                        public static final Font GAME_FONT = new Font("宋体", Font.BOLD, 24);

                        //窗口刷新间隔
                        public static final int REPAINT_INTERVAL = 30;

                        //最大敌人数量
                        public static final int ENEMY_MAX_COUNT = 10;

                        //敌方坦克生产间隔
                        public static final int ENEMY_BORN_INTERVAL = 5000;

                        //敌方坦克状态切换的间隔
                        public static final int ENEMY_AI_INTERVAL = 1000;

                        //敌方坦克每帧发射子弹的概率
                        public static final double ENEMY_AI_PERCENT = 0.10;
                        }


                        各位同学要是有啥不懂的可以留言哈


                        转发,在看,关注公众号,一起学习、成长

                        文章转载自java小哥,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论