[ java ] 坦克大战 5.0 ~ 最终完整版

坦克大战5.0
新增功能内容:(加入IO流内容)

  • 防止敌坦克间重叠
  • 击杀数显示
  • 保存上局游戏进度–>两种开局方式
  • 加入开局音乐
  • 修复记录文件丢失后的异常

5.0版本为最终版
提示:爆炸图片需自行按路径放在工程文件的out文件夹对应的包下
以及适当位置安放开局音乐文件,否则会报空指针异常

画框

package com.hspedu.tankgame06;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-20:33
 * @Version
 * 第六版:开局音乐->修复记录文件丢失后的异常
 */
public class ZxkTankGame06 extends JFrame {//画框
    MyPanel mp = null;//定义画板
    Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        ZxkTankGame06 zxkTankGame01 = new ZxkTankGame06();//初始化画框
    }
    public ZxkTankGame06(){

        System.out.println("请选择:1.开始新游戏/2.继续上局游戏");
        String key = scanner.next();
        setSize(1300,950);//画框大小
        mp = new MyPanel(key);//新建画板
        new Thread(mp).start();
        this.add(mp);//添加画板自动重画线程为了子弹和敌坦克的移动

        addKeyListener(mp);//监听画板的键盘
        setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭操作
        setVisible(true);//可视化

        //画板中增加相应的关闭窗口的处理
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("监听到关闭窗口");
                Recorder.keepRecord();
                System.exit(0);
            }
        });
    }
}

画板

package com.hspedu.tankgame06;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-20:32
 * @Version
 *///画板
public class MyPanel extends JPanel implements KeyListener, Runnable {
    Hero hero = null;//定义我的坦克
    Vector<EnemyTank> enemyTanks = new Vector<>();//创建敌坦克集合
    Vector<Bomb> bombs = new Vector<>();//创建炸弹集合
    Vector<Node> nodes = null;//用于接收上局敌坦克信息
    //定义三张爆炸图片
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    public MyPanel(String key) {
        String recordFile = Recorder.getRecordFile();
        File file = new File(recordFile);
        if (!file.exists() ) {//文件丢失->强制开新游戏
            System.out.println("没有上局记录,选择重开游戏!");
            key = "1";
        }

        //初始化Hero
        hero = new Hero(400, 400, 'a', 10);
        nodes = Recorder.getInfo();//接收上局敌坦克信息

        switch (key) {
            case "1"://新游戏
                //初始化敌坦克及其子弹
                for (int i = 0; i < 3; i++) {
                    EnemyTank enemyTank = new EnemyTank(100 + i * 100, 0, 's', 1);
                    new Thread(enemyTank).start();
                    enemyTanks.add(enemyTank);
                    Bullet ammo = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 60, 's');
                    new Thread(ammo).start();
                    enemyTank.ammos.add(ammo);
                }
                break;
            case "2"://继续上局
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY(), node.getDirect(), 1);
                    new Thread(enemyTank).start();
                    enemyTanks.add(enemyTank);
                    Bullet ammo = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 30, enemyTank.getDirection());
                    new Thread(ammo).start();
                    enemyTank.ammos.add(ammo);
                }
                break;
        }





        //敌坦克集合传递给Recorder属性
        Recorder.setEnemyTanks(enemyTanks);


        //加载图片
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));//必须用"/"
        //开局音效
        new AePlayWave("chapter20\\src\\111.wav").start();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);//填满画板
        //绘制Hero
        if (hero.alive) {
            drawTank(hero.getX(), hero.getY(), g, hero.getDirection(), true);
        }
        //绘制Hero的子弹
        if (hero.bullets != null) {
            for (int i = 0; i < hero.bullets.size(); i++) {
                Bullet bullet = hero.bullets.get(i);//从弹夹取出子弹
                if (bullet != null && bullet.alive) {
                    g.draw3DRect(bullet.x, bullet.y, 1, 1, false);
                } else {
                    hero.bullets.remove(bullet);//移除已消亡的子弹
                }
            }

        }
        //绘制敌坦克及其子弹
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            if (enemyTank.alive) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), false);
                enemyTank.setEnemyTanks(enemyTanks);//敌坦克集合赋值给敌坦克的属性
            } else {
                enemyTanks.remove(enemyTank);
            }
            for (int j = 0; j < enemyTank.ammos.size(); j++) {
                //取出子弹绘制
                Bullet ammo = enemyTank.ammos.get(j);
                if (ammo != null && ammo.alive) {
                    g.draw3DRect(ammo.x, ammo.y, 1, 1, false);
                } else {
                    enemyTank.ammos.remove(ammo);
                }
            }
        }
        //绘制爆炸
        for (int i = 0; i < bombs.size(); i++) {
            Bomb bomb = bombs.get(i);
            if (bomb.life > 6) {
                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
            } else if (bomb.life > 3) {
                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
            } else {
                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
            }
            bomb.lifeDown();
            if (!bomb.alive) {
                bombs.remove(bomb);
            }
        }
        showInfo(g);
    }

    //编写方法:显示我方击毁敌方坦克信息
    public void showInfo(Graphics g){
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);

        g.drawString("您累计击毁敌方坦克", 1020, 30);
        drawTank(1020, 60, g, 'w', false);
        g.setColor(Color.BLACK);//重设颜色为黑
        g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
    }

    //封装坦克绘制方法
    public void drawTank(int x, int y, Graphics g, char direction, boolean type) {
        if (type) {//敌我坦克颜色
            g.setColor(Color.YELLOW);
        } else {
            g.setColor(Color.cyan);
        }
        //由方向绘制坦克各部分位置
        switch (direction) {
            case 'w':
                g.fill3DRect(x, y, 10, 60, false);//左车轮
                g.fill3DRect(x + 30, y, 10, 60, false);//右车轮
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//车底
                g.fillOval(x + 10, y + 20, 20, 20);//圆盖
                g.drawLine(x + 20, y + 30, x + 20, y);//炮筒
                break;
            case 's':
                g.fill3DRect(x, y, 10, 60, false);//左车轮
                g.fill3DRect(x + 30, y, 10, 60, false);//右车轮
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//车底
                g.fillOval(x + 10, y + 20, 20, 20);//圆盖
                g.drawLine(x + 20, y + 30, x + 20, y + 60);//炮筒
                break;
            case 'a':
                g.fill3DRect(x - 10, y + 10, 60, 10, false);//上车轮
                g.fill3DRect(x - 10, y + 40, 60, 10, false);//下车轮
                g.fill3DRect(x, y + 20, 40, 20, false);//车底
                g.fillOval(x + 10, y + 20, 20, 20);//圆盖不变
                g.drawLine(x + 20, y + 30, x - 10, y + 30);//炮筒
                break;
            case 'd':
                g.fill3DRect(x - 10, y + 10, 60, 10, false);//上车轮
                g.fill3DRect(x - 10, y + 40, 60, 10, false);//下车轮
                g.fill3DRect(x, y + 20, 40, 20, false);//车底
                g.fillOval(x + 10, y + 20, 20, 20);//圆盖不变
                g.drawLine(x + 20, y + 30, x + 50, y + 30);//炮筒
                break;
        }
    }

    //判断方法:子弹是否击中坦克->坦克消亡,子弹消亡->新建爆炸对象
    /*public void hitEnemyTank(Bullet bullet, EnemyTank enemyTank){
        switch (enemyTank.getDirection()) {
            case 'w':
            case 's':
                if (bullet.x >= enemyTank.getX() && bullet.x <= enemyTank.getX() + 40
                        && bullet.y >= enemyTank.getY() && bullet.y <= enemyTank.getY() + 60) {
                    bombs.add(new Bomb(enemyTank.getX(), enemyTank.getY()));
                    enemyTank.alive = false;
                    bullet.alive = false;
                }
                break;
            case 'a':
            case 'd':
                if (bullet.x >= enemyTank.getX() - 10 && bullet.x <= enemyTank.getX() + 50
                        && bullet.y >= enemyTank.getY() + 10 && bullet.y <= enemyTank.getY() + 50) {
                    bombs.add(new Bomb(enemyTank.getX()-10, enemyTank.getY()+10));
                    enemyTank.alive = false;
                    bullet.alive = false;
                }
                break;
        }
    }*/
    //判断的参数类型为Tank (父类),返回坦克的存活布尔值
    public boolean hitTank(Bullet bullet, Tank tank) {
        switch (tank.getDirection()) {
            case 'w':
            case 's':
                if (bullet.x >= tank.getX() && bullet.x <= tank.getX() + 40
                        && bullet.y >= tank.getY() && bullet.y <= tank.getY() + 60) {
                    bombs.add(new Bomb(tank.getX(), tank.getY()));
//                    enemyTank.alive = false;
                    bullet.alive = false;
                    return false;
                }
                break;
            case 'a':
            case 'd':
                if (bullet.x >= tank.getX() - 10 && bullet.x <= tank.getX() + 50
                        && bullet.y >= tank.getY() + 10 && bullet.y <= tank.getY() + 50) {
                    bombs.add(new Bomb(tank.getX() - 10, tank.getY() + 10));
//                    enemyTank.alive = false;
                    bullet.alive = false;
                    return false;
                }
                break;
        }
        return true;
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {//重写按键事件
        //按键控制移动
        if (e.getKeyCode() == KeyEvent.VK_W) {
            hero.setDirection('w');
            hero.moveUp();
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            hero.setDirection('s');
            hero.moveDown();
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            hero.setDirection('a');
            hero.moveLeft();
        }
        if (e.getKeyCode() == KeyEvent.VK_D) {
            hero.setDirection('d');
            hero.moveRight();
        }
        //j键hero射击
        if (e.getKeyCode() == KeyEvent.VK_J) {
            /*if (hero.bullet == null || !hero.bullet.alive) {
                hero.shot();
            }*/
            hero.shot();
        }
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);//定时自动重画为显示自动移动的对象
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (hero.bullet != null) {//定时判断是否击中敌坦克
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);//取出敌坦克
                    for (int j = 0; j < hero.bullets.size(); j++) {
                        Bullet bullet = hero.bullets.get(j);//取出Hero子弹
                        if (enemyTank.alive) {//判断存活的坦克是否被击中
                            enemyTank.alive = hitTank(bullet, enemyTank);
                            if (!enemyTank.alive) {//如果被击中则记录下来
                                Recorder.addEnemyTankNum();
                            }
                        }
                    }
                }
            }
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);//取出敌坦克
                for (int j = 0; j < enemyTank.ammos.size(); j++) {
                    Bullet ammo = enemyTank.ammos.get(j);//取出其子弹
                    if (hero.alive) {//保证hero存活才判断,hero消亡如果调用则会复活
                        hero.alive = hitTank(ammo, hero);
                    }
                }
            }
            repaint();
        }
    }
}

Tank类

package com.hspedu.tankgame06;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-20:32
 * @Version
 *///坦克类
public class Tank {
    private int x;
    private int y;
    private char direction;
    private int speed;

    public Tank(int x, int y, char direction, int speed) {
        this.x = x;
        this.y = y;
        this.direction = direction;
        this.speed = speed;
    }

    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 char getDirection() {
        return direction;
    }

    public void setDirection(char direction) {
        this.direction = direction;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }
    //坦克四个移动方法
    public void moveUp(){
        if (y > 0) {
            y -= speed;
        }
    }
    public void moveDown(){
        if (y+60< 750) {
            y += speed;
        }
    }
    public void moveLeft(){
        if (x -10> 0) {
            x -= speed;
        }
    }
    public void moveRight(){
        if (x +50< 1000) {
            x += speed;
        }
    }

}

Hero类

package com.hspedu.tankgame06;

import java.util.Vector;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-20:32
 * @Version
 *///我方坦克
public class Hero extends Tank {
    boolean alive = true;
    Bullet bullet = null;//空弹
    Vector<Bullet> bullets = new Vector<>();
    public Hero(int x, int y, char direction, int speed) {
        super(x, y, direction, speed);
    }
    public void shot(){//射击时填弹
        if (bullets.size() >= 5) {
            return;
        }
        switch (getDirection()) {
            case 'w':
                bullet = new Bullet(getX() + 20, getY(), 'w');
                break;
            case 's':
                bullet = new Bullet(getX() + 20, getY()+60, 's');
                break;
            case 'a':
                bullet = new Bullet(getX() -10, getY()+30, 'a');
                break;
            case 'd':
                bullet = new Bullet(getX() +50, getY()+30, 'd');
                break;
        }
        bullets.add(bullet);
        new Thread(bullet).start();//启动该子弹线程控制轨迹
        /*for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            new Thread(bullet).start();
        }*/

    }
}

EnemyTank类

package com.hspedu.tankgame06;

import java.util.Vector;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-20:32
 * @Version
 * 敌坦克线程:自由移动
 */
public class EnemyTank extends Tank implements Runnable{
    boolean alive = true;
    Bullet ammo = null;
    Vector<Bullet> ammos = new Vector<>();//敌坦克弹夹
    Vector<EnemyTank> enemyTanks = new Vector<>();//用以防止重叠的敌坦克集合属性

    public EnemyTank(int x, int y, char direction, int speed) {
        super(x, y, direction, speed);
    }

    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        this.enemyTanks = enemyTanks;
    }

    //判断当前坦克与其他坦克是否重叠true/不重叠false
    //当前坦克必须分四个方向,其他坦克可以反向归为一类
    public boolean isTouch() {
        switch (getDirection()) {
            //当前坦克方向为:w
            case 'w':
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
                        if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
                            //当前坦克左上角点(x,y)进入其他坦克
                            if (getX() >= enemyTank.getX() && getX() <= enemyTank.getX() + 40
                                    && getY() >= enemyTank.getY() && getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //当前坦克右上角点(x+40,y)进入其他坦克
                            if (getX() +40>= enemyTank.getX() && getX() +40<= enemyTank.getX() + 40
                                    && getY() >= enemyTank.getY() && getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
                        if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
                            //当前坦克左上角点(x,y)进入其他坦克
                            if (getX() >= enemyTank.getX()-10 && getX() <= enemyTank.getX() + 50
                                    && getY() >= enemyTank.getY()+10 && getY() <= enemyTank.getY() + 50) {
                                return true;
                            }
                            //当前坦克右上角点(x+40,y)进入其他坦克
                            if (getX() +40>= enemyTank.getX()-10 && getX() +40<= enemyTank.getX() + 50
                                    && getY() >= enemyTank.getY() +10&& getY() <= enemyTank.getY() + 50) {
                                return true;
                            }
                        }
                    }
                }
                break;
            //当前坦克方向为:s
            case 's':
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
                        if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
                            //当前坦克左下角点(x,y+60)进入其他坦克
                            if (getX() >= enemyTank.getX() && getX() <= enemyTank.getX() + 40
                                    && getY()+60 >= enemyTank.getY() && getY()+60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //当前坦克右下角点(x+40,y+60)进入其他坦克
                            if (getX() +40>= enemyTank.getX() && getX()+40 <= enemyTank.getX() + 40
                                    && getY()+60 >= enemyTank.getY() && getY()+60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
                        if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
                            //当前坦克左下角点(x,y+60)进入其他坦克
                            if (getX() >= enemyTank.getX() -10 && getX()<= enemyTank.getX() + 50
                                    && getY()+60 >= enemyTank.getY()+10 && getY()+60 <= enemyTank.getY() + 50) {
                                return true;
                            }
                            //当前坦克右下角点(x+40,y+60)进入其他坦克
                            if (getX() +40>= enemyTank.getX() -10&& getX()+40 <= enemyTank.getX() + 50
                                    && getY()+60 >= enemyTank.getY()+10 && getY()+60 <= enemyTank.getY() + 50) {
                                return true;
                            }
                        }
                    }

                }
                break;
            //当前坦克方向为:a
            case 'a':
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
                        if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
                            //当前坦克左上角点(x-10,y+10)进入其他坦克
                            if (getX() -10>= enemyTank.getX() && getX() -10<= enemyTank.getX() + 40
                                    && getY() +10>= enemyTank.getY() && getY()+10 <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //当前坦克左下角点(x-10,y+50)进入其他坦克
                            if (getX() -10>= enemyTank.getX() && getX() -10<= enemyTank.getX() + 40
                                    && getY()+50 >= enemyTank.getY() && getY()+50 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
                        if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
                            //当前坦克左上角点(x-10,y+10)进入其他坦克
                            if (getX() -10>= enemyTank.getX()-10 && getX() -10<= enemyTank.getX() + 50
                                    && getY() +10>= enemyTank.getY()+10 && getY()+10 <= enemyTank.getY() + 50) {
                                return true;
                            }
                            //当前坦克左下角点(x-10,y+50)进入其他坦克
                            if (getX() -10>= enemyTank.getX() -10 && getX()-10<= enemyTank.getX() + 50
                                    && getY()+50 >= enemyTank.getY()+10 && getY()+50 <= enemyTank.getY() + 50) {
                                return true;
                            }
                        }
                    }

                }
                break;
            //当前坦克方向为:d
            case 'd':
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
                        if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
                            //当前坦克右上角点(x+50,y+10)进入其他坦克
                            if (getX() +50>= enemyTank.getX() && getX() +50<= enemyTank.getX() + 40
                                    && getY() +10>= enemyTank.getY() && getY()+10 <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //当前坦克右下角点(x+50,y+50)进入其他坦克
                            if (getX() +50>= enemyTank.getX() && getX()+50 <= enemyTank.getX() + 40
                                    && getY()+50 >= enemyTank.getY() && getY()+50 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
                        if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
                            //当前坦克右上角点(x+50,y+10)进入其他坦克
                            if (getX() +50>= enemyTank.getX()-10 && getX() +50<= enemyTank.getX() + 50
                                    && getY() +10>= enemyTank.getY() +10&& getY() +10<= enemyTank.getY() + 50) {
                                return true;
                            }
                            //当前坦克右下角点(x+50,y+50)进入其他坦克
                            if (getX() +50>= enemyTank.getX() -10&& getX()+50 <= enemyTank.getX() + 50
                                    && getY()+50 >= enemyTank.getY()+10 && getY()+50 <= enemyTank.getY() + 50) {
                                return true;
                            }
                        }
                    }

                }
                break;
        }
        return false;
    }
    @Override
    public void run() {
        while (true) {//敌坦克子弹消亡立即填弹并开启子弹线程
            switch (getDirection()) {
                case 'w':
                    ammo = new Bullet(getX() + 20, getY(), 'w');
                    break;
                case 's':
                    ammo = new Bullet(getX() + 20, getY()+60, 's');
                    break;
                case 'a':
                    ammo = new Bullet(getX() -10, getY()+30, 'a');
                    break;
                case 'd':
                    ammo = new Bullet(getX() +50, getY()+30, 'd');
                    break;
            }
            if (ammos.size() == 0) {
                ammos.add(ammo);
                new Thread(ammo).start();
            }



            switch (getDirection()) {//按随机生成的方向移动30次(50ms一次)
                case 'w':
                    for (int i = 0; i < 30; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!isTouch()) {
                            moveUp();
                        }
                    }
                    break;
                case 's':
                    for (int i = 0; i < 30; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!isTouch()) {
                            moveDown();
                        }
                    }
                    break;
                case 'a':
                    for (int i = 0; i < 30; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!isTouch()) {
                            moveLeft();
                        }
                    }
                    break;
                case 'd':
                    for (int i = 0; i < 30; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (!isTouch()) {
                            moveRight();
                        }
                    }
                    break;
            }
            int direct = (int)(Math.random() * 4);//生成随机方向
            switch (direct) {
                case 0:
                    setDirection('w');
                    break;
                case 1:
                    setDirection('s');
                    break;
                case 2:
                    setDirection('a');
                    break;
                case 3:
                    setDirection('d');
                    break;
            }
        }
    }
}

Bullet类

package com.hspedu.tankgame06;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-21-21:49
 * @Version
 */
public class Bullet implements Runnable{
    int x;
    int y;
    char direction;
    boolean alive = true;

    public Bullet(int x, int y, char direction) {
        this.x = x;
        this.y = y;
        this.direction = direction;
    }

    @Override
    public void run() {
        while (true) {
            switch (direction) {
                case 'w':
                    y -= 5;
                    break;
                case 's':
                    y += 5;
                    break;
                case 'a':
                    x -= 5;
                    break;
                case 'd':
                    x += 5;
                    break;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //子弹脱离画板或消亡(击中)终止线程
            if (x <= 0 || x >= 1000 || y <= 0 || y >= 750||!alive) {
                System.out.println("子弹线程终止");
                alive = false;//此时不画子弹
                break;
            }
        }
    }
}

Bomb类

package com.hspedu.tankgame06;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-20-10:46
 * @Version
 */
public class Bomb {
    int x, y;
    int life = 9;
    boolean alive = true;

    public Bomb(int x, int y) {
        this.x = x;
        this.y = y;
    }
    //减少生命值
    public void lifeDown() {
        if (life > 0) {
            life--;
        } else {
            alive = false;
        }
    }
}

Recorder类

package com.hspedu.tankgame06;

import java.io.*;
import java.util.Vector;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-29-21:03
 * @Version 该类用于记录相关信息, 和文件交互
 */
public class Recorder {
    private static int allEnemyTankNum = 0;
    private static Vector<EnemyTank> enemyTanks = null;
    private static Vector<Node> nodes = new Vector<>();//用于存放读到的坦克信息到结点
    private static String recordFile = "chapter20\\src\\myRecord.txt";//保存到src下

    //读取上局坦克信息到结点
    public static Vector<Node> getInfo() {
        BufferedReader br = null;
        String line;
        try {
            File file = new File(recordFile);
            if (file.exists()) {//健壮性判断:文件找不到异常
                br = new BufferedReader(new FileReader(recordFile));
                allEnemyTankNum = Integer.parseInt(br.readLine());//String->int存活数
                while ((line = br.readLine()) != null) {
                    String[] s = line.split(" ");
                    Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), s[2].charAt(0));//位置
                    nodes.add(node);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return nodes;
    }
    //记录上局游戏的杀敌数,敌人属性
    public static void keepRecord()  {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(recordFile));
            //写入杀敌数
            bw.write(allEnemyTankNum + "");//方法形参没有int类型
            bw.newLine();
            //写入敌人退出时的属性
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);
                bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirection());
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
    //提供获取文件路径的方法

    public static String getRecordFile() {
        return recordFile;
    }

    public static void setAllEnemyTankNum(int allEnemyTankNum) {
        Recorder.allEnemyTankNum = allEnemyTankNum;
    }
    public static int getAllEnemyTankNum() {
        return allEnemyTankNum;
    }

    public static Vector<EnemyTank> getEnemyTanks() {
        return enemyTanks;
    }

    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    public static void addEnemyTankNum() {
        ++allEnemyTankNum;
    }
}

Node类

package com.hspedu.tankgame06;

/**
 * @ClassName
 * @Description
 * @Author zxk
 * @DateTime 2022-01-30-0:00
 * @Version
 记录坦克信息到结点
 */
public class Node {
    private int x;
    private int y;
    private char direct;

    public Node(int x, int y, char direct) {
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

    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 char getDirect() {
        return direct;
    }

    public void setDirect(char direct) {
        this.direct = direct;
    }
}

AePlayWave类

package com.hspedu.tankgame06;

import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;

/**
 * @author 韩顺平
 * @version 1.0
 * 该类用于开局播放音乐
 */
public class AePlayWave extends Thread {
    private String filename;

    public AePlayWave(String wavfile) { //构造器 , 指定文件
        filename = wavfile;

    }

    public void run() {

        File soundFile = new File(filename);

        AudioInputStream audioInputStream = null;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (Exception e1) {
            e1.printStackTrace();
            return;
        }

        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

        try {
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        auline.start();
        int nBytesRead = 0;
        //这是缓冲
        byte[] abData = new byte[512];

        try {
            while (nBytesRead != -1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0)
                    auline.write(abData, 0, nBytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }

    }
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值