Java初学笔记28-【坦克游戏0.2——java部分代码】

Java初学笔记28

坦克游戏部分代码0.2

1.Tank

package project.tankgame05;

/**
 * @ClassName: Tank
 * @Description: 坦克父类
 */
public class Tank {
    private int x; //坦克的横坐标
    private int y; //坦克的纵坐标
    private int direction; //坦克方向 0123 上下左右
    private int speed = 3; //坦克速度

    /**
     * 坦克存活状态
     */
    private boolean t_sur = true;

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

    /**
     * 坦克上移动方法
     */
    public void moveUp(){
        y -= speed;
    }

    /**
     * 坦克右移动方法
     */
    public void moveRight(){
        x += speed;
    }

    /**
     * 坦克下移动方法
     */
    public void moveDown(){
        y += speed;
    }

    /**
     * 坦克左移动方法
     */
    public void moveLeft(){
        x -= speed;
    }

    /**
     * 坦克开火的方法
     */
    public void fire(){

    }

    public int getDirection() {
        return direction;
    }

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

    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 getSpeed() {
        return speed;
    }

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

    public boolean isT_sur() {
        return t_sur;
    }

    public void setT_sur(boolean t_sur) {
        this.t_sur = t_sur;
    }
}

2.MyTank

package project.tankgame05;


import java.util.Vector;

/**
 * @ClassName: MyTank
 * @Description: 自己的坦克
 */
public class MyTank extends Tank {  //继承父类坦克

    /**
     * 属性:自己的子弹线程
     */
    MyBullet myBullet = null;

    /**
     * Vector集合:存储自己的子弹集合
     */
    Vector<MyBullet> myBullets = new Vector<>();

    /**
     * 自己的坦克-构造器
     */
    public MyTank(int x, int y) {
        super(x, y);
    }

    /**
     * 方法:自己坦克开火。
     * 实例化并启动自己的子弹线程
     */
    @Override
    public void fire() {
        //游戏面板控制自己的子弹最多为8个
        if(myBullets.size() == 8){
            return;
        }
        switch (getDirection()){
            case 0:
                myBullet = new MyBullet(getX()+20,getY(),getDirection());
                break;
            case 1:
                myBullet = new MyBullet(getX()+60,getY()+20,getDirection());
                break;
            case 2:
                myBullet = new MyBullet(getX()+20,getY()+60,getDirection());
                break;
            case 3:
                myBullet = new MyBullet(getX(),getY()+20,getDirection());
                break;
        }
        //将自己的子弹线程加入集合
        myBullets.add(myBullet);
        //启动子弹线程
        new Thread(myBullet).start();
    }

}

3.EnemyTank

package project.tankgame05;

import java.util.Vector;

/**
 * @ClassName: EnemyTank
 * @Description: 敌人的坦克线程
 */
public class EnemyTank extends Tank implements Runnable{
    /**
     * Vector集合:每个敌人坦克用集合存放自己的多个子弹线程
     */
    Vector<EnemyBullet> e_Bullets_Ve = new Vector<>();


    /**
     * Vector集合:每个敌人坦克用集合存放其他的敌人坦克线程(该集合内也有自己的)
     */
    Vector<EnemyTank> enemyTanks = new Vector<>();

    /**
     * 可以在TankPanel类中调用该方法,在每个敌人内部初始化多个敌人坦克线程
     * @param enemyTanks
     */
    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        this.enemyTanks = enemyTanks;
    }

    /**
     * 判断当前坦克是否与其他坦克重叠
     * @return
     */
    public boolean isTouchEnemyTank(){
        //遍历取出每一个敌人坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            //因为该集合中有自己的的坦克线程,自己坦克不能和自己坦克比较
            if(this != enemyTank){
                //把每个坦克看成60*60的矩形,判断两个坦克中心是否小于60
                double len = Math.sqrt((this.getX() - enemyTank.getX())*(this.getX() - enemyTank.getX())+
                        (this.getY() - enemyTank.getY())*(this.getY() - enemyTank.getY()));
                if(len <= 70){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 敌人坦克的构造器
     * @param x
     * @param y
     */
    public EnemyTank(int x, int y) {
        super(x, y);
    }

    @Override
    public void run() {
        while (true){

            //判断此时敌人坦克是否存活,以及坦克里面的子弹线程是否还有
            //使敌人坦克可以发射5颗子弹
            if(isT_sur() && e_Bullets_Ve.size() < 5){

                EnemyBullet bul = null;
                //根据此时坦克的位置创建敌人子弹线程
                switch (getDirection()){
                    case 0:
                        bul = new EnemyBullet(getX()+20,getY(),0);
                        break;
                    case 1:
                        bul = new EnemyBullet(getX()+60,getY()+20,1);
                        break;
                    case 2:
                        bul = new EnemyBullet(getX()+20,getY()+60,2);
                        break;
                    case 3:
                        bul = new EnemyBullet(getX(),getY()+20,3);
                        break;
                }
                //将敌人子弹线程加入集合
                e_Bullets_Ve.add(bul);
                //启动敌人子弹线程
                new Thread(bul).start();
            }
            //敌人坦克随机移动
            switch (getDirection()){
                case 0:
                    for (int i = 0; i < 10; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if(getY() > 0 && !isTouchEnemyTank()){
                            moveUp();
                        }
                    }
                    break;
                case 1:
                    for (int i = 0; i < 10; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if(getX() + 60 < 1000  && !isTouchEnemyTank()){
                            moveRight();
                        }
                    }
                    break;
                case 2:
                    for (int i = 0; i < 10; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if(getY() + 60 < 750  && !isTouchEnemyTank()){
                            moveDown();
                        }
                    }
                    break;
                case 3:
                    for (int i = 0; i < 10; i++) {
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if(getX() > 0 && !isTouchEnemyTank()){
                            moveLeft();
                        }
                    }
                    break;
            }

            //为敌人坦克设置随机方向
            setDirection((int)(Math.random()*4));
            //敌人坦克死亡,结束线程
            if(!isT_sur()){
                System.out.println("敌人坦克线程: "+ Thread.currentThread().getName()
                        +" 已经结束");
                break;
            }
        }
    }
}

4.Bullet

package project.tankgame05;

/**
 * @Package: project.tankgame03
 * @ClassName: Bullet
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/10/28 9:50
 * @Description:  子弹父类
 */
public class Bullet {
    /**
     * 子弹的b_x位置
     */
    private int b_x;
    /**
     * 子弹的b_y位置
     */
    private int b_y;
    /**
     * 子弹的方向 0123 上右下左
     */
    private int b_direction;
    /**
     * 子弹的速度  默认3
     */
    private int b_speed = 3;
    /**
     * 子弹存活状态
     */
    private boolean b_sur = true;

    /**
     * 构造函数:初始化子弹的原始位置以及方向
     * @param b_x
     * @param b_y
     * @param b_direction
     */
    public Bullet(int b_x, int b_y, int b_direction) {
        this.b_x = b_x;
        this.b_y = b_y;
        this.b_direction = b_direction;
    }

    /**
     * 获取子弹x坐标
     * @return
     */
    public int getB_x() {
        return b_x;
    }

    /**
     * 设置子弹x坐标
     * @return
     */
    public void setB_x(int b_x) {
        this.b_x = b_x;
    }

    /**
     * 获取子弹y坐标
     * @return
     */
    public int getB_y() {
        return b_y;
    }

    /**
     * 设置子弹y坐标
     * @return
     */
    public void setB_y(int b_y) {
        this.b_y = b_y;
    }

    /**
     * 获取子弹方向
     * @return
     */
    public int getB_direction() {
        return b_direction;
    }

    /**
     * 设置获取子弹方向
     * @return
     */
    public void setB_direction(int b_direction) {
        this.b_direction = b_direction;
    }


    /**
     * 获取子弹速度
     * @return
     */
    public int getB_speed() {
        return b_speed;
    }


    /**
     * 设置子弹速度
     * @return
     */
    public void setB_speed(int b_speed) {
        this.b_speed = b_speed;
    }

    /**
     * 获取子弹存活状态
     * @return
     */
    public boolean isB_sur() {
        return b_sur;
    }

    /**
     * 设置子弹存活状态
     * @return
     */
    public void setB_sur(boolean b_sur) {
        this.b_sur = b_sur;
    }
}

5.MyBullet

package project.tankgame05;

/**
 * @Package: project.tankgame03
 * @ClassName: MyBullet
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/10/28 9:57
 * @Description:  我的子弹线程
 */
public class MyBullet extends Bullet implements Runnable{

    /**
     * 构造函数:初始化我的子弹原始位置以及方向
     *
     * @param b_x
     * @param b_y
     * @param b_direction
     */
    public MyBullet(int b_x, int b_y, int b_direction) {
        super(b_x, b_y, b_direction);
    }

    @Override
    public void run() {
        while (true){
            //休眠50毫秒
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断自己的子弹方向,沿着这一方向移动
            switch (getB_direction()){
                case 0:
                    setB_y(getB_y()-getB_speed());
                    break;
                case 1:
                    setB_x(getB_x()+getB_speed());
                    break;
                case 2:
                    setB_y(getB_y()+getB_speed());
                    break;
                case 3:
                    setB_x(getB_x()-getB_speed());
                    break;
            }
            //System.out.println("我的子弹坐标"+getB_x()+" "+getB_y());

            //如果自己的子弹超出世界边界,或者生命状态在其他地方被设置成false,则
            //设置子弹线程的生命状态为false,并且结束线程
            if(!(getB_x()>=0 && getB_x()<=1000 && getB_y()>=0 &&getB_y()<=750)
                    || isB_sur() == false){
                setB_sur(false);
                System.out.println("我的子弹线程 "+ Thread.currentThread().getName() +" 已经结束");
                break;
            }
        }
    }
}

6.EnemyBullet

package project.tankgame05;

/**
 * @Package: project.tankgame03
 * @ClassName: EnemyBullet
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/10/28 14:10
 * @Description:
 */
public class EnemyBullet extends Bullet implements Runnable{
    /**
     * 构造函数:初始化敌人子弹的原始位置以及方向
     *
     * @param b_x
     * @param b_y
     * @param b_direction
     */
    public EnemyBullet(int b_x, int b_y, int b_direction) {
        super(b_x, b_y, b_direction);
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //设置敌人子弹朝着某一方向移动
            switch (getB_direction()){
                case 0:
                    setB_y(getB_y()-getB_speed());
                    break;
                case 1:
                    setB_x(getB_x()+getB_speed());
                    break;
                case 2:
                    setB_y(getB_y()+getB_speed());
                    break;
                case 3:
                    setB_x(getB_x()-getB_speed());
                    break;
            }
            //System.out.println("敌人子弹坐标"+getB_x()+" "+getB_y());
            if(!(getB_x()>=0 && getB_x()<=1000 && getB_y()>=0 &&getB_y()<=750)
                    || !isB_sur()){
                setB_sur(false);
                System.out.println("敌人子弹线程 "+ Thread.currentThread().getName() +" 已经结束");
                break;
            }
        }
    }
}

7.Bomb

package project.tankgame05;

/**
 * @Package: project.tankgame03
 * @ClassName: Bomb
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/10/29 9:41
 * @Description: 炸弹特效类
 */
public class Bomb {
    /**
     * 炸弹的X坐标
     */
    int x;

    /**
     * 炸弹的Y坐标
     */
    int y;

    /**
     * 炸弹的生命周期
     */
    int life = 9;

    /**
     * 炸弹的存活状态
     */
    boolean isLive = true;

    /**
     * 炸弹构造器,初始化X,Y坐标
     * @param x
     * @param y
     */
    public Bomb(int x, int y) {
        this.x = x;
        this.y = y;
    }

    /**
     * 使炸弹图片生命值逐渐减少
     */
    public void cutLife(){
        if(isLive && life>=0){
            life--;
        }else{
            isLive = false;
        }
    }
}

8.Recorder

package project.tankgame05;

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

/**
 * @Package: project.tankgame05
 * @ClassName: Recorder
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/11/5 11:12
 * @Description: 与文件进行交互
 */
public class Recorder {
    /**
     * 击毁敌人坦克数量
     */
    private static int killEneTankNum = 0;

    /**
     * 定义输出文件对象
     */
    private static BufferedWriter bw = null;

    /**
     * 定义输入文件对象
     */
    private static BufferedReader br = null;

    /**
     * 定义存放敌人数量的文件路径
     */
    private static String filePath = "src\\record.txt";
    /**
     * 定义存放存活敌人的文件路径
     */
    private static String filePath1 = "src\\record2.txt";

    /**
     * 使击毁的敌人坦克数量就加1
     */
    public static void addkillEneTankNum(){
        Recorder.killEneTankNum++;
    }

    /**
     * 集合:记录敌人坦克信息
     */
    private static Vector<EnemyTank> enemyTanks = null;

    /**
     * 定义我的坦克
     */
    private static MyTank mytank = null;

    /**
     * 集合:记录恢复的坦克信息
     */
    private static Vector<Node> nodes = new Vector<>();

    /**
     * 初始化敌人坦克线程
     * @param enemyTanks
     */
    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    /**
     * 初始化自己坦克
     * @param mytank
     */
    public static void setMytank(MyTank mytank) {
        Recorder.mytank = mytank;
    }

    /**
     * 关闭游戏时将击毁敌人坦克的数量写入文件
     */
    public static void storekillEneTankNum(){
        try {
            bw = new BufferedWriter(new FileWriter(filePath));
//            bw.write(killEneTankNum+"\r\n");
            bw.write(killEneTankNum+"");
            bw.newLine();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bw != null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭游戏时将存活的敌人与自己的坦克写入文件
     */
    public static void storeAliveEneTank(){
        try {
            bw = new BufferedWriter(new FileWriter(filePath1));
            //存入敌人坦克
            for (int i = 0; i < enemyTanks.size(); i++) {
                //取出每一个坦克
                EnemyTank enemyTank = enemyTanks.get(i);
                if(enemyTank.isT_sur()){
                    String str = enemyTank.getX() + " " + enemyTank.getY()
                            + " " + enemyTank.getDirection();
                    //bw.write(str+"\r\n");
                    bw.write(str);
                    bw.newLine();
                }
            }
            //存入自己的坦克
            if(mytank!= null && mytank.isT_sur()){
                String str = mytank.getX() + " " + mytank.getY()
                        + " " + mytank.getDirection();
                bw.write(str);
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(bw!=null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 恢复读取已经击杀的敌人坦克数量
     * @return
     */
    public static void readKillTankNum(){
        try {
            br = new BufferedReader(new FileReader(filePath));
            Recorder.killEneTankNum = Integer.parseInt(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 恢复坦克位置方向信息
     * @return
     */
    public static Vector<Node> readTank(){
        try {
            br = new BufferedReader(new FileReader(filePath1));
            String tanks = null;
            while ((tanks = br.readLine()) != null){
                String[] s = tanks.split(" ");
                Node node = new Node(Integer.parseInt(s[0])
                        , Integer.parseInt(s[1])
                        , Integer.parseInt(s[2]));
                nodes.add(node);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return nodes;
        }
    }

    public static int getKillEneTankNum() {
        return killEneTankNum;
    }

    public static void setKillEneTankNum(int killEneTankNum) {
        Recorder.killEneTankNum = killEneTankNum;
    }
}

9.Node

package project.tankgame05;

/**
 * @Package: project.tankgame05
 * @ClassName: Node
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2021/11/7 9:52
 * @Description: Node节点恢复保存的坦克
 */
public class Node {
    /**
     * 用于保存恢复的坦克的x,y,方法
     */
    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;
    }
}

10.AePlayWave

package project.tankgame05;

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

/**
 *  wav音频播放线程
 */
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();
        }

    }
}

11.TankPanel

package project.tankgame05;

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: TankPanel
 * @Description: 坦克游戏区域————“画板”
 */
public class TankPanel extends JPanel implements KeyListener,Runnable{

    /**
     * 定义我的坦克
     */
    MyTank mytank = null;

    /**
     * Vector集合:集合中存放敌人坦克
     */
    Vector<EnemyTank> enemyTanks = new Vector<>();

    /**
     * Vector集合:集合中存放恢复的坦克
     */
    Vector<Node> nodes = new Vector<>();

    /**
     * 敌人坦克数量
     */
    int enemyTankNum = 5;

    /**
     * Vector集合:存放炸弹特效
     * 当自己的子弹击中敌人坦克时,加入一个炸弹
     */
    Vector<Bomb> bombs = new Vector<>();

    /**
     * 声明3个存放炸弹特效的变量image1,image2,image3
     */
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    /**
     * “画板”构造器
     */
    public TankPanel(String key){
        File file1 = new File("src\\record.txt");
        File file2 = new File("src\\record2.txt");
        if(!file1.exists() && !file2.exists()){
            key = "1";
            System.out.println("读取旧游戏失败,开启新游戏");
        }
        switch (key){
            case "1": //1: 开始新游戏
                //初始化我的坦克
                mytank = new MyTank(100,600);
                //初始化敌人坦克,默认朝下
                for (int i = 0; i < enemyTankNum; i++) {
                    EnemyTank enemyTank = new EnemyTank(150 * (i + 1), 0);
                    //初始化敌人的子弹
                    EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
                            enemyTank.getY() + 60, 2);
                    //把敌人子弹加入到集合中
                    enemyTank.e_Bullets_Ve.add(enemyBullet);
                    //启动敌人子弹线程
                    new Thread(enemyBullet).start();
                    enemyTank.setDirection(2);
                    //把敌人坦克加入到集合中
                    enemyTanks.add(enemyTank);
                    //将 enemyTanks集合 赋值给每个敌人坦克
                    enemyTank.setEnemyTanks(enemyTanks);
                    //启动敌人坦克
                    new Thread(enemyTank).start();
                }
                //将敌人坦克线程初始化到Recorder
                Recorder.setEnemyTanks(enemyTanks);
                //将自己的坦克初始化到Recorder
                Recorder.setMytank(mytank);
                break;
            case "2": //2: 继续上局游戏
                //恢复击杀敌人信息
                Recorder.readKillTankNum();
                //恢复坦克信息
                nodes = Recorder.readTank();
                if(nodes == null){
                    break;
                }
                //核对坦克数量信息
                int hedui = (Recorder.getKillEneTankNum() + nodes.size());
                if(hedui != enemyTankNum){
                    //初始化我的坦克
                    Node node = nodes.get(this.nodes.size() - 1);
                    mytank = new MyTank(node.getX(),node.getY());
                    mytank.setDirection(node.getDirect());
                    //初始化敌人坦克
                    for (int i = 0; i < nodes.size()-1; i++) {
                        //取出敌人坦克节点信息
                        Node node1 = nodes.get(i);
                        EnemyTank enemyTank = new EnemyTank(node1.getX(),node1.getY());
                        //初始化敌人的子弹
                        EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
                                enemyTank.getY() + 60, node1.getDirect());
                        //把敌人子弹加入到集合中
                        enemyTank.e_Bullets_Ve.add(enemyBullet);
                        //启动敌人子弹线程
                        new Thread(enemyBullet).start();
                        //设置敌人坦克方向
                        enemyTank.setDirection(node1.getDirect());
                        //把敌人坦克加入到集合中
                        enemyTanks.add(enemyTank);
                        //将 enemyTanks集合 赋值给每个敌人坦克
                        enemyTank.setEnemyTanks(enemyTanks);
                        //启动敌人坦克
                        new Thread(enemyTank).start();
                    }
                    //将敌人坦克线程初始化到Recorder
                    Recorder.setEnemyTanks(enemyTanks);
                    //将自己的坦克初始化到Recorder
                    Recorder.setMytank(mytank);
                }else{
                    //初始化敌人坦克
                    for (int i = 0; i < nodes.size(); i++) {
                        //取出敌人坦克节点信息
                        Node node1 = nodes.get(i);
                        EnemyTank enemyTank = new EnemyTank(node1.getX(),node1.getY());
                        //初始化敌人的子弹
                        EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
                                enemyTank.getY() + 60, node1.getDirect());
                        //把敌人子弹加入到集合中
                        enemyTank.e_Bullets_Ve.add(enemyBullet);
                        //启动敌人子弹线程
                        new Thread(enemyBullet).start();
                        //设置敌人坦克方向
                        enemyTank.setDirection(node1.getDirect());
                        //把敌人坦克加入到集合中
                        enemyTanks.add(enemyTank);
                        //将 enemyTanks集合 赋值给每个敌人坦克
                        enemyTank.setEnemyTanks(enemyTanks);
                        //启动敌人坦克
                        new Thread(enemyTank).start();
                    }
                    //将敌人坦克线程初始化到Recorder
                    Recorder.setEnemyTanks(enemyTanks);
                    //将自己的坦克初始化到Recorder
                    Recorder.setMytank(mytank);
                }
                break;
            default:
                System.out.println("输入有误~~");
        }
        //初始化炸弹特效图片
        image1 = Toolkit.getDefaultToolkit()
                .getImage(TankPanel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit()
                .getImage(TankPanel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit()
                .getImage(TankPanel.class.getResource("/bomb_3.gif"));

        //播放音乐
        new AePlayWave("src\\111.wav").start();
    }

    /**
     * 显示玩家成绩
     */
    public void showInfor(Graphics g){
        g.setColor(Color.black);
        Font font = new Font("楷体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("已击毁敌人坦克",1020,30);

        drawTank(1020,60,g,0,1);
        g.setColor(Color.black);
        g.drawString(Recorder.getKillEneTankNum()+"",1080,100);
    }

    /**
     * paint绘画方法
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //默认黑色矩形背景
        g.setColor(Color.BLACK);
        //默认黑色矩形1000 × 750
        g.fillRect(0,0,1000,750);

        //绘制成绩
        showInfor(g);
        //绘制-自己的坦克
        if(mytank != null && mytank.isT_sur()){
            drawTank(mytank.getX(),mytank.getY(),g,mytank.getDirection(),0);
        }

        //绘制敌人的坦克
        //判断敌人坦克集合不为空
        if(enemyTanks != null){
            //遍历敌人坦克集合
            for (int i = 0; i < enemyTanks.size(); i++) {
                //取出每个敌人坦克
                EnemyTank enemyTank = enemyTanks.get(i);
                //判断每个坦克的生命状态
                if(enemyTank.isT_sur()) {
                    drawTank(enemyTank.getX(), enemyTank.getY(), g,
                            enemyTank.getDirection(), 1);
                }else{
                    //坦克的生命状态为false,除了不绘画之外,还需要在
                    //集合中移除
                    enemyTanks.remove(enemyTank);
                }
            }
        }

        //绘制自己的子弹
        //遍历自己的子弹集合
        if(mytank != null && mytank.myBullets != null){
            for (int i = 0; i < mytank.myBullets.size(); i++) {
                //取出每个子弹
                MyBullet myBullet = mytank.myBullets.get(i);
                //判断子弹的生命状态
                if(myBullet != null && myBullet.isB_sur()){
                    g.setColor(Color.RED);
                    g.fillOval(myBullet.getB_x(),myBullet.getB_y(),5,5);
                }else{
                    mytank.myBullets.remove(myBullet);
                }
            }
        }

        //绘制敌人的子弹
        //判断敌人坦克集合不为空
        if(enemyTanks != null ){
            //遍历敌人坦克集合
            for (int i = 0; i < enemyTanks.size(); i++) {
                //取出每个敌人坦克
                EnemyTank enemyTank = enemyTanks.get(i);
                //判断敌人坦克的子弹集合不为空
                if(enemyTank.e_Bullets_Ve != null){
                    //遍历敌人坦克的子弹集合
                    for (int j = 0; j < enemyTank.e_Bullets_Ve.size(); j++) {
                        //取出每个敌人坦克的子弹
                        EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(j);
                        //判断每个敌人子弹的状态
                        if(enemyBullet.isB_sur()){
                            g.setColor(Color.yellow);
                            g.fillOval(enemyBullet.getB_x(), enemyBullet.getB_y(),
                                    5, 5);
                        }else{
                            //敌人子弹的生命状态为false,除了不绘画之外
                            // 还需要在集合中移除
                            enemyTank.e_Bullets_Ve.remove(enemyBullet);
                        }
                    }
                }
            }
        }

        //绘制炸弹特效
        //遍历炸弹集合
        for (int i = 0; i < bombs.size(); i++) {
            //取出每一个炸弹
            Bomb bomb = bombs.get(i);
            if(bomb.isLive){
                //分阶段绘制炸弹
                if(bomb.life > 6){
                    g.drawImage(image1,bomb.x,bomb.y,50,50,this);
                    bomb.cutLife();
                }else if(bomb.life > 3){
                    g.drawImage(image2,bomb.x,bomb.y,50,50,this);
                    bomb.cutLife();
                }else{
                    g.drawImage(image3,bomb.x,bomb.y,50,50,this);
                    bomb.cutLife();
                }
            }else{
                bombs.remove(bomb);
            }
        }
    }

    /**
     * 画坦克的方法
     * @param x 坦克左上角的x坐标
     * @param y 坦克右上角的x坐标
     * @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.pink);
                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,y+20,x+30,y+20);  //坦克炮筒
                break;
        }
    }

    /**
     * 字符输出事件方法
     * @param e
     */
    @Override
    public void keyTyped(KeyEvent e) {

    }

    /**
     * 键盘按下事件方法
     * WDSA 坦克的方向:上右下左
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W){
            mytank.setDirection(0);  //更改坦克的方向
            if(mytank.getY()>0){
                mytank.moveUp(); //使坦克向上走
            }
        }else if(e.getKeyCode() == KeyEvent.VK_D){
            mytank.setDirection(1);
            if(mytank.getX()+60<1000){
                mytank.moveRight(); //使坦克向右走
            }
        }else if(e.getKeyCode() == KeyEvent.VK_S){
            mytank.setDirection(2);
            if(mytank.getY()+60<750){
                mytank.moveDown(); //使坦克向下走
            }
        }else if(e.getKeyCode() == KeyEvent.VK_A){
            mytank.setDirection(3);
            if(mytank.getX()>0){
                mytank.moveLeft(); //使坦克向左走
            }
        }
        //按下J键 子弹射击
        if(mytank != null && mytank.isT_sur()){
            if(e.getKeyCode() == KeyEvent.VK_J){
                mytank.fire();
            }
        }
        this.repaint();
    }

    /**
     * 键盘弹起事件方法
     * @param e
     */
    @Override
    public void keyReleased(KeyEvent e) {

    }

    /**
     * “画板”刷新
     */
    @Override
    public void run() {
        while (true){
            //画板隔0.1秒刷新一次
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            killEnenmy();
            killMyTank();
            this.repaint();
        }
    }

    /**
     * 方法:自己的子弹打敌人坦克
     * 设置自己的子弹和敌人坦克的生命状态
     * @param myBullet  自己的子弹
     * @param enemyTank  敌人坦克
     */
    public void bitEnenmy(MyBullet myBullet, EnemyTank enemyTank){
        switch (enemyTank.getDirection()){
            case 0:
            case 2:
                if(myBullet.getB_x() >= enemyTank.getX() && myBullet.getB_x() <= enemyTank.getX()+40
                        && myBullet.getB_y() >= enemyTank.getY() && myBullet.getB_y() <= enemyTank.getY()+60 ){
                    //子弹状态:FALSE
                    myBullet.setB_sur(false);
                    //坦克状态:FALSE
                    enemyTank.setT_sur(false);
                    for (int i = 0; i < enemyTank.e_Bullets_Ve.size(); i++) {
                        EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(i);
                        enemyBullet.setB_sur(false);
                    }
                    //敌人坦克被击毁的数量加1
                    Recorder.addkillEneTankNum();
                    //把炸弹特效放在敌人位置处,并加入集合
                    bombs.add(new Bomb(enemyTank.getX(),enemyTank.getY()));
                }
                break;
            case 1:
            case 3:
                if(myBullet.getB_x() >= enemyTank.getX() && myBullet.getB_x() <= enemyTank.getX()+60
                        && myBullet.getB_y() >= enemyTank.getY() && myBullet.getB_y() <= enemyTank.getY()+40 ){
                    //子弹状态:FALSE
                    myBullet.setB_sur(false);
                    //坦克状态:FALSE
                    enemyTank.setT_sur(false);
                    for (int i = 0; i < enemyTank.e_Bullets_Ve.size(); i++) {
                        EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(i);
                        enemyBullet.setB_sur(false);
                    }
                    //敌人坦克被击毁的数量加1
                    Recorder.addkillEneTankNum();
                    //把炸弹特效放在敌人位置处,并加入集合
                    bombs.add(new Bomb(enemyTank.getX(),enemyTank.getY()));
                }
                break;
        }
    }

    /**
     * 取出自己的子弹集合与敌人坦克进行遍历看是否击中
     */
    public void killEnenmy(){
        //遍历自己的坦克子弹,取出每个子弹
        for (int i = 0; i < mytank.myBullets.size(); i++) {
            MyBullet myBullet = mytank.myBullets.get(i);
            //判断自己的子弹打中敌人
            for (int j = 0; j < enemyTanks.size(); j++) {
                if (enemyTanks != null && myBullet!= null){
                    EnemyTank enemyTank = enemyTanks.get(j);
                    bitEnenmy(myBullet,enemyTank);
                }
            }
        }
    }

    /**
     * 方法:敌人的子弹打自己坦克
     * 设置敌人的子弹和自己人坦克的生命状态
     * @param enemyBullet  敌人的子弹
     * @param mytank  自己的坦克
     */
    public void bitMyTank(EnemyBullet enemyBullet, MyTank mytank){
        if(mytank != null && mytank.isT_sur()) {
            switch (mytank.getDirection()) {
                case 0:
                case 2:
                    if (enemyBullet.getB_x() >= mytank.getX() && enemyBullet.getB_x() <= mytank.getX() + 40
                            && enemyBullet.getB_y() >= mytank.getY() && enemyBullet.getB_y() <= mytank.getY() + 60) {
                        //子弹状态:FALSE
                        enemyBullet.setB_sur(false);
                        //坦克状态:FALSE
                        mytank.setT_sur(false);
                        for (int i = 0; i < mytank.myBullets.size(); i++) {
                            MyBullet myBullet = mytank.myBullets.get(i);
                            myBullet.setB_sur(false);
                        }
                        //把炸弹特效放在自己位置处,并加入集合
                        bombs.add(new Bomb(mytank.getX(), mytank.getY()));
                    }
                    break;
                case 1:
                case 3:
                    if (enemyBullet.getB_x() >= mytank.getX() && enemyBullet.getB_x() <= mytank.getX() + 60
                            && enemyBullet.getB_y() >= mytank.getY() && enemyBullet.getB_y() <= mytank.getY() + 40) {
                        //子弹状态:FALSE
                        enemyBullet.setB_sur(false);
                        //坦克状态:FALSE
                        mytank.setT_sur(false);
                        for (int i = 0; i < mytank.myBullets.size(); i++) {
                            MyBullet myBullet = mytank.myBullets.get(i);
                            myBullet.setB_sur(false);
                        }
                        //把炸弹特效放在自己位置处,并加入集合
                        bombs.add(new Bomb(mytank.getX(), mytank.getY()));
                    }
                    break;
            }
        }
    }

    /**
     * 取出敌人的子弹与自己坦克遍历,看是否击中自己的坦克
     */
    public void killMyTank(){
        //先遍历敌人的坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            //取出每个敌人坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //遍历每个敌人坦克里面的每个子弹线程
            for (int j = 0; j < enemyTank.e_Bullets_Ve.size(); j++) {
                EnemyBullet bullet = enemyTank.e_Bullets_Ve.get(j);
                bitMyTank(bullet,mytank);
            }
        }
    }
}

12.TankGame05

package project.tankgame05;

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

/**
 * @ClassName: TankGame05
 * @Description: 坦克游戏5.0框架
 */
public class TankGame05 extends JFrame {

    TankPanel tankPanel01 = null; //先定义一个空的1.0“画板”

    public static void main(String[] args) {
        TankGame05 tankGame01 = new TankGame05();
    }

    /**
     * 构造器
     */
    public TankGame05(){
        System.out.println("1: 开始新游戏\r\n2: 继续上局游戏");
        Scanner scanner = new Scanner(System.in);
        String next = scanner.next();
        tankPanel01 = new TankPanel(next); //初始化1.0“画板”
        this.add(tankPanel01);  //添加1.0“画板”
        this.setSize(1300,850); //设置“画板”大小
        this.setVisible(true); //设置“画板”可见
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //点×关闭
        this.addKeyListener(tankPanel01);
        new Thread(tankPanel01).start();

        //Windows窗口关闭监听事件
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("游戏关闭,数据正在存档中......");
                Recorder.storekillEneTankNum();
                Recorder.storeAliveEneTank();
                System.exit(0);
            }
        });
    }


}

上一篇:Java笔试题库之选题题篇(61-140题)


下一篇:Django 学习笔记之一 环境搭建