坦克大战源码放出

272 篇文章 4 订阅
14 篇文章 4 订阅

文章目录

只需要注意一点

需要载入一下坦克爆炸图片,不然会异常,你们自己找来复制命名吧
复制在这个位置
在这里插入图片描述
wav音乐文件最好也注意下路径啥的

AePlayWave类

package tankgame6;

/**
 * Create By 刘鸿涛
 * 2022/2/5 18:06
 */


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

//public class AePlayWave {
//    public static void main(String[] args){
//        AePlayWave apw = new AePlayWave("D:\\start.wav");
//        apw.start();
//    }
//}

class AePlayWave extends Thread{
    private String filename;

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

    public void run(){
        File SoundFile = new File(filename);

        AudioInputStream audioInputStream = null;

        try {
            audioInputStream = AudioSystem.getAudioInputStream(SoundFile);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

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

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

        sdl.start();
        int nBytesRead = 0;
        //缓冲
        byte[] abData = new byte [1024];
        try {
            while(nBytesRead!=-1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) {
                    sdl.write(abData, 0, nBytesRead);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        } finally {
            sdl.drain();
            sdl.close();
        }
    }
}

Bomb类

package tankgame6;

/**
 * Create By 刘鸿涛
 * 2022/1/19 4:56
 */
public class Bomb {
    int x, y;   //炸弹的坐标
    int life = 9;   //炸弹的生命周期
    boolean isLive = true;  //是否还存活

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

    //减少生命值
    public void lifeDown(){
        if(life > 0){
            life--;
        }else {
            isLive = false;
        }
    }
}

EnemyTank类

package tankgame6;

import java.util.Vector;

/**
 * Create By 刘鸿涛
 * 2022/1/13 2:16
 */
public class EnemyTank extends Tank implements Runnable {
    //在敌人坦克类,使用Vector 保存多个Shot
    Vector<Shot> shots = new Vector<>();
    //增加成员,EnemyTank 可以得到敌人坦克的Vector
    Vector<EnemyTank> enemyTanks = new Vector<>();
    boolean isLive = true;

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

    //这里提供一个方法,可以将MyPanel的成员 Vector<EnemyTank> enemyTanks = new Vector<>();
    //设置到 EnemyTank 的成员 enemyTanks
    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {

        this.enemyTanks = enemyTanks;
    }

    //编写方法,判断当前的这个敌人坦克,是否和enemyTanks中的其他坦克发生了重叠或者碰撞
    public boolean isTouchEnemyTank() {
        //判断当前敌人坦克(this)方向
        switch (this.getDirect()) {
            case 0:////让当前的敌人坦克和其他所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上、下
                        //1.如果敌人坦克是上/下 x的范围[enemyTank.getX(),enemyTank.getX() + 40]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            //2.当前坦克,左上角的坐标 [this.getX(),this.getY()]
                            if (this.getX() >= enemyTank.getX() &&
                                    this.getX() <= enemyTank.getX() &&
                                    this.getY() >= enemyTank.getY() &&
                                    this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }

                            //3.当前坦克 右上角的坐标 [this.getX() + 40,this.getY()]
                            if (this.getX() + 40 >= enemyTank.getX() &&
                                    this.getX() + 40 <= enemyTank.getX() + 40 &&
                                    this.getY() >= enemyTank.getY() &&
                                    this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人坦克是右、左
                        //1.如果敌人坦克是上/下 x的范围[enemyTank.getX(),enemyTank.getX() + 60]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //2.当前坦克,左上角的坐标 [this.getX(),this.getY()]
                            if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                                //2.当前坦克,左上角的坐标 [this.getX(),this.getY()]
                                if (this.getX() >= enemyTank.getX() &&
                                        this.getX() <= enemyTank.getX() + 60 &&
                                        this.getY() >= enemyTank.getY() &&
                                        this.getY() <= enemyTank.getY() + 40) {
                                    return true;
                                }
                                //3.当前坦克 右上角的坐标 [this.getX() + 40,this.getY()]
                                if (this.getX() + 40 >= enemyTank.getX() &&
                                        this.getX() + 40 <= enemyTank.getX() + 60 &&
                                        this.getY() >= enemyTank.getY() &&
                                        this.getY() <= enemyTank.getY() + 40) {
                                    return true;
                                }
                            }
                        }
                    }
                }
                break;
            case 1:////让当前的敌人坦克和其他所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上、下
                        //1.如果敌人坦克是上/下 x的范围[enemyTank.getX(),enemyTank.getX() + 40]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            //2.当前坦克,右上角的坐标 [this.getX() + 60,this.getY()]
                            if (this.getX() + 60 >= enemyTank.getX() &&
                                    this.getX() + 60 <= enemyTank.getX() &&
                                    this.getY() >= enemyTank.getY() &&
                                    this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }

                            //3.当前坦克 右下角的坐标 [this.getX() + 60,this.getY() + 40]
                            if (this.getX() + 60 >= enemyTank.getX() &&
                                    this.getX() + 60 <= enemyTank.getX() + 60 &&
                                    this.getY() + 40 >= enemyTank.getY() &&
                                    this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                        //如果敌人坦克是右、左
                        //1.如果敌人坦克是左/右 x的范围[enemyTank.getX(),enemyTank.getX() + 60]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //2.当前坦克,右上角的坐标 [this.getX() + 60,this.getY()]
                            if (this.getX() + 60 >= enemyTank.getX() &&
                                    this.getX() + 60 <= enemyTank.getX() + 60 &&
                                    this.getY() >= enemyTank.getY() &&
                                    this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //3.当前坦克 右下角的坐标 [this.getX() + 60,this.getY() + 40]
                            if (this.getX() + 60 >= enemyTank.getX() &&
                                    this.getX() + 60 <= enemyTank.getX() + 60 &&
                                    this.getY() + 40 >= enemyTank.getY() &&
                                    this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 2:////让当前的敌人坦克和其他所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上、下
                        //1.如果敌人坦克是上/下 x的范围[enemyTank.getX(),enemyTank.getX() + 40]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            //2.当前坦克,左下角的坐标 [this.getX(),this.getY() + 60]
                            if (this.getX() >= enemyTank.getX() + 40 &&
                                    this.getX() <= enemyTank.getX() &&
                                    this.getY() + 60 >= enemyTank.getY() &&
                                    this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }

                            //3.当前坦克 右下角的坐标 [this.getX() + 40,this.getY() + 60]
                            if (this.getX() + 40 >= enemyTank.getX() &&
                                    this.getX() + 40 <= enemyTank.getX() + 40 &&
                                    this.getY() + 60 >= enemyTank.getY() &&
                                    this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人坦克是右、左
                        //1.如果敌人坦克是左/右 x的范围[enemyTank.getX(),enemyTank.getX() + 60]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //2.当前坦克,左下角的坐标 [this.getX(),this.getY() + 60]
                            if (this.getX() >= enemyTank.getX() &&
                                    this.getX() <= enemyTank.getX() + 60 &&
                                    this.getY() + 60 >= enemyTank.getY() &&
                                    this.getY() + 60 <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //3.当前坦克 右下角的坐标 [this.getX() + 40,this.getY() + 60]
                            if (this.getX() + 40 >= enemyTank.getX() &&
                                    this.getX() + 40 <= enemyTank.getX() + 40 &&
                                    this.getY() + 60 >= enemyTank.getY() &&
                                    this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                    }
                }

                break;
            case 3:////让当前的敌人坦克和其他所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上、下
                        //1.如果敌人坦克是上/下 x的范围[enemyTank.getX(),enemyTank.getX() + 40]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            //2.当前坦克,左上角的坐标 [this.getX(),this.getY()]
                            if (this.getX() >= enemyTank.getX() + 40 &&
                                    this.getX() <= enemyTank.getX() &&
                                    this.getY()  >= enemyTank.getY() &&
                                    this.getY()  <= enemyTank.getY() + 60) {
                                return true;
                            }

                            //3.当前坦克 左下角的坐标 [this.getX() ,this.getY() + 40]
                            if (this.getX() >= enemyTank.getX() &&
                                    this.getX() <= enemyTank.getX() + 40 &&
                                    this.getY() + 40 >= enemyTank.getY() &&
                                    this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人坦克是右、左
                        //1.如果敌人坦克是左/右 x的范围[enemyTank.getX(),enemyTank.getX() + 60]
                        //            y的范围 [enemyTank.getY(),enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //2.当前坦克,左上角的坐标 [this.getX(),this.getY()]
                            if (this.getX() >= enemyTank.getX() &&
                                    this.getX() <= enemyTank.getX() + 60 &&
                                    this.getY() >= enemyTank.getY() &&
                                    this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //3.当前坦克 左下角的坐标 [this.getX() ,this.getY() + 40]
                            if (this.getX() >= enemyTank.getX() &&
                                    this.getX() <= enemyTank.getX() + 40 &&
                                    this.getY() + 40 >= enemyTank.getY() &&
                                    this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                    }
                }
                break;
        }
        return false;
    }


    @Override
    public void run() {
        //然后随机的改变坦克方向
        while (true) {
            //这里我们判断如果shots size() = 0,创建一颗子弹,放入到shots集合中,并启动
            if (isLive && shots.size() < 10000) {

                Shot s = null;
                //判断坦克的方向,创建对应的子弹
                switch (getDirect()) {
                    case 0:
                        s = new Shot(getX() + 20, getY(), 0);
                        break;
                    case 1:
                        s = new Shot(getX() + 60, getY(), 1);
                        break;
                    case 2:
                        s = new Shot(getX() + 20, getY() + 60, 2);
                        break;
                    case 3:
                        s = new Shot(getX() + 20, getY(), 3);
                        break;
                }
                shots.add(s);
                //启动
                new Thread(s).start();

            }


            //根据坦克的方向来继续移动
            switch (getDirect()) {
                case 0://向上
                    //让坦克保存一个方向,走30步
                    for (int i = 0; i < 30; i++) {
                        if (getY() > 0 && (!isTouchEnemyTank())) {
                            moveUp();
                            //休眠50毫秒
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                    break;
                case 1://for (int i = 0; i < 30; i++) {
//                        if (getX() + 60 < 1000){
                        if (getX() < 902 && (!isTouchEnemyTank())) {

                            moveRight();
                            //休眠50毫秒
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    break;
                case 2://for (int i = 0; i < 30; i++) {
                        if (getY() < 620 && (!isTouchEnemyTank())) {
//                        if(getY() + 60 < 750){
                            moveDown();
                            //休眠50毫秒
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    break;
                case 3://for (int i = 0; i < 30; i++) {
                        if (getX() > 0 && (!isTouchEnemyTank())) {
                            moveLeft();
                            //休眠50毫秒
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    break;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //随机改变坦克方向0 - 3
            setDirect((int) (Math.random() * 4));
            //如果坦克被击中线程终止
            if (!isLive) {
                break;
            }
        }


    }
}

Hero类

package tankgame6;

import java.util.Vector;

/**
 * Create By 刘鸿涛
 * 2022/1/12 4:40
 * 自己的坦克
 */
public class Hero extends Tank {
    //定义一个Shot对象,表示一个射击(线程)
    Shot shot = null;
    Vector<Shot> shots = new Vector<>();

    public Hero(int x, int y) {
        super(x, y);
    }
    //射击
    public void shotEnemyTank() {
        //发多颗子弹怎么办,控制在我们的面板上,最多只有5颗
        if(shots.size() == 1000){
            return;
        }
        //创建 Shot 对象,根据当前Hero对象的位置和方向来创建Shot
        switch (getDirect()){   //得到Hero对象方向
            case 0: //向上
                shot = new Shot(getX() + 20,getY(),0);
                break;
            case 1: //向右
                shot = new Shot(getX() + 60 ,getY() + 20, 1);
                break;
            case 2: //向下
                shot = new Shot(getX() + 20, getY() + 60,2);
                break;
            case 3: //向左
                shot = new Shot(getX(), getY() + 20,3);
                break;
        }

        //把新创建的shot放入到shots
        shots.add(shot);
        //启动我们的Shot线程
        new Thread(shot).start();
    }

}

MyPanel类

package tankgame6;

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

/**
 * Create By 刘鸿涛
 * 2022/1/12 4:41
 * 坦克大战的绘图区域
 */
//为了让Pannel 不停地重绘子弹,需要将 MyPanel实现 Runnable,当做一个线程使用
public class MyPanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    Hero hero = null;
    //定义敌人坦克,放入到Vector集合
    Vector<EnemyTank> enemyTanks = new Vector();
    //定义一个存放Node 对象的Vector,用于恢复敌人坦克的坐标和方向
    Vector<Node> nodes = new Vector<>();

    //定义一个Vector,用于存放炸弹
    //说明,当子弹击中坦克时,加入一个Bomb对象bombs
    Vector<Bomb> bombs = new Vector<>();
    int enemyTanksSize = 8;

    //定义三张炸弹图片,用于显示爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;


    public MyPanel(String key) {
        //判断记录的文件是否存在
        //不存在,只能开启新游戏
        File file = new File(Recorder.getRecordFile());
        if (file.exists()){
            try {
                nodes = Recorder.getNodesAndEnemyTankRec();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("文件不存在,只能开启新的游戏");
            key = "1";
        }

        try {
            nodes = Recorder.getNodesAndEnemyTankRec();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //将MyPanel对象的 enemyTanks 设置给 Recorder 的 enemyTanks
        Recorder.setEnemyTanks(enemyTanks);

        hero = new Hero(500, 500);   //初始化自己的坦克
        hero.setSpeed(50);               //初始化坦克速度

        switch (key){
            case "1": //新游戏
                //初始化敌人坦克
                for (int i = 0; i < enemyTanksSize; i++) {
                    //创建一个敌人的坦克
                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
                    //将 enemyTanks 设置给 enemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(2);
                    //启动敌方坦克线程
                    new Thread(enemyTank).start();
                    //给该enemyTank 加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector 成员
                    enemyTank.shots.add(shot);
                    //启动 shot 对象
                    new Thread(shot).start();
                    //加入坦克
                    enemyTanks.add(enemyTank);
                }
                break;
            case "2":   //继续游戏
                //初始化敌人坦克
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    //创建一个敌人的坦克
                    EnemyTank enemyTank = new EnemyTank(node.getX(),node.getY());
                    //将 enemyTanks 设置给 enemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(node.getDirect());
                    //启动敌方坦克线程
                    new Thread(enemyTank).start();
                    //给该enemyTank 加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector 成员
                    enemyTank.shots.add(shot);
                    //启动 shot 对象
                    new Thread(shot).start();
                    //加入坦克
                    enemyTanks.add(enemyTank);
                }
                break;
            default:
                System.out.println("你的输入有误");
        }


        //初始化图片对象

        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/Bomb1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/Bomb2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/Bomb3.gif"));

        //这里,播放指定的音乐
        new AePlayWave("src\\111.wav").start();
    }

    //编写方法,显示我方击毁敌方坦克的信息
    public void showInfo(Graphics g){

        //画出玩家的总成绩
        g.setColor(Color.black);
        Font font = new Font("宋体",Font.BOLD,25);
        g.setFont(font);

        g.drawString("你击毁的敌方坦克",1000,30);
        drawTank(1000,60,g,0,0);    //画出一个敌方坦克
        g.setColor(Color.BLACK);            //这里需要重新设置成黑色,不然会保持青色
        g.drawString(Recorder.getAllEnemyTankNum() + "",1080,100);      //注意转字符串
    }

    @Override
    public void paint(Graphics g) {

        super.paint(g);
        g.fillRect(0, 0, 1000, 750);    //填充矩形,默认黑色
        showInfo(g);

        //画出坦克 - 封装方法
        //自己的坦克
        if(hero.isLive)
        drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);        //type坦克类型

        //画出hero射击的子弹
//        if (hero.shot != null && hero.shot.isLive) {
//            g.draw3DRect(hero.shot.x, hero.shot.y, 2, 2, false);
//        }

        //将hero的子弹集合 shots,遍历取出绘制
        for (int i = 0; i < hero.shots.size(); i++) {
            Shot shot = hero.shots.get(i);
            if (shot != null && shot.isLive) {
                g.draw3DRect(shot.x, shot.y, 2, 2, false);
            } else {  //如果该shot对象已经无效了,就从shots集合中拿掉
                hero.shots.remove(shot);
            }
        }

        //如果bombs 集合中有对象,就画出
        for (int i = 0; i < bombs.size(); i++) {
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前这个bomb对象的life值去画出对应的图片
            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();
            //如果bomb life 为0,就从bombs的集合中删除
            if (bomb.life == 0) {
                bombs.remove(bomb);
            }
        }
        //画出敌人的坦克,遍历Vector
        for (int i = 0; i < enemyTanks.size(); i++) {
            //取出坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //判断当前坦克是否存活
            if (enemyTank.isLive) {  //当敌人坦克是存活的,才画出该坦克
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
                //画出 enemyTank 所有子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    //取出子弹
                    Shot shot = enemyTank.shots.get(j);
                    //绘制
                    if (shot.isLive) {   //isLive 为 true
                        g.draw3DRect(shot.x, shot.y, 2, 2, false);
                    } else {
                        //从Vector 移除
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }
    }

    //编写方法,画出坦克

    /**
     * @param x      坦克的左上角x坐标
     * @param y      坦克的左上角y坐标
     * @param g      画笔
     * @param direct 坦克方向(上下左右)
     * @param type   坦克类型
     */
    public void drawTank(int x, int y, Graphics g, int direct, int type) {
        switch (type) {
            case 0: //敌人的坦克
                g.setColor(Color.CYAN);
                break;
            case 1: //我的坦克
                g.setColor(Color.yellow);
                break;
        }

        //根据坦克方向,来绘制对应形状坦克
        //
        switch (direct) {
            case 0: //表示向上
                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 1: //向右
                g.fill3DRect(x, y, 60, 10, false);                  //左边轮子
                g.fill3DRect(x, y + 30, 60, 10, false);          //右边轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);    //底盘
                g.fillOval(x + 20, y + 10, 20, 20);               //炮塔
                g.drawLine(x + 30, y + 20, x + 60, y + 20);           //炮筒
                break;

            case 2: //向下
                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 3: //向左
                g.fill3DRect(x, y, 60, 10, false);                  //左边轮子
                g.fill3DRect(x, y + 30, 60, 10, false);          //右边轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);    //底盘
                g.fillOval(x + 20, y + 10, 20, 20);               //炮塔
                g.drawLine(x + 30, y + 20, x, y + 20);           //炮筒
                //炮筒
                break;
            default:
                System.out.println("暂时没有处理");
        }
    }

    //如果我们的坦克可以发射多个子弹
    //在判断我方子弹是否击中敌人坦克时,就需要把我们的子弹集合中的所有子弹遍历,并进行判断
    public void hitEnemyTank() {
        //遍历我们的子弹
        for (int j = 0; j < hero.shots.size(); j++) {
            Shot shot = hero.shots.get(j);

            //判断是否击中了敌人坦克
            if (shot != null && shot.isLive) {   //当前我的子弹存活
                //遍历所有的坦克
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }

    //编写方法,判断我方的子弹是否击中敌人坦克,这里直接换成父类Tank(多态)
    public void hitTank(Shot s, Tank tank) {
        //判断 s 击中坦克
        switch (tank.getDirect()) {
            case 0: //坦克向上
            case 2: //坦克向下
                if (s.x > tank.getX() && s.x < tank.getX() + 40
                        && s.y > tank.getY() && s.y < tank.getY() + 60) {
                    s.isLive = false;
                    tank.isLive = false;
                    //把敌方坦克从集合中remove
                    enemyTanks.remove(tank);
                    //当我方击毁一个地方坦克时,就对数据allEnemyTankNum++
                    //注意:此时的坦克可以是hero也可以是enemyTank
                    if (tank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象,加入到bombs集合中
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1: //坦克向右
            case 3: //坦克向左
                if (s.x > tank.getX() && s.x < tank.getX() + 60
                        && s.y > tank.getY() && s.y < tank.getY() + 40) {
                    s.isLive = false;
                    tank.isLive = false;
                    //将敌方坦克从集合中remove
                    enemyTanks.remove(tank);
                    if (tank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象,加入到bombs集合中
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
        }
    }
    编写方法,击中我放坦克功能
    public void hitHero(){
        //遍历所有的敌人坦克
        for (int i = 0; i < enemyTanks.size(); i++){
            //取出敌人坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //遍历enemyTank 对象的所有子弹
            for (int j = 0; j < enemyTank.shots.size(); j++){
                //取出子弹
                Shot shot = enemyTank.shots.get(j);
                //判断 shot 是否击中我方坦克
                if (hero.isLive && shot.isLive){
                    hitTank(shot,hero);
                }
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //处理键位按下操作
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) {    //上
            //改变坦克方向
            hero.setDirect(0);
            if (hero.getY() > 0) {
                hero.moveUp();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_D) {  //右
            hero.setDirect(1);
            if (hero.getX() < 901) {
                hero.moveRight();
            }
//            hero.setX(hero.getX() + 1);
        } else if (e.getKeyCode() == KeyEvent.VK_S) {  //下

            hero.setDirect(2);
            if (hero.getY() < 620) {
                hero.moveDown();
            }
//            hero.setY(hero.getY() + 1);
        } else if (e.getKeyCode() == KeyEvent.VK_A) {  //左
            hero.setDirect(3);
            if (hero.getX() > 0) {
                hero.moveLeft();
            }
//            hero.setX(hero.getX() - 1);
        }
        if (e.getKeyCode() == KeyEvent.VK_J) {  //发射子弹
            //发射一发子弹情况
//            if (hero.shot == null || hero.shot.isLive == false) {
//                hero.shotEnemyTank();
//            }
            hero.shotEnemyTank();
        }
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {  //每隔10毫秒,重绘区域,刷新绘图区域,子弹就移动
        while (true) {

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断敌人坦克是否击中我们坦克
            hitHero();

            hitEnemyTank();
            this.repaint();
        }

    }
}


Node类

package tankgame6;

/**
 * Create By 刘鸿涛
 * 2022/2/5 16:28
 * 一个Node 对象,表示一个敌人坦克的信息
 */
public class Node {
    private int x;
    private int y;
    private int direct;

    public Node(int x, int y, int 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 int getDirect() {
        return direct;
    }

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

Recorder类

package tankgame6;

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

/**
 * Create By 刘鸿涛
 * 2022/2/5 12:58
 * 该类用于记录相关信息的,和文件交互
 */
public class Recorder {
    //定义变量,记录我方击毁敌人坦克数
    private static int allEnemyTankNum = 0;
    //定义IO对象
    private static FileWriter fw = null;
    private static BufferedWriter bw = null;
    private static BufferedReader br = null;

    //把记录文件保存到src 下
    //private static String recordFile = "d:\\myRecord.txt";
    private static String recordFile = "src\\myRecord.txt";
    //定一个Vector,指向 MyPanel 对象的 敌人坦克Vector
    private static Vector<EnemyTank> enemyTanks = null;
    //定义一个Node 的Vector ,用于保存敌人的信息node
    private static Vector<Node> nodes = new Vector<>();


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

    //返回记录文件路径
    public static String getRecordFile(){
        return recordFile;
    }
    //增加一个方法,用于读取recordFile,恢复相关信息
    //该方法,在继续上局游戏时调用即可
    public static Vector<Node> getNodesAndEnemyTankRec() throws IOException {
        br = new BufferedReader(new FileReader(recordFile));
        allEnemyTankNum = Integer.parseInt(br.readLine());
        //循环读取文件,生成nodes集合
        String line = "";
        while ((line = br.readLine()) != null){
            String []xyd = line.split(" ");
            Node node = new Node(Integer.parseInt(xyd[0]),
                    Integer.parseInt(xyd[1]), Integer.parseInt(xyd[2]));
            nodes.add(node);        //nodes Vector
        }
        if(br != null){
            br.close();
        }
        return nodes;
    }



    //增加一个方法,当游戏退出时,我们将allEnemyTankNum保存到 recordFile
    //对keepRecord 进行升级,保存敌人坦克的坐标和方向

    public static void keepRecord() throws IOException {
        bw = new BufferedWriter(new FileWriter(recordFile));
//        bw.newLine();
        bw.write(allEnemyTankNum + "\r\n");
        //遍历敌人坦克Vector,然后根据情况保存即可
        //OOP,定义一个属性,然后通过setXxx得到敌人Vector
        for (int i = 0; i < enemyTanks.size(); i++){
            //取出敌人坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //建议下面判断下(可以不判断)
            if (enemyTank.isLive){
                //保存该enemyTank信息
                String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
                //写入到文件
                bw.write(record + "\r\n");

            }
        }

        if (bw != null){
            bw.close();
        }
    }
    public static int getAllEnemyTankNum(){
        return allEnemyTankNum;
    }

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

    //当我方坦克击毁一个敌人坦克时,就应当allEnemyTankNum++
    public static void addAllEnemyTankNum(){
        Recorder.allEnemyTankNum++;
    }
}

Shot类

package tankgame6;

/**
 * Create By 刘鸿涛
 * 2022/1/17 5:19
 */
public class Shot implements Runnable{
    int x;  //子弹x坐标
    int y; //子弹y坐标
    int direct = 0; //子弹方向
    int speed = 2;  //子弹速度
    boolean isLive = true;  //子弹是否存活

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

    @Override
    public void run() {     //射击
        while (true){
            //子弹休眠
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //根据方向来改变x,y坐标
            switch (direct){
                case 0://上
                    y -= speed;
                    break;
                case 1://右
                    x += speed;
                    break;
                case 2://下
                    y += speed;
                    break;
                case 3://左
                    x -= speed;
                    break;
            }
            //测试,这里我们输出x,y坐标
//            System.out.println("子弹 x = " + x + " y= " + y);
            //当子弹移动到面板
            if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750)){
                isLive = false;
                break;
            }
        }
    }
}

Tank类

package tankgame6;

/**
 * Create By 刘鸿涛
 * 2022/1/12 4:38
 */
public class Tank {
    private int x;  //坦克的横坐标
    private int y;  //坦克的纵坐标
    private int direct; //坦克方向返回值
    private int speed = 10;  //坦克的速度

    //给hero坦克使用的isLive属性
    boolean isLive = true;

    public int getDirect() {
        return direct;
    }

    public void moveUp(){
        y -= speed;
    }
    public void moveRight(){
        x += speed;
    }
    public void moveDown(){
        y += speed;
    }
    public void moveLeft(){
        x -= speed;
    }

    public int getSpeed() {
        return speed;
    }

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

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

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

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

TankGame06类

package tankgame6;

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

/**
 * Create By 刘鸿涛
 * 2022/1/12 4:45
 */
public class TankGame06 extends JFrame {
    //定义MyPanel
    MyPanel mp = null;
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {

        TankGame06 taoTankGame01 = new TankGame06();
    }

    public TankGame06() {
        System.out.println("请输入选择 1:新游戏  、 2:继续上局");
        String key = sc.next();
        mp = new MyPanel(key);
        //将mp 放入到Thread,并启动
        Thread thread = new Thread(mp);
        thread.start();
        this.add(mp);   //把面板(就是游戏的绘图区域)
        this.setSize(1300, 950);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //点击x 关闭程序
        this.setVisible(true);  //显示
        this.setLocationRelativeTo(null);

        this.addKeyListener(mp);

        //在JFrame中增加相应关闭窗口的处理
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("监听到关闭窗口");
                try {
                    Recorder.keepRecord();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                //退出
                System.exit(0);
            }
        });
    }
}


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼鬼骑士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值