b站韩顺平老师的坦克大战

一.主要的几个类

  1. Mypanel  
  2. WwyTankGame01
  3. AnemyTank //写代码时候把单词拼错了哈哈不好意思
  4. Bomb
  5. Recorder
  6. Node
  7. Shot
  8. Tank
  9. Hero

二.功能实现的思路

1.画出敌我坦克

2.实现发射子弹

3.击中时坦克爆炸和消失

4.解决出界问题

5.解决碰撞问题

三.功能的实现

1. Mypanel 

这个类是坦克的大战的绘图区域,实现功能最也最为的复杂,这个类用到了java的绘图

 简单的学习这个绘图原理的使用

public class DrawCircle extends JFrame{//JFrame对应的窗口,可以理解为一个画框

    //定义一个面板
    private MyPanel mp = null;

    public static void main(String[] args) {
        new DrawCircle();
    }

    public DrawCircle(){
        //初始化面板
        mp = new MyPanel();//构造器
        //把我们的面板放入我们的窗口
        this.add(mp);
        //设置窗口的大小
        this.setSize(400,300);
        //可以显示
        this.setVisible(true);
        //当点击窗口的小x,程序完全退出
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
//1.首先定义一个面板MyPanel,继承JPanel类,画图形,就在面板上画
class MyPanel extends JPanel{
    //说明:
    //1.MyPanel 对象就是一个画板
    //2.Graphics g 把g理解为一个画笔
    //3.Graphics 提供了很多绘图的方法

    @Override
    public void paint(Graphics g){//绘图方法
        super.paint(g);
        //画出一个圆
        g.drawOval(10,10,10,100);
    }
}

package tankgame3;

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

/**
 * 坦克大战的绘图区域
 */
//为了监听键盘事件,实现KeyLister
public class MyPanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    private int hitNums;


    private Hero hero = null;

    private Boolean flag = false;

    //定义敌人的坦克
    Vector anemyTanks = new Vector<>();

    //定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
    Vector nodes = Recorder.getNodesAndAanemyNums();

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

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

    public MyPanel(String key){

        //传入 anemyTanks 并记录
        Recorder.setAnemyTanks(anemyTanks);

        //初始化自己坦克
        hero = new Hero(50,600);

        // 判断是重新开始,还是继续游戏
        switch (key){
            case "1"://重新开始

                //
                Recorder.setHitTankNums(0);

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



        //初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/3.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/2.png"));
        image3  = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/1.png"));


    }

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

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

        g.drawString("你累计击败敌方坦克", 810,30 );
        drawTank(820, 60, g, 0, 0);//画出个敌方坦克
        g.setColor(Color.black);//这里需要重新获取黑色
        g.drawString(String.valueOf(Recorder.getHitTankNums()), 900, 100);
    }

    @Override
    public void
    paint(Graphics g) {
        super.paint(g);

        g.fillRect(0,0,800, 750);//填充矩形,默认黑色

        showHitInfo(g);

        if (hero != null && hero.isLife()){
            //画出坦克--封装方法
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
        }

        //将hero中的shots集合遍历取出绘制,发射多颗子弹
        for (int i = 0; i < hero.getShots().size(); i++) {
            Shot shot =  hero.getShots().get(i);
            if (shot != null && shot.isLive()){
                g.setColor(Color.blue);
                g.fill3DRect(shot.getX(),shot.getY(), 10, 10, false);
            }else {//如果子弹已经失效,移除
                hero.getShots().remove(shot);
            }

        }

        //画出敌人的坦克
        for (int i = 0; i < anemyTanks.size(); i++){
            //取出坦克
            AnemyTank anemyTank = this.anemyTanks.get(i);

            //判断当前的坦克是否存活
            if (anemyTank.isLive()){//当敌人坦克是存活的
                drawTank(anemyTank.getX(), anemyTank.getY(), g, anemyTank.getDirect(), 0);
                //取出enemyTank所有子弹
                for (int j = 0; j < anemyTank.getShots().size(); j++){
                    //取出子弹准备绘制
                    Shot shot = anemyTank.getShots().get(j);
                    //绘制
                    if (shot.isLive()){//isLive == true;
                        g.draw3DRect(shot.getX(), shot.getY(), 5, 5, false);
                    }else {
                        //移除子弹
                        anemyTank.getShots().remove(shot);
                    }
                }
            }

        }

        //如果bombs集合中有对象,就画出
        for (int i = 0; i < bombs.size(); i++) {
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前bomb对象的life去画出对应的图像
            if (bomb.getLife() > 6){
                g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
            }else if (bomb.getLife() > 3){
                g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
            }else {
                g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
            }
            //让这个炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb life为0,就从bombs的集合中删除
            if (bomb.getLife() == 0){
                bombs.remove(bomb);
            }
        }



    }


    //边写方法画出坦克
    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;
        }


        //根据坦克方向来绘制坦克
        //direct表示方向(0:向上 1:向右 2:向下 3:向左)
        //
        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.fill3DRect(x+18,y,4,20,false);
              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.fill3DRect(x+30,y+18,30,4,false);
                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.fill3DRect(x+18,y+30,4,30,false);
                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.fill3DRect(x,y+18,30,4,false);
                break;

        }


    }



    @Override
    public void keyTyped(KeyEvent e) {

    }



   @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W){
            hero.setDirect(0);
            hero.moveUp();
        }else if (e.getKeyCode() == KeyEvent.VK_D){
            hero.setDirect(1);
            hero.moveRight();
        }else if (e.getKeyCode() == KeyEvent.VK_S){
            hero.setDirect(2);
            hero.moveDown();
        }else if (e.getKeyCode() == KeyEvent.VK_A){
            hero.setDirect(3);
            hero.moveLeft();
        }

        //如果用户用户按下的是J,就发射
       if (e.getKeyCode() == KeyEvent.VK_J){
           System.out.println("用户按下了J,开始射击");
//           发射一颗子弹
//           if (hero.getShot() == null || !hero.getShot().isLive()){
//               hero.shotEnemyTank();
//           }
            //发射多颗子弹
           hero.shotEnemyTank();


       }
        this.repaint();
    }

    //判断敌方坦克打到我方坦克
    public void hitMyTank(){
        //遍历所有的敌方坦克
        for (int i = 0; i < anemyTanks.size(); i++) {
            //取出敌方坦克
            AnemyTank anemyTank = anemyTanks.get(i);
            //遍历他的所有子弹
            for(int j = 0; j < anemyTank.getShots().size(); j++){
                Shot s = anemyTank.getShots().get(j);
                //判断shot是否击中我方的坦克
                if(hero.isLife() && s.isLive()){
                    hitTank(s, hero);
                }

            }
        }
    }

    //如果我们可以发射多颗子弹
    //在判断我方的坦克是否命中敌人时,需要把所有子弹遍历出来,挨个判断

    //编写方法,判断我方的坦克是否命中目标
    //什么时候判断我方坦克击中敌方的坦克
    public void hitTank(Shot s, Tank tank){

        switch (tank.getDirect()){
            case 0://方向为上
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
                        && s.getY() > tank.getY() && s.getY() <= tank.getY() + 60
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    anemyTanks.remove(tank);

                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof AnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1://方向为右
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
                        && s.getY() > tank.getY() && s.getY() < tank.getY() + 40
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    anemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof AnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);

                }
                break;

            case 2://方向为下
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
                        && s.getY() > tank.getY() && s.getY() <= tank.getY() + 40
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    anemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof AnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);

                }
                break;
            case 3:
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
                        && s.getY() > tank.getY() && s.getY() < tank.getY() + 60
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    anemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof AnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);
                }
                break;
        }

    }

    public void hitAnemyTank(){
        for (int i = 0; i < hero.getShots().size(); i++) {
            Shot shot = hero.getShots().get(i);
            //判断是否击中敌人的坦克
            if (shot != null && shot.isLive()) {//当我的子弹还活着
                //遍历敌人所有的坦克
                for (int j = 0; j < anemyTanks.size(); j++) {
                    AnemyTank anemyTank = anemyTanks.get(j);
                    hitTank(shot, anemyTank);
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        //每隔100毫秒,重绘区域
        while (true){

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断我方子弹是否击中敌方的  坦克
            hitAnemyTank();

            hitMyTank();
            this.repaint();
        }
    }
}

2.WwyTankGame01

package tankgame3;

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

public class WwyTankGame1 extends JFrame {

    //定义一个MyPanel
    private MyPanel mp = null;
     static Scanner scanner = new Scanner(System.in);

     public static void main(String[] args) {

         WwyTankGame1 wwyTankGame = new WwyTankGame1();
    }

    public WwyTankGame1(){
         System.out.println("请输入选择: 1.新游戏 2.继续上局");
         String key = scanner.next();
        mp = new MyPanel(key);
        //开启多线程
        Thread thread = new Thread(mp);
        thread.start();
        this.add(mp);//绘图区域
        this.setSize(1000,750);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addKeyListener(mp);

        //在JFrame 中增加相应关闭窗口的处理
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                Recorder.keepRecord();
                System.exit(0);
            }
        });
    }
}

3.AnemyTank

package tankgame3;

import java.util.Vector;

public class AnemyTank extends Tank implements Runnable{

    private boolean isLive = true;

    //炮弹
    private Vector shots = new Vector<>();

    //获取所有的敌人的坦克
    private Vector anemyTanks = new Vector<>();

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

    public Vector getShots() {
        return shots;
    }

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

    public void setShots(Vector shots) {
        this.shots = shots;
    }

    public Vector getAnemyTanks() {
        return anemyTanks;
    }

    //这里提供一个方法,可以将 Mypanel 的成员 anemyTanks 成员变量设置到本类
    public void setAnemyTanks(Vector anemyTanks) {
        this.anemyTanks = anemyTanks;
    }

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

            case 3:
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < anemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    AnemyTank anemyTank = anemyTanks.get(i);
                    //不和自己比较
                    if (anemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){
                            //敌人坦克左上坐标
                            if (this.getX() >= anemyTank.getX()
                                    && this.getX() <= anemyTank.getX() + 40
                                    && this.getY() >= anemyTank.getY()
                                    && this.getY() <= anemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= anemyTank.getX()
                                    && this.getX() <= anemyTank.getX() + 40
                                    && this.getY() + 40 >= anemyTank.getY()
                                    && this.getY() + 40 <= anemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){
                            //敌人坦克左上坐标
                            if (this.getX() >= anemyTank.getX()
                                    && this.getX() <= anemyTank.getX() + 60
                                    && this.getY() >= anemyTank.getY()
                                    && this.getY() <= anemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= anemyTank.getX()
                                    && this.getX() <= anemyTank.getX() + 60
                                    && this.getY() + 40 >= anemyTank.getY()
                                    && this.getY() + 40 <= anemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
        }
        return false;
    }

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

            //如果一个子弹都没有就new一个
            //并启动
            if (isLive && getShots().size() < 2){
                Shot s = null;
                switch (getDirect()){
                    case 0:
                        s = new Shot(getX() + 20, getY(), 0);
                        break;
                    case 1:
                        s = new Shot(getX() + 60, getY() + 20, 1);
                        break;
                    case 2:
                        s = new Shot(getX() + 20, getY() + 60, 2);
                        break;
                    case 3:
                        s = new Shot(getX() -  60, getY() + 20, 3);
                        break;
                }
                getShots().add(s);
                new Thread(s).start();
            }

            //根据坦克的方向继续移动
            switch (getDirect()){
                case 0://向上
                    for (int i = 0; i < 30; i++) {
                            if (getY() > 0 && !isTouchAnemyTank() ) {
                                moveUp();
                            }

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1://向右
                    for (int i = 0; i < 30; i++) {
                            if (getX() < 800 && !isTouchAnemyTank()){
                                moveRight();
                            }
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2://向下
                    for (int i = 0; i < 30; i++) {
                            if (getY() < 750 && !isTouchAnemyTank()) {
                                moveDown();
                            }

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3://向左
                    for (int i = 0; i < 30; i++) {

                            if (getX() > 0 && !isTouchAnemyTank())
                                moveLeft();
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }

            //休眠50毫秒
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //然后随机的改变
            setDirect((int)(Math.random() * 4));

            //写多线程时,一定要考虑到线程什么时候结束
            if (!isLive){
                break;
            }

        }
    }
}

4.Bomb


package tankgame3;



public class Bomb {
    private int x, y;//炸弹的坐标
    private int life = 9;//炸弹的生命周期
    private boolean isLife = true;

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

    //减少生命值
    public void lifeDown(){
        if(life > 0){
            life--;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }else {
            isLife = false;
        }
    }

    public int getX() {
        return x;
    }

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

    public int getY() {
        return y;
    }

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

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public boolean isLife() {
        return isLife;
    }

    public void setLife(boolean life) {
        isLife = life;
    }
}

5.Recorder

package tankgame3;

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

/**
 * 该类记录文件信息和文件交互
 */
public class Recorder {

    //定义变量记录我方击毁敌人坦克数
    private static int hitTankNums = 0;
    //定义IO对象
    private static BufferedWriter bw = null;
    private static BufferedReader br = null;
    private static String recordFile = "d:\\xiangmu\\abc\\a.txt";

    private static Vector anemyTanks = null;

    //定义一个node 的Vector,用于恢复信息
    private static Vector nodes = new Vector<>();

    //添加一个方法,用于读取recordFile,恢复相关的信息
    public static Vector getNodesAndAanemyNums(){

        try {
            br = new BufferedReader(new FileReader(recordFile));
            //循环读取文件,生成 nodes 集合
            String line = "";//255 40 0
            while ((line = br.readLine()) != null){
                String[] s = line.split(" ");
                if (s.length == 3){
                    Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
                    nodes.add(node);
                }else if (s.length == 1){
                    line = s[0];
                    int hitTankNums = Integer.parseInt(line);
                    setHitTankNums(hitTankNums);

                }

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return nodes;
    }

    //添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
    public static void keepRecord(){
        try {
            bw = new BufferedWriter(new FileWriter(recordFile));

            //记录每个存活的敌方坦克
            for (int i = 0; i < anemyTanks.size(); i++) {
               AnemyTank anemyTank = anemyTanks.get(i);
               if (anemyTank.isLive()){
                   bw.write(anemyTank.getX() + " " +anemyTank.getY() + " " + anemyTank.getDirect() + "\r\n");
               }
            }

            bw.write(hitTankNums + "\r\n");

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static int getHitTankNums() {
        return hitTankNums;
    }

    public static Vector getAnemyTanks() {
        return anemyTanks;
    }

    public static void setAnemyTanks(Vector anemyTanks) {
        Recorder.anemyTanks = anemyTanks;
    }

    public static void setHitTankNums(int hitTankNums) {
        Recorder.hitTankNums = hitTankNums;
    }

    public static void addHitTankNums(){
        Recorder.hitTankNums++;
    }
}

6.Node

package tankgame3;

/**
 * 用来记录上次游戏结束的坦克的信息,用来实现继续游戏
 */
public class Node {
    private int x;
    private int y;
    private int direact;

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

    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 getDireact() {
        return direact;
    }

    public void setDireact(int direact) {
        this.direact = direact;
    }
}

7.Shot

package tankgame3;

/**
 * 子弹类
 */
public class Shot implements Runnable{
    private int x;//子弹的横坐标
    private int y;//子弹的纵坐标
    private int direct;//子弹的方向
    private int speed = 5;//子弹的速度
    private boolean isLive = true;//子弹是否成活

    public Shot(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;
    }

    public int getSpeed() {
        return speed;
    }

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

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

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

            //休眠500毫秒
            try {
                Thread.sleep(100);
            } 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;
            }
            System.out.println("子弹的x=" + x + "y=" + y);
            //当子弹移动到边界的时候我们就应该销毁
            //当子弹碰到敌人的坦克时,线程也应该退出
            if (!(x >= 0 && x <= 800 && y >= 0 && y <= 750 && isLive)){
                isLive = false;
                System.out.println("子弹的线程退出");

                break;
            }

        }
    }
}

8.Tank

package tankgame3;

/**
 * 坦克类
 */
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct;//坦克的方向
    private boolean life = true;//坦克是否存活

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

    }

    public boolean isLife() {
        return life;
    }

    public void setLife(boolean life) {
        this.life = life;
    }

    //坦克移动
    //上移
    public void moveUp(){
        if (getY() > 0){
            y-=1;
        }
    }

    //下移
    public void moveDown(){
        if (getY() < 800) {
            y+=1;
        }
    }

    //左移
    public void moveLeft(){
        if (getX() > 0) {
            x-=1;
        }
    }

    //右移
    public void moveRight(){
        if (getX() < 750){
            x+=1;
        }
    }


    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        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;
    }


}

9.Hero

package tankgame3;

import java.util.Vector;

/**
 * 这个是我们的坦克
 */
public class Hero extends Tank {

    //定义一个Shot对象,表示一个射击行为(线程)
    private Shot shot = null;

    //可以发射多颗子弹
    private Vector shots = new Vector<>();

    private boolean life = true;

    public boolean isLife() {
        return life;
    }

    public void setLife(boolean life) {
        this.life = life;
    }

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

    public Shot getShot() {
            return shot;
    }

    public void setShot(Shot shot) {
        this.shot = shot;
    }

    public Vector getShots() {
        return shots;
    }

    public void setShots(Vector shots) {
        this.shots = shots;
    }

    public void shotEnemyTank(){

        //只能存储五颗子弹,如果子弹数目大于5就不再存贮
        if (getShots().size() == 5){
            return;
        }

        //创建Shot对象,根据当前Hero对象的位置和方向来创建shot
        //只有当当前子弹消亡才能再次发射子弹
        switch (getDirect()){
            case 0://向上
                shot = new Shot(getX() + 18, getY(), 0);
                break;
            case 1://向右
                shot = new Shot(getX() + 30, getY() + 18, 1);
                break;
            case 2://向下
                shot = new Shot(getX() + 18,getY() + 30, 2);
                break;
            case 3://向左
                shot = new Shot(getX(), getY() + 18, 3);
                break;
        }
        //把新建的shot放入到集合中
        shots.add(shot);

        //启动我们的shot线程
        new Thread(shot).start();

    }

}

学习时间不长里面很多的内容实现的不是很好,希望勿喷 

你可能感兴趣的:(java,游戏,junit)