当前位置:   article > 正文

2022最新java坦克大战+免费源码+坦克大战图片_java塔防游戏完整源码

java塔防游戏完整源码

游戏介绍

本次项目模仿了小时候玩的坦克大战小游戏,其中的功能基本实现,里面最重要的思想就是对象池,类似于前面所学的线程池,让对象重复的使用,减少资源的浪费。做的时候逻辑性很强,很不容易,不过总算是有所实现。
用到的知识点:
主要是:Frame窗体,Graphics绘图,
其次是:集合 多线程

游戏的主窗体

/**
 * 主界面的绘制
 */
public class GameFrame extends Frame  implements Runnable{


    // 1.定义一张和屏幕大小一致的图片(双缓存)
    private BufferedImage bufImg=new BufferedImage(FRAME_WIDTH,FRAME_HEIGTH,BufferedImage.TYPE_4BYTE_ABGR);
    // 游戏的状态
    public static int gameStart;
    // 菜单指向
    private int menuIndex;
    // 创建坦克对象
    private Tank myTank;
    // 敌人坦克对象
    private List<Tank> enemies=new ArrayList<>();
    // 标题栏的高度
    public static int menuTitle;
    // 绘制游戏结束的方法,(用到的时候在加载)
    private static Image overImage =null;
    //定义地图相关的内容
    private GameMap gameMap;



    /**
     * 对窗口进行初始化
     */
    public GameFrame(){
        initFrame();
        iniEventListener();
        new Thread(this).start();

    }

    /**
     * 对窗口初始化
     */
    private void initFrame(){
        gameStart=START_MENU;

        setTitle(NAME_TANK);
        setSize(FRAME_WIDTH,FRAME_HEIGTH);
        setLocationRelativeTo(null);
        // 设置不可修改
        setResizable(false);
        menuTitle=getInsets().top;
        setVisible(true);

    }

    /**
     * 该方法负责了所有的绘制内容,该方法不能主动调用
     *  repaint去回调该方法
     */
    public void update(Graphics g2) {
        // 定义图片画笔
        Graphics g=bufImg.getGraphics();
        switch (gameStart){
            case START_MENU:
                drawMenus(g);
                break;
            case START_HELP:
                drawHelp(g);
                break;
            case START_ABOUT:
                drawAbout(g);
                break;
            case START_RUN:
                drawRun(g);
                break;
            case START_OVER:
                drawOver(g);
                break;
        }
        // 使用系统画笔将内容绘制在窗口上
        g2.drawImage(bufImg,0,0,FRAME_WIDTH, FRAME_HEIGTH,this);
    }
    
    // 主菜单的方法
    private void drawMenus(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(FONT_SIZE);
        // 绘制黑色背景颜色
        g2.setColor(Color.GRAY);
         g2.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGTH);
        // 把文字绘制成白色
        // 该方法默认设置字体
        g2.setColor(Color.black);
        final int STR_WIDTH = 50;
        final int x = FRAME_WIDTH / 2-50;
        final int y = FRAME_HEIGTH / 3;
        for (int i = 0; i < MENUS.length; i++) {
            // 设置菜单的触发颜色
            if (i == menuIndex) {
                g2.setColor(Color.pink);

            } else {
                g2.setColor(Color.white);
            }
            g2.drawString(MENUS[i], x, y + STR_WIDTH * i);

        }
    }

    /**
     * 负责存放所以监听事件
     */
    private void iniEventListener(){
        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 (gameStart){
                    case START_MENU:
                        keyEventMenu(keyCode);
                        break;
                    case START_HELP:
                        keyEventHELP(keyCode);
                        break;
                    case START_ABOUT:
                        keyEventABOUT(keyCode);
                        break;
                    case START_RUN:
                        keyEventRUN(keyCode);
                        break;
                    case START_OVER:
                        keyEventOVER(keyCode);
                        break;

                }

            }

            @Override
            public void keyReleased(KeyEvent e) {
                // 获得事件相关联的整数
                int  keyCode=e.getKeyCode();
                //不同的游戏状态,给出不同的处理方法
                    if(gameStart==START_RUN) {
                        keyReleaseEventMenu(keyCode);

                    }
            }
        });

    }
    // 按键松开的时候游戏处理的方法
    private void keyReleaseEventMenu(int keyCode) {
        switch (keyCode){
            case KeyEvent.VK_UP:
            case KeyEvent.VK_W:

            case KeyEvent.VK_DOWN:
            case KeyEvent.VK_S:

            case KeyEvent.VK_A:
            case KeyEvent.VK_LEFT:

            case KeyEvent.VK_D:
            case KeyEvent.VK_RIGHT:
                myTank.setState(Tank.STATE_STAND);
        }
    }

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

                newGame();
                break;
        }

    }
    // 游戏中行走时的监听
    private void keyEventRUN(int keyCode) {

        switch (keyCode){
            case KeyEvent.VK_UP:
            case KeyEvent.VK_W:
                myTank.setDir(Tank.UP);
                myTank.setState(Tank.STATE_MOVE);
                break;
            case KeyEvent.VK_DOWN:
            case KeyEvent.VK_S:
                myTank.setDir(Tank.DOWN);
                myTank.setState(Tank.STATE_MOVE);
                break;
            case KeyEvent.VK_A:
            case KeyEvent.VK_LEFT:
                myTank.setDir(Tank.LEFT);
                myTank.setState(Tank.STATE_MOVE);
                break;

            case KeyEvent.VK_D:
            case KeyEvent.VK_RIGHT:
                myTank.setDir(Tank.RIGHT);
                myTank.setState(Tank.STATE_MOVE);
                break;
            case KeyEvent.VK_SPACE:
                myTank.fire();
                break;
        }
    }
    private void keyEventHELP(int keyCode) {
    }
    private void keyEventABOUT(int keyCode) {
    }

    // 游戏结束后的执行
    private void keyEventOVER(int keyCode) {
        // 结束游戏
        if(keyCode==KeyEvent.VK_ESCAPE){
            System.exit(0);
        }else if(keyCode==KeyEvent.VK_ENTER){
            setGameStart(START_MENU);
            resetGame();
        }

    }


    /**
     * 游戏运行状态的内容绘制
     * @param g
     */
    private void drawRun(Graphics g) {
        g.setColor(Color.gray);
        g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGTH);
        // 绘制地图
        gameMap.drawBK(g);

        drawEnemies(g);

        myTank.draw(g);
        // 绘制地图遮挡
        gameMap.drawCover(g);
        // 子弹和坦克碰撞
        drawExplodes(g);

        bulletCollideTank();

        bulletAndTankCollideMapTile();


    }

    /**
     * 绘制敌人坦克
     * @param g
     */
    private void drawEnemies(Graphics g){

        for (int i = 0; i < enemies.size(); i++) {
            Tank enemy=enemies.get(i);
            if(enemy.isDie()){
                enemies.remove(i);
                i--;
                continue;
            }
            enemy.draw(g);
        }

    }

    private void drawAbout(Graphics g) {
    }


    /**
     * 游戏结束按键处理
     * @param g
     */
    private void drawOver(Graphics g) {
        // 保证只加载一次
        if(overImage ==null){
            overImage =MyUtil.creatImage(gameOver);
        }
        // 得到图片的宽和高
        int imgW=overImage.getWidth(null);
        int imgH=overImage.getHeight(null);
        g.drawImage(overImage,FRAME_WIDTH-imgW>>1,FRAME_HEIGTH-imgH>>1,null);
        // 添加按键提示信息
        g.setColor(Color.red);
        g.drawString(OVER_STA,10,FRAME_HEIGTH-40);
        g.drawString(OVER_STA1,FRAME_WIDTH-200,FRAME_HEIGTH-30);

    }



    private void drawHelp(Graphics g) {
    }

    @Override
    public void run() {
        while (true) {
            repaint();
            try {
                Thread.sleep(REPAIN_TIME);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 重置游戏状态
     */
    private void resetGame(){
        menuIndex=0;
        // 先让自己坦克的子弹还回对象池
        myTank.bulletsReturn();
        // 销毁自己坦克
        myTank=null;
        for (Tank enemy : enemies) {
            enemy.bulletsReturn();
        }
        // 清空敌人
        enemies.clear();
        gameMap=null;

    }

    /**
     * 开始游戏的方法
     */
     private void newGame(){
         gameStart=START_RUN;
         // 创建坦克对象
         myTank=new MyTank(FRAME_WIDTH/3,FRAME_HEIGTH-Tank.BAN_JIN ,Tank.UP);
         gameMap=new GameMap();
         // 使用一个单独的线程用于控制敌人的坦克
         new Thread(){
             @Override
             public void run() {
                 while (true){
                     if(enemies.size()<MAX_ENEMY_COUNT){
                         Tank enemy= EnemyTank.creatEnemy();
                         enemies.add(enemy);
                     }
                     // 产生敌人坦克间隔
                     try {
                         Thread.sleep(3000);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                     // 如果游戏不再运行中,我们就停止创建敌人坦克
                     if(gameStart!=START_RUN){
                         break;
                     }
                 }
             }
         }.start();
     }
     // 敌所有人坦克的子弹和我坦克的碰撞
    // 我的坦克子弹敌人的坦克碰撞
    private void bulletCollideTank(){
         // 我的坦克子弹碰撞所有敌人
        for (Tank enemy : enemies) {
            enemy.collideBullets((myTank.getBullets()));
        }

        // 所有敌人坦克子弹碰撞我坦克
        for (Tank enemy : enemies) {
            myTank.collideBullets((enemy.getBullets()));
        }

    }
    // 所有的子弹和地图块的碰撞
    private void bulletAndTankCollideMapTile(){
         // 自己子弹和砖块碰撞

        myTank.bulletCollideMapTile(gameMap.getTiles());
        // 敌人子弹和砖块碰撞
        for (Tank enemy : enemies) {
            enemy.bulletCollideMapTile(gameMap.getTiles());
        }
        // 坦克和地图的碰撞
       if( myTank.isCollideTile(gameMap.getTiles())){
           myTank.backLast();
       }
       // 敌人的坦克和地图的碰撞
        for (Tank enemy : enemies) {
            if(enemy.isCollideTile(gameMap.getTiles())){
                enemy.backLast();
            }
        }
        // 清理被销毁的地图块
        gameMap.clearDestoryTile();
    }
    // 所有坦克的爆炸效果
    private void drawExplodes(Graphics g){
        for (Tank enemy : enemies) {
            enemy.drawExplodes(g);
        }
        myTank.drawExplodes(g);
    }

    public static int getGameStart() {
        return gameStart;
    }

    public static void setGameStart(int gameStart) {
        GameFrame.gameStart = gameStart;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428

坦克共同拥有的属性

package com.hg.tank;

import com.hg.MainJFrame.GameFrame;
import com.hg.TankBattle.Bullet;
import com.hg.TankBattle.Explode;
import com.hg.Util.*;
import com.hg.map.MapTile;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static com.hg.Util.ConsDemo.*;

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


    public static final int UP=0;
    public static final int DOWN=1;
    public static final int LEFT=2;
    public static final int RIGHT=3;
    // 坦克状态
    public static final int STATE_STAND=0;
    public static final int STATE_MOVE=1;
    // 死亡
    private static final int DIE=2;
    // 坦克初始生命
    public static final int DEFAULT_HP=1000;
    // 坐标
    private int x;
    private int y;
    // 半径
    public static final int BAN_JIN=23;
    // 坦克的默认状态
    private int state;
    // 默认速度,每一帧30ms 4速度
    public static final int DEFAULT_SPEED=6;
    // 血量
    private int hp=DEFAULT_HP;
    // 攻击力
    private int atk;
    public int ATK_MAX=500;
    public int ATK_MIN=90;
    // 颜色
    private Color color;
    // 方向
    private int dir;
    // 速度
    private int speed=DEFAULT_SPEED;
    // 是否是敌人
    private boolean isEnemy =false;
    // TODO炮弹
    private List<Bullet> bullets=new ArrayList();
    // 使用容器来保持当前坦克上的所有爆炸效果
    private List<Explode> explodes=new ArrayList<>();
    // 名字
    private String name;
    // 血条对象
    private BloodBar bar=new BloodBar();



    // 坦克的初始状态
    public Tank(int x,int y,int dir){
        this.x=x;
        this.y=y;
        this.dir=dir;
        initTank();
    }

    public Tank() {
        // 初始化坦克
        initTank();
    }
    public void initTank(){
        color= MyUtil.getRamdomColor();
        name=MyUtil.getRandomName();
        atk=MyUtil.getRamdomNumber(ATK_MIN,ATK_MAX);
    }


    /**
     * 坦克的逻辑处理
     */
    public void tankLogic(){
        switch (state){
            case STATE_MOVE:
                move();
                break;
            case STATE_STAND:
                break;
        }
    }

    /**
     * 坦克的移动
     */
    private int oldX=-1,oidY=-1;

    public void move(){
        oldX=x;
        oidY=y;
        switch (dir){
            case UP:
                y-=speed;
                if(y<(3*BAN_JIN))
                    y=3*BAN_JIN;
                break;
            case DOWN:
                y+=speed;
                if(y>(ConsDemo.FRAME_HEIGTH-BAN_JIN))
                    y=(ConsDemo.FRAME_HEIGTH-BAN_JIN);
                break;
            case LEFT:
                x-=speed;
                if(x<BAN_JIN)
                    x=BAN_JIN;
                break;
            case RIGHT:
                x+=speed;
                if(x>(ConsDemo.FRAME_WIDTH-BAN_JIN))
                    x =(ConsDemo.FRAME_WIDTH-BAN_JIN);
                break;
        }
    }

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

    public void draw(Graphics g){

        tankLogic();

        drawBullet(g);

        drawTankImg(g);

        drawName(g);

        bar.drawBlood(g);


    }

    /**
     * 绘制坦克的名字
     * @param g
     */
    private void drawName(Graphics g){
        g.setColor(color);
        g.drawString(name,x-(2*BAN_JIN),y-40);
        g.setFont(GAME_FONT);
    }

    /**
     * 对坦克进行绘画->使用系统的方式绘制
     * @param g2
     */
    public void drawTank(Graphics g2){
        Graphics2D g=(Graphics2D)g2;
        g.setColor(color);
        int endX=x;
        int endY=y;
        // 设置画笔的宽度
        Stroke stroke=new BasicStroke(4.0f);
        g.setStroke(stroke);
        // 绘制坦克的圆,是以矩形的一个端点开始
        g.fillOval(x-BAN_JIN,y-BAN_JIN,BAN_JIN<<1,BAN_JIN<<1);
        // 判断坦克走向

        switch (dir){
            case UP:
                endY=y-2*BAN_JIN;
                break;
            case DOWN:
                endY=y+2*BAN_JIN;
                break;
            case LEFT:
                endX=x-2*BAN_JIN;
                break;
            case RIGHT:
                endX=x+2*BAN_JIN;
                break;

        }

        g.drawLine(x,y,endX,endY);

    }
    /**
     * 坦克开火的功能
     */
    // 上一次开火的时间
    private long millis;
    // 发射最小间隔
    public static final int FIRE_INTEN=350;
    public void fire(){
        if(System.currentTimeMillis()-millis>FIRE_INTEN){
            int bulletX=x;
            int bulletY=y;
            switch (dir){
                case UP:
                    bulletY-=2*BAN_JIN;
                    break;
                case DOWN:
                    bulletY+=2*BAN_JIN;
                    break;
                case LEFT:
                    bulletX-=2*BAN_JIN;
                    break;
                case RIGHT:
                    bulletX+=2*BAN_JIN;
                    break;
            }
            // 从池塘中拿取
            Bullet bullet= BulletsPool.get();
            bullet.setX(bulletX);
            bullet.setY(bulletY);
            bullet.setDir(dir);
            bullet.setAtk(atk);
            bullet.setColor(color);
            bullet.setVisible(true);
            //Bullet bullet = new Bullet(bulletX,bulletY,dir,atk,color);
            // 将子弹添加到坦克管理的容器中。
            bullets.add(bullet);
            // 发射子弹后,记录本次发射子弹的时间
            millis=System.currentTimeMillis();
        }


    }
    // 发射的所有子弹绘制出来
    public void drawBullet(Graphics g){
        for (Bullet bullet : bullets) {
            bullet.draw(g);
        }
        // 遍历所有的子弹,把不可见的子弹移除还原对象池
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet=bullets.get(i);
            if(!bullet.isVisible()){
                Bullet re=bullets.remove(i);
                i--;
                BulletsPool.back(re);
            }
        }
    }

    /**
     * 坦克销毁时处理坦克所有的子弹
     */
    public void bulletsReturn(){
        for (Bullet bullet : bullets) {
            // 把每个子弹还回去
            BulletsPool.back(bullet);
        }
        bullets.clear();
        }


    /**
     * 坦克和敌人子弹碰撞的方法。
     * @param bullets
     */
    public void collideBullets(List<Bullet> bullets){
        for (Bullet bullet : bullets) {
            int bulletX=bullet.getX();
            int bulletY=bullet.getY();
            // 子弹和坦克碰撞
            if(MyUtil.isCollide(x,y,BAN_JIN,bulletX,bulletY)){
                // 子弹消失,坦克减血
                bullet.setVisible(false);
                hurt(bullet);
                // 爆炸效果,就是坦克边沿的位置
                addExplode(x,y+BAN_JIN);
            }
        }
    }

    /**
     * 坦克受到伤害
     * @param bullet
     */
    private void hurt(Bullet bullet){
        // 坦克受到伤害
         int atk= bullet.getAtk();
        hp-=atk;
        if (hp < 0){
            hp=0;
            die();
        }
    }

    /**
     * 坦克死亡的内容
     */
    private void die(){
        if(isEnemy()){
            // 坦克死亡归回对象池
            EnemyTanksPool.back(this);
        }else{
            // 自己坦克死亡,游戏结束或者回到主菜单
            delaySecondsToOver();

        }
    }

    /**
     * 判断当前坦克是否死亡了
     * @return
     */
    public boolean isDie(){
        return hp<=0;
    }

    /**
     * 绘制当前坦克上的所有爆炸效果
     * @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);
            explodes.remove(i);
            ExplodePool.back(explode);
            i--;
        }
    }

    /**
     * 坦克回退的方法
     */
    public void backLast() {
        x=oldX;
        y=oidY;
    }

    class BloodBar{
        // 血条的宽和高
        public static final int BAY_LENGTH=50;
        public static final int BAY_HEIGHT=5;
        public void drawBlood(Graphics g){
            // 血条颜色填充
            g.setColor(Color.yellow);
            g.fillRect(x-(BAN_JIN+10),y-BAN_JIN-BAY_HEIGHT*2,BAY_LENGTH,BAY_HEIGHT);
            // 当前血条颜色
            g.setColor(Color.red);
            g.fillRect(x-(BAN_JIN+10),y-BAN_JIN-BAY_HEIGHT*2,hp*BAY_LENGTH/DEFAULT_HP,BAY_HEIGHT);
            // 血条边框
            g.setColor(Color.white);
            g.drawRect(x-(BAN_JIN+10) ,y-BAN_JIN-BAY_HEIGHT*2,BAY_LENGTH,BAY_HEIGHT);
        }
    }

    // 所有的子弹和地图块的碰撞
    public void bulletCollideMapTile(List<MapTile> tiles){
        // 自己子弹和砖块碰撞
        for (MapTile tile : tiles) {
            if(tile.isCollideBullet(bullets)){
                // 添加爆炸效果
                addExplode(tile.getX(),tile.getY());
                // 银块不被击毁
                if(tile.getType()==MapTile.TYPE_HARD)
                    continue;
                // 设置地图块销毁
                tile.setVisible(false);
                // 归还对象池
                MapTitlePool.back(tile);
                // 老巢被击毁,1s后切换到游戏结束界面
                if(tile.isHouse()){
                    delaySecondsToOver();
                }


            }

        }
    }

    /**
     * 延迟若干毫秒切换到游戏结束
     */
    public void delaySecondsToOver(){
        new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                GameFrame.setGameStart(START_OVER);
            }
        }.start();
    }
    private void addExplode(int x,int y){
        // 爆炸效果,就是坦克边沿的位置
        Explode explode=ExplodePool.get();
        explode.setX(x);
        explode.setY(y);
        explode.setVisible(true);
        explode.setIndex(0);
        explodes.add(explode);
    }
    // 一个地图和当前坦克碰撞的方法

    /**
     * 从tile`中提取八个点来判断坦克是否和地图碰撞,按照顺时针
     * @param
     * @return
     */
    public boolean isCollideTile(List<MapTile> tiles){
        for (MapTile tile : tiles) {
            if(!tile.isVisible() || tile.getType()==MapTile.TYPE_COVER)
                continue;
            // 1左上角的点
            int tileX=tile.getX();
            int tileY=tile.getY();
            boolean collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            // 碰上直接返回否则判断下一个点
            if(collide){
                return true;
            }
            // 点二,中上
            tileX+=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 3 右上角
            tileX+=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 4 右中脚
            tileY+=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 5 右下角
            tileY+=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 6 中下
            tileX-=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 7 左下
            tileX-=MapTile.radius;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
            // 8 左中
            tileY-=MapTile.radius;;
            collide = MyUtil.isCollide(x, y, BAN_JIN, tileX, tileY);
            if(collide){
                return true;
            }
        }

        return false;
    }
    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }


    public int getY() {
        return y;
    }


    public void setY(int y) {
        this.y = y;
    }


    public int getHp() {
        return hp;
    }


    public void setHp(int hp) {
        this.hp = hp;
    }


    public int getAtk() {
        return atk;
    }


    public void setAtk(int atk) {
        this.atk = atk;
    }


    public Color getColor() {
        return color;
    }


    public void setColor(Color color) {
        this.color = color;
    }


    public int getDir() {
        return dir;
    }


    public void setDir(int dir) {
        this.dir = dir;
    }
    public boolean isEnemy() {
        return isEnemy;
    }

    public void setEnemy(boolean enemy) {
        isEnemy = enemy;
    }

    public List<Bullet> getBullets() {
        return bullets;
    }

    public void setBullets(List<Bullet> bullets) {
        this.bullets = bullets;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573

自己坦克

package com.hg.tank;

import com.hg.Util.MyUtil;
import com.hg.tank.Tank;

import java.awt.*;

import static com.hg.Util.ConsDemo.*;
import static com.hg.Util.ConsDemo.enemyUrl4;

/**
 * 自己的坦克
 */
public class MyTank extends Tank {
    // 自己坦克图片数组
    private static Image[] tankImg;
    // 静态代码块中初始化
    static {
        tankImg = new Image[4];
        tankImg[0]= MyUtil.creatImage(url);
        tankImg[1]=MyUtil.creatImage(url1);
        tankImg[2]=MyUtil.creatImage(url2);
        tankImg[3]=MyUtil.creatImage(url3);

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

    }
    public MyTank(){

    }

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

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

敌人坦克

1.敌人坦克类

package com.hg.tank;

import com.hg.Util.EnemyTanksPool;
import com.hg.Util.MyUtil;
import java.awt.*;

import static com.hg.Util.ConsDemo.*;
import static com.hg.Util.ConsDemo.enemyUrl4;

/**
 * 敌人的坦克
 */
public class EnemyTank extends Tank {
    public static final int TYPE_1=0;
    public static final int TYPE_2=1;
    // 敌人图片数组
    private static Image[] enemyImg;
    private static Image[] enemyImg2;
    private int type=TYPE_1;
    // 记录坦克开始的时间
    private long aiTime;
    // 静态代码块中初始化
    static {
        enemyImg = new Image[4];
        enemyImg[0]=MyUtil.creatImage(enemyUrl1);
        enemyImg[1]=MyUtil.creatImage(enemyUrl2);
        enemyImg[2]=MyUtil.creatImage(enemyUrl3);
        enemyImg[3]=MyUtil.creatImage(enemyUrl4);

        enemyImg2 = new Image[4];
        enemyImg2[0]=MyUtil.creatImage(enemy2Url1);
        enemyImg2[1]=MyUtil.creatImage(enemy2Url2);
        enemyImg2[2]=MyUtil.creatImage(enemy2Url3);
        enemyImg2[3]=MyUtil.creatImage(enemy2Url4);
    }

    public EnemyTank() {
        aiTime=System.currentTimeMillis();
        type=MyUtil.getRamdomNumber(0,2);
    }

    /**
     *
     * @return 用于创建敌人的坦克
     */
    public static Tank creatEnemy(){
        int x= MyUtil.getRamdomNumber(0,2)==0?BAN_JIN: (FRAME_WIDTH- BAN_JIN);
        int y=2*BAN_JIN;
        int dir=DOWN;
        Tank enemy= EnemyTanksPool.get();
        enemy.setX(x);
        enemy.setY(y);
        enemy.setDir(dir);
        enemy.setEnemy(true);
        enemy.setState(STATE_MOVE);
        enemy.setHp(Tank.DEFAULT_HP);
        return enemy;
    }

    public EnemyTank(int x, int y, int dir) {
        super(x, y, dir);
        // 敌人创建就开始计时
        aiTime=System.currentTimeMillis();
        type=MyUtil.getRamdomNumber(0,2);


    }

    @Override
    public void drawTankImg(Graphics g) {
        AI();
        g.drawImage(type==TYPE_1?enemyImg[getDir()]:enemyImg2[getDir()],getX()-BAN_JIN,getY()-BAN_JIN,null);
    }
    private void AI(){
        if(System.currentTimeMillis()-aiTime> ENEMY_AI){
            // 间隔五秒随机切换状态
            setDir(MyUtil.getRamdomNumber(UP,4));
            setState(MyUtil.getRamdomNumber(0,2)==0?STATE_STAND:STATE_MOVE);
            aiTime=System.currentTimeMillis();
            // 开火概率
            if(Math.random()< ENEMY_FIRE)
                fire();
        }

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

2.敌人坦克对象池

package com.hg.Util;

import com.hg.tank.EnemyTank;
import com.hg.tank.Tank;
import java.util.ArrayList;
import java.util.List;

/**
 * 敌人坦克对象池
 */
public class EnemyTanksPool {

        // 总的坦克数量
        public static final int ALL_BULLET=15;
        // 用于保存所有子弹的容器
        private static List<Tank> pool =new ArrayList<>();
        // 在类加载的时候就创建出200个子弹添加到容器中
        static {
            for (int i = 0; i < ALL_BULLET; i++) {
                pool.add(new EnemyTank());
            }
        }

        /**
         *
         * @return 从池塘中拿出坦克
         */
        public static Tank get(){
            Tank tank;
            // 如果池塘被掏空
            if(pool.size()==0){
                tank=new EnemyTank();
            }else{
                tank= pool.remove(0);
            }
            return tank;

        }

        /**
         * 子弹别销毁的时候,归还到池塘中
         * @return
         */
        public static void  back(Tank tank){
            // 池塘中的子弹已经达到最大
            if(pool.size()==5){
                return;
            }
            pool.add(tank);
        }
    }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

子弹类

  1. 子弹属性
package com.hg.TankBattle;

import com.hg.Util.ConsDemo;
import com.hg.tank.Tank;
import java.awt.*;

/**
 * 子弹类
 */
public class Bullet {
    // 子弹默认速度为坦克两倍<<1
    public static final int DEFAULT_SPEED=14;
    // 炮弹的半径
    public static final int BAN_JIN =4;
    private int x;
    private int 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;
        g.setColor(color);
        g.fillOval(x-BAN_JIN,y-BAN_JIN,BAN_JIN<<1,BAN_JIN<<1);
        logicBullet();

    }

    /**
     * 子弹的逻辑
     */
    public void logicBullet(){
        move();
    }

    /**
     * 子弹的移动
     */
    public void move() {
        switch (dir) {
            case Tank.UP:
                y -= speed;
                if(y<=0)
                    visible=false;
                break;
            case Tank.DOWN:
                y += speed;
                if(y>ConsDemo.FRAME_HEIGTH)
                    visible=false;
                break;
            case Tank.LEFT:
                x -= speed;
                if(x<=0)
                    visible=false;
                break;
            case Tank.RIGHT:
                x += speed;
                if(x>ConsDemo.FRAME_WIDTH)
                    visible=false;
                break;
        }
    }



    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  1. 子弹的对象池
package com.hg.Util;

import com.hg.TankBattle.Bullet;
import java.util.ArrayList;
import java.util.List;

/**
 *  子弹的对象池
 */
public class BulletsPool {
    // 初始子弹数量
    public static final int ALL_BULLET=200;
    // 用于保存所有子弹的容器
    private static List<Bullet> pool =new ArrayList<>();
    // 在类加载的时候就创建出200个子弹添加到容器中
    static {
        for (int i = 0; i < ALL_BULLET; i++) {
            pool.add(new Bullet());
        }
    }

    /**
     *
     * @return 从池塘中拿出子弹
     */
    public static Bullet get(){
        Bullet bullet=null;
        // 如果池塘被掏空
        if(pool.size()==0){
            bullet=new Bullet();
        }else{
              bullet= pool.remove(0);
        }
        return bullet;

    }

    /**
     * 子弹别销毁的时候,归还到池塘中
     * @return
     */
    public static void  back(Bullet bullet){
        // 池塘中的子弹已经达到最大,那就不再归还
        if(pool.size()==300){
            return;
        }
        pool.add(bullet);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

爆炸效果

1.爆炸类

package com.hg.TankBattle;

import com.hg.Util.ConsDemo;
import com.hg.Util.MyUtil;
import java.awt.*;

/**
 * 控制爆炸效果
 */
public class Explode {
    public static final int EXPLODE_FRAME=8;
    private static Image[] img;
    static {
        img=new Image[EXPLODE_FRAME];
        for (int i = 0; i < img.length; i++) {
            img[i]= MyUtil.creatImage(ConsDemo.BOOM);
        }
    }
    // 爆炸效果的属性
    private int x,y;
    // 当前播放帧的下表
    private int index=0;
    // 设置是否可见
    private boolean visible=true;

    // 对爆炸效果图片的宽高
    private static int imgHeight;
    private static int imgWidth;

    public Explode(){

    }

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

    /**
     * 绘制爆炸效果
     * @param g
     */
    public void draw(Graphics g){
        if(imgHeight<=0){
            imgHeight =img[0].getHeight(null);
            imgWidth =img[0].getWidth(null)>>2;
        }
        if(!visible)return;
        g.drawImage(img[index],x,y,null);
        index++;
        // 播放完最后一帧设置为不可见
        if(index>=EXPLODE_FRAME){
            visible=false;
        }
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public int getImgHeight() {
        return imgHeight;
    }

    public void setImgHeight(int imgHeight) {
        this.imgHeight = imgHeight;
    }

    public int getImgWidth() {
        return imgWidth;
    }

    public void setImgWidth(int imgWidth) {
        this.imgWidth = imgWidth;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

2.爆炸效果对象池

package com.hg.Util;

import com.hg.TankBattle.Bullet;
import java.util.ArrayList;
import java.util.List;

/**
 *  爆炸效果的对象池
 */
public class BulletsPool {
    // 初始爆炸效果数量
    public static final int ALL_BULLET=50;
    // 用于保存所有子弹的容器
    private static List<Bullet> pool =new ArrayList<>();
    // 在类加载的时候就创建出200个子弹添加到容器中
    static {
        for (int i = 0; i < ALL_BULLET; i++) {
            pool.add(new Bullet());
        }
    }

    /**
     *
     * @return 从池塘中拿出爆炸效果
     */
    public static Bullet get(){
        Bullet bullet=null;
        // 如果池塘被掏空
        if(pool.size()==0){
            bullet=new Bullet();
        }else{
              bullet= pool.remove(0);
        }
        return bullet;

    }

    /**
     * 销毁的时候,归还到池塘中
     * @return
     */
    public static void  back(Bullet bullet){
        // 池塘中的子弹已经达到最大,那就不再归还
        if(pool.size()==ALL_BULLET){
            return;
        }
        pool.add(bullet);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

地图砖块类

package com.hg.map;

import com.hg.TankBattle.Bullet;
import com.hg.Util.BulletsPool;
import com.hg.Util.ConsDemo;
import com.hg.Util.MyUtil;
import java.util.List;
import java.awt.*;

/**
 * 地图砖块
 */
public class MapTile {
    public static final int TYPE_NORMAL=0;
    public static final int TYPE_HOUSE=1;
    public static final int TYPE_COVER=2;
    public static final int TYPE_HARD=3;
    public static int tileW=20;
    public static int radius=(tileW>>1);
    private int type=TYPE_NORMAL;
    private static Image[] titleImg;
    static {
        titleImg=new Image[4];
        titleImg[TYPE_NORMAL]= MyUtil.creatImage(ConsDemo.BRICK);
        titleImg[TYPE_COVER]=MyUtil.creatImage(ConsDemo.GRASS);
        titleImg[TYPE_HOUSE]=MyUtil.creatImage(ConsDemo.BOSS);
        titleImg[TYPE_HARD]=MyUtil.creatImage(ConsDemo.IRON);
        if(tileW<=0){
            tileW=titleImg[TYPE_HOUSE].getWidth(null);
        }

    }
    // 图片资源的左上角坐标
    private int x,y;
    private boolean visible=true;

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    /**
     * 地图块和子弹是否有碰撞
     * @param
     * @return
     */
    public boolean isCollideBullet(List<Bullet> bullets){
        if(!visible || type==TYPE_COVER)
            return false;
        for (Bullet bullet : bullets) {
            int bulletX=bullet.getX();
            int bulletY= bullet.getY();
            boolean collide = MyUtil.isCollide((x + radius), (y + radius), radius, bulletX, bulletY);
            if(collide){
                // 子弹销毁
                bullet.setVisible(false);
                BulletsPool.back(bullet);
                return true;
            }
        }
        return false;
    }


    public MapTile(int x, int y){
        this.x=x;
        this.y=y;
        if(tileW<=0){
            tileW=titleImg[TYPE_HOUSE].getWidth(null);
        }
    }

    public MapTile() {
    }

    // 判断当前地图块是否是老巢
    public boolean isHouse(){
        return type==TYPE_HOUSE;
    }
    public void draw(Graphics g){
        if(!visible)
            return;
        if(tileW<=0){
            tileW=titleImg[TYPE_HOUSE].getWidth(null);
        }
        g.drawImage(titleImg[type],x,y,null);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

游戏地图类

package com.hg.map;

import com.hg.MainJFrame.GameFrame;
import com.hg.Util.ConsDemo;
import com.hg.Util.MapTitlePool;
import com.hg.Util.MyUtil;
import com.hg.tank.Tank;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 游戏地图类
 */
public class GameMap {
    // 地图坐标
    public static final int MAP_X = Tank.BAN_JIN*3;
    public static final int MAP_Y = Tank.BAN_JIN*3+ GameFrame.menuTitle;
    public static final int MAP_WIDTH = ConsDemo.FRAME_WIDTH-Tank.BAN_JIN*6;
    public static final int MAP_HEIGHT = (ConsDemo.FRAME_HEIGTH-Tank.BAN_JIN*8-GameFrame.menuTitle);
    // 地图大小
    private int width,height;
    private TankHouse house;
    // 地图元素块容器
    private List<MapTile> tiles=new ArrayList<>();

    public GameMap() {
        initMap();
    }

    /**
     * 初始化地图元素块
     */
    private void initMap(){
        // 可以加上,可以不加
         // 随机添加一个地图块元素,添加到容器中
//        final int COUNT=30;
//        for (int i = 0; i < COUNT; i++) {
//            MapTile title= MapTitlePool.get();
//            int x= MyUtil.getRamdomNumber(MAP_X,MAP_X+MAP_WIDTH-MapTile.tileW);
//            int y= MyUtil.getRamdomNumber(MAP_Y,MAP_Y+MAP_HEIGHT-MapTile.tileW);
//            title.setX(x);
//            title.setY(y);
//            tiles.add(title);
//        }
        // 三行地图
        addRow(MAP_X,MAP_Y,MAP_X+MAP_WIDTH,MapTile.TYPE_NORMAL,0);
        addRow(MAP_X,MAP_Y+MapTile.tileW*6,MAP_X+MAP_WIDTH,MapTile.TYPE_COVER,0);
        addRow(MAP_X,MAP_Y+MapTile.tileW*20,MAP_X+MAP_WIDTH,MapTile.TYPE_HARD,MapTile.tileW*3);
        house=new TankHouse();
        addHouse();
    }

    /**
     * 往地图块容器中添加一行指定类型的地图块
     * @param startX 地图块起始坐标
     * @param startY
     * @param endX 新增地图块的结束坐标
     * @param type 地图块类型
     * @param DIS 地图块的间隔
     */
    public void addRow(int startX,int startY,int endX,int type,final int DIS){
        int count=0;
            count=(endX-startX)/MapTile.tileW;
            for (int i = 0; i < count; i++) {
                MapTile tile=MapTitlePool.get();
                tile.setType(type);
                tile.setX(startX+i*(MapTile.tileW+DIS));
                tile.setY(startY);
                tiles.add(tile);
            }
        }


    /**
     * 某一个点是否和 titles 集合中的所有块用重叠部分,有返回true
     * @param tiles
     * @param x
     * @param y
     * @return
     */
    private boolean isCollide(List<MapTile> tiles,int x,int y){
        for (MapTile tile : tiles) {
            int tiltX=tile.getX();
            int tiltY=tile.getY();
            if(Math.abs(tiltX-x)<MapTile.tileW && Math.abs(tiltY-y)<MapTile.tileW);
            return true;
        }
        return false;
    }
    // 对没有遮挡效果的块绘制
    public void drawBK(Graphics g){
        for (MapTile tile : tiles) {
            if(tile.getType()!=MapTile.TYPE_COVER)
            tile.draw(g);
        }
        // 初始化大本营
        //house.draw(g);
    }
    // 只绘制有遮挡的块
    public void drawCover(Graphics g){
        for (MapTile tile : tiles) {
            if(tile.getType()==MapTile.TYPE_COVER)
                tile.draw(g);
        }
        // 初始化大本营
        //house.draw(g);
    }

    /**
     * 把老巢元素块添加到地图的容器中
     */
    private void addHouse(){
        tiles.addAll(house.getTiles());

    }

    /**
     * 将所有不可见的地图块全部移除
     */
    public void clearDestoryTile(){
        for (int i = 0; i < tiles.size(); i++) {
            MapTile tile=tiles.get(i);
            if(!tile.isVisible()){
                tiles.remove(i);
            }
        }
    }

    public List<MapTile> getTiles() {
        return tiles;
    }

    public void setTiles(List<MapTile> tiles) {
        this.tiles = tiles;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

砖块所在对象池

package com.hg.Util;

import com.hg.map.MapTile;
import java.util.ArrayList;
import java.util.List;

public class MapTitlePool {
    // 初始数量
    public static final int ALL_BULLET=50;
    // 最大数量
    public static final int POOL_MAX_SIZE=70;
    // 用于保存所有砖块
    private static List<MapTile> pool =new ArrayList<>();
    static {
        for (int i = 0; i < ALL_BULLET; i++) {
            pool.add(new MapTile());
        }
    }

    /**
     *
     * @return 从池塘中拿出砖块
     */
    public static MapTile get(){
        MapTile tile;
        // 如果池塘被掏空
        if(pool.size()==0){
            tile=new MapTile();
        }else{
            tile= pool.remove(0);
        }
        return tile;

    }

    /**
     * 销毁的时候,归还到池塘中
     * @return
     */
    public static void  back(MapTile tile){
        // 池塘中的砖块已经达到最大
        if(pool.size()==POOL_MAX_SIZE){
            return;
        }
        pool.add(tile);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

BOSS所在类

package com.hg.map;

import com.hg.Util.ConsDemo;
import com.hg.Util.MyUtil;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Boss所在地方
 */
public class TankHouse {
    public static final int HOUSE_X= (ConsDemo.FRAME_WIDTH-4*MapTile.tileW>>1);
    public static final int HOUSE_Y= (ConsDemo.FRAME_HEIGTH-3*MapTile.tileW)-5;
    public static Image bossImg= MyUtil.creatImage(ConsDemo.BOSS);
    // 一共7块老鬼地图
    private List<MapTile> tiles=new ArrayList<>();

    public TankHouse() {
        tiles.add(new MapTile(HOUSE_X,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X,HOUSE_Y+MapTile.tileW));
        tiles.add(new MapTile(HOUSE_X,HOUSE_Y+MapTile.tileW*2));

        tiles.add(new MapTile(HOUSE_X+MapTile.tileW,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW*2,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW*3,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW*3,HOUSE_Y+MapTile.tileW));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW*3,HOUSE_Y+MapTile.tileW*2));
        //tiles.add(new MapTile(HOUSE_X+MapTile.tileW+6,HOUSE_Y+MapTile.tileW+15));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW,HOUSE_Y+MapTile.tileW));
        // 设置老巢地图块类型
        tiles.get(tiles.size()-1).setType(MapTile.TYPE_HOUSE);
    }
    public void draw(Graphics g){
        for (MapTile tile : tiles) {
            tile.draw(g);
        }
        //g.drawImage(bossImg,HOUSE_X+MapTile.tileW,HOUSE_Y+MapTile.tileW,null);
    }

    public List<MapTile> getTiles() {
        return tiles;
    }

    public void setTiles(List<MapTile> tiles) {
        this.tiles = tiles;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

工具类

package com.hg.Util;

import java.awt.*;
import java.net.URL;

/**
 * 工具类
 */
public class MyUtil {
    private MyUtil(){

    }

    /**
     *
     * @param min 区间最小值
     * @param max 区间最大值 (左闭右开)
     * @return 随机数
     */
    public static final int getRamdomNumber(int min,int max){
        //return (int)(Math.random()*max-min);
        return (int)(Math.random()*(max-min)+min);
    }

    /**

     * @return 获取随机三原色
     */
    public static final Color getRamdomColor(){
        int red=getRamdomNumber(0,256);
        int blue=getRamdomNumber(0,256);
        int green=getRamdomNumber(0,256);
        return new Color(red,blue,green);

    }

    /**
     * 判断一个点是否在一个正方形中心点的内部
     * @param retX 正方形中心点x
     * @param retY 正方形中心点y
     * @param radius 正方形边长的一半
     * @param pointX 圆的x坐标
     * @param pointY 圆的y坐标
     * @return 如果点在正方形内部返回true
     */
    public static final boolean isCollide(int retX,int retY,int radius,int pointX,int pointY){
        // 正方形中心点的 x和 y的距离
        int disX=Math.abs(retX-pointX);
        int disY=Math.abs(retY-pointY);
        if(disX<radius && disY< radius)
            return true;
        return false;
    }

    /**
     *
     * @param path 图片路径
     * @return
     */
    public static final Image creatImage(URL path){
        return Toolkit.getDefaultToolkit().createImage(path);
    }

    public static final String[] AI_Name={

            "行人","乐园", "花草","人才","左手","目的","课文","优点","年代","灰尘","沙子","小说","儿女","难题","明星","本子",
            "彩色", "水珠","路灯","把握","房屋","心愿","左边","新闻","早点", "市场","雨点", "细雨","书房","毛巾","画家",
            "元旦","绿豆","本领" , "起点","青菜","土豆","总结","礼貌","右边"

};
    public static final String[] AI_NAME={
            "可爱","傻傻","萌萌","羞羞","笨笨","呆呆","美丽","聪明" ,"伶俐","狡猾","胖乎乎","粉嫩嫩","白胖胖","漂亮"
            ,"可爱","聪明","懂事","乖巧","淘气","淘气","顽劣","调皮","顽皮", "天真","可爱","无邪","单纯","纯洁","无暇","纯真"
    };
    /**
     * 随机获取一个名字
     */
    public static final String getRandomName(){
        return AI_NAME[getRamdomNumber(0,AI_NAME.length)]+"的"+AI_Name[getRamdomNumber(0,AI_Name.length)];
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

静态资源类

package com.hg.Util;

import com.hg.tank.Tank;

import java.awt.*;
import java.net.URL;

/**
 *  游戏中的常量都在该类中,方便后期管理
 */
public class ConsDemo {
    public static final String NAME_TANK="坦克大战";
    public static final int FRAME_WIDTH=1200;
    public static final int FRAME_HEIGTH=800;

    /**
     * 游戏菜单相关常量
     */
    public static final int START_MENU=0;
    public static final int START_HELP=1;
    public static final int START_ABOUT=2;
    public static final int START_RUN=3;
    public static final int START_OVER =4;

    public static final String[] MENUS={
      "开始游戏","继续游戏","游戏帮助","游戏关于","退出游戏"
    };
    public static final String OVER_STA="ESC退出游戏";
    public static final String OVER_STA1="Enter回到主菜单";
    // 坦克名字
    public static final Font GAME_FONT=new Font("楷体",Font.BOLD,14);

    public static final Font FONT_SIZE=new Font("楷体",Font.PLAIN,25);
    // 重绘时间
    public static final int REPAIN_TIME=30;
    // 坦克图片的地址
    public static final URL url= Tank.class.getResource("/tank/player1_up.png");
    public static final URL url1=Tank.class.getResource("/tank/player1_down.png");
    public static final URL url2=Tank.class.getResource("/tank/player1_left.png");
    public static final URL url3=Tank.class.getResource("/tank/player1_right.png");

    // 敌人坦克图片地址
    public static final URL enemyUrl1= Tank.class.getResource("/tank/bot_up.png");
    public static final URL enemyUrl2=Tank.class.getResource("/tank/bot_down.png");
    public static final URL enemyUrl3=Tank.class.getResource("/tank/bot_left.png");
    public static final URL enemyUrl4=Tank.class.getResource("/tank/bot_right.png");

    // 敌人坦克图片地址
    public static final URL enemy2Url1= Tank.class.getResource("/tank/player2_up.png");
    public static final URL enemy2Url2=Tank.class.getResource("/tank/player2_down.png");
    public static final URL enemy2Url3=Tank.class.getResource("/tank/player2_left.png");
    public static final URL enemy2Url4=Tank.class.getResource("/tank/player2_right.png");

    // 最大敌人数量
    public static final int MAX_ENEMY_COUNT=10;
    // 敌人随机切换状态的时间
    public static final int ENEMY_AI=1000;
    // 敌人开火的几率
    public static final double ENEMY_FIRE=0.6;
    // 爆炸的路径
    public static final URL BOOM= Tank.class.getResource("/img/boom/boom.png");
    // 结束游戏图片路径
    public static final URL gameOver= Tank.class.getResource("/tank/gameover.jpg");
    // 砖块路径
    public static final URL BRICK= Tank.class.getResource("/img/wall/brick.png");
    public static final URL GRASS= Tank.class.getResource("/img/wall/grass.png");
    public static final URL IRON= Tank.class.getResource("/img/wall/iron.png");
    // BOSS
    public static final URL BOSS= Tank.class.getResource("/img/wall/base.png");


}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

main方法

package com.hg.TankBattle;

import com.hg.MainJFrame.GameFrame;

public class TextMain {
    public static void main(String[] args) {
        new GameFrame();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

图片目录

大家有图片的可以自行设置路径
在这里插入图片描述

游戏效果截图:

在这里插入图片描述第一次做还有很多不足之处,欢迎大家指出,大家有什么问题也可以留言咨询!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/513749
推荐阅读
相关标签
  

闽ICP备14008679号