JavaStudy7(18章-坦克大战2)—B站韩顺平

JavaStudy7(18章-坦克大战2)—B站韩顺平

1.坦克大战

1.1线程-应用到坦克大战

1.1.1 坦克大战 0.3

在这里插入图片描述

代码演示:
//为了监听 键盘事件, 实现 KeyListener
public class HspTankGame03 extends JFrame {
    //定义一个面板
    private MyPanel mp = null;

    public static void main(String[] args) {
        HspTankGame03 hspTankGame03 = new HspTankGame03();
        System.out.println("程序开始");
    }

    public HspTankGame03() {//构造器
        //初始化面板
        mp = new MyPanel();
        //将mp 放入到Thread ,并启动
        Thread thread = new Thread(mp);
        thread.start();
        //把面板放入到窗口(画框)
        this.add(mp);
        //设置窗口的大小
        this.setSize(1000, 750);
        this.addKeyListener(mp);//让JFrame 监听mp的事件
        //当点击窗口的小×,程序完全退出.
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);//可以显示

    }
}
package com.qinbo.tankgame03;

/**
 * @ClassName Tank
 * @Author :BLWY-1124
 * @Date :2022/3/27 12:29
 * @Description: 父类坦克模板
 * @Version: 1.0
 */
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct; //坦克方向 0 上 1 右 2 下 3 左
    private int speed = 1;
    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 int getDirect() {
        return direct;
    }

    public int getSpeed() {
        return speed;
    }

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

    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;
    }
}
package com.qinbo.tankgame03;

/**
 * @ClassName EnemyTank
 * @Author :BLWY-1124
 * @Date :2022/3/27 18:19
 * @Description: 敌人的坦克
 * @Version: 1.0
 */
public class EnemyTank extends Tank{
    public EnemyTank(int x, int y) {
        super(x, y);
    }
}
package com.qinbo.tankgame03;

/**
 * @ClassName MyTank
 * @Author :BLWY-1124
 * @Date :2022/3/27 12:29
 * @Description:自己的坦克
 * @Version: 1.0
 */
public class Hero extends Tank {
    //定义一个Shot对象, 表示一个射击(线程)
    Shot shot = null;

    public Hero(int x, int y) {
        super(x, y);
    }
    //射击子弹
    public void shotEnemyTank(){
        //创建 shot 对象,根据当前hero对象的位置和方向来创建Shot
        switch (getDirect()){
            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);
        }
        //启动我们的Shot线程
        new Thread(shot).start();
    }
}
package com.qinbo.tankgame03;

/**
 * @ClassName Shot
 * @Author :BLWY-1124
 * @Date :2022/3/30 15:48
 * @Description: 射击子弹
 * @Version: 1.0
 */
public class Shot implements Runnable {
    int x; // 子弹横坐标
    int y; //子弹纵坐标
    int direct; 子弹方向 0 上 1 右 2 下 3 左
    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) {

            //线程(子弹)休眠50ms
            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;
                System.out.println("子弹线程退出");
                break;
            }
        }
    }
}
    package com.qinbo.tankgame03;

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

    /**
     * @ClassName MyPanel
     * @Author :BLWY-1124
     * @Date :2022/3/27 12:14
     * @Description: 坦克大战的绘图区
     * @Version: 1.0
     */
    //为了监听 键盘事件, 实现KeyListener
//为了让Panel 不停的重绘子弹,需要将 MyPanel 实现Runnable ,当做一个线程使用
    public class MyPanel extends JPanel implements KeyListener ,Runnable{
        //定义我的坦克
        Hero hero = null;
        //定义敌人的坦克放到Vector
        Vector<EnemyTank> enemyTanks = new Vector<>();
        int enemyTanksSize = 3;

        public MyPanel() {
            hero = new Hero(100, 100);//初始化自己坦克
            hero.setSpeed(6);
            //初始敌人的坦克
            for (int i = 0; i < enemyTanksSize; i++) {
                //创建一个敌人的坦克
                EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
                //设置方向
                enemyTank.setDirect(2);
                //加入
                enemyTanks.add(enemyTank);
            }
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            //填充矩形,默认黑色
            g.fillRect(0, 0, 1000, 750);
            //画出自己坦克-封装方法
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
            //画出hero射出得子弹
            if (hero.shot != null && hero.shot.isLive){
                System.out.println("绘制子弹。。。");
                g.draw3DRect(hero.shot.x,hero.shot.y,1,1,false);
            }
            //画出敌人的坦克, 遍历Vector
            for (int i = 0; i < enemyTanks.size(); i++) {
                //取出坦克
                EnemyTank enemyTank = enemyTanks.get(i);
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
            }
        }
        //编写方法,画出坦克

        /**
         * @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;
            }

            //根据坦克方向,来绘制对应形状坦克
            //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.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("暂时没有处理");
            }

        }

        @Override
        public void keyTyped(KeyEvent e) {

        }

        //处理 wdsa 键按下的情况
        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(e.getKeyCode());
            if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键
                //改变坦克的方向
                hero.setDirect(0);//
                //修改坦克的坐标 y -= 1
                hero.moveUp(); //向上
            } else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右
                hero.setDirect(1);
                hero.moveRight();//向右

            } else if (e.getKeyCode() == KeyEvent.VK_S) {//S键
                hero.setDirect(2);
                hero.moveDown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {//A键
                hero.setDirect(3);
                hero.moveLeft();
            }
            //如果用户按下的时J,就发射
            if (e.getKeyCode() == KeyEvent.VK_J){ //J键 射击
                System.out.println("用户按下了J, 开始射击.");
                hero.shotEnemyTank();
            }
            //让面板重绘
            this.repaint();
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }

        @Override
        public void run() { //每隔 100ms  重绘区域, 刷新绘图区域, 子弹就移动
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.repaint();
            }
        }
    }
1.1.2 坦克大战 0.4 版

在这里插入图片描述

思路:

在这里插入图片描述

在这里插入图片描述

代码演示:

package com.qinbo.tankgame04;


import javax.swing.*;

/**
 * @ClassName HspTankGame01
 * @Author :BLWY-1124
 * @Date :2022/3/27 11:21
 * @Description:
 * @Version: 1.0
 */
//为了监听 键盘事件, 实现 KeyListener
public class HspTankGame04 extends JFrame {
    //定义一个面板
    private MyPanel mp = null;

    public static void main(String[] args) {
        HspTankGame04 hspTankGame04 = new HspTankGame04();
        System.out.println("程序开始");
    }

    public HspTankGame04() {//构造器
        //初始化面板
        mp = new MyPanel();
        //将mp 放入到Thread ,并启动
        Thread thread = new Thread(mp);
        thread.start();
        //把面板放入到窗口(画框)
        this.add(mp);
        //设置窗口的大小
        this.setSize(1000, 750);
        this.addKeyListener(mp);//让JFrame 监听mp的事件
        //当点击窗口的小×,程序完全退出.
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);//可以显示

    }
}
    package com.qinbo.tankgame04;

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

    /**
     * @ClassName MyPanel
     * @Author :BLWY-1124
     * @Date :2022/3/27 12:14
     * @Description: 坦克大战的绘图区
     * @Version: 1.0
     */
    //为了监听 键盘事件, 实现KeyListener
//为了让Panel 不停的重绘子弹,需要将 MyPanel 实现Runnable ,当做一个线程使用
    public class MyPanel extends JPanel implements KeyListener ,Runnable{
        //定义我的坦克
        Hero hero = null;
        //定义敌人的坦克放到Vector
        Vector<EnemyTank> enemyTanks = new Vector<>();
        int enemyTanksSize = 3;
        //定义一个Vector 存放炸弹
        //说明,当子弹击中坦克时,加入一个Bomb对象到bombs
        Vector<Bomb> bombs = new Vector<>();

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

        public MyPanel() {
            hero = new Hero(100, 100);//初始化自己坦克
            hero.setSpeed(6);
            //初始敌人的坦克
            for (int i = 0; i < enemyTanksSize; i++) {
                //创建一个敌人的坦克
                EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
                //启动坦克
                new Thread(enemyTank).start();
                //设置方向
                enemyTank.setDirect(2);
                //给该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);
            }
            image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
            image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
            image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            //填充矩形,默认黑色
            g.fillRect(0, 0, 1000, 750);
            //画出自己坦克-封装方法
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
            //画出hero射出得子弹
            if (hero.shot != null && hero.shot.isLive){
                System.out.println("绘制子弹。。。");
                g.draw3DRect(hero.shot.x,hero.shot.y,1,1,false);
            }
            //如果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();
                //如果life=0,就把他从集合中删除
                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, 1, 1, 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;
            }

            //根据坦克方向,来绘制对应形状坦克
            //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.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 hitTank( Shot s, EnemyTank enemyTank){
            //判断击中敌方坦克
            switch (enemyTank.getDirect()){
                case 0://坦克向上
                case 2://坦克向下
                    if (s.x > enemyTank.getX() && s.x < enemyTank.getX()+40 &&
                            s.y >enemyTank.getY() && s.y < enemyTank.getY()+60){
                        //坦克消失,子弹消失,线程终止
                        enemyTank.isLive = false;
                        s.isLive = false;
                        //当我的子弹击中敌人坦克后,将enemyTank 从Vector 拿掉
                        enemyTanks.remove(enemyTank);
                    //坦克被击中爆炸 创建Bomb对象,加入到bombs集合
                       Bomb bomb =  new Bomb(enemyTank.getX(),enemyTank.getY());
                       bombs.add(bomb);
                    }
                    break;
                case 1://坦克向左
                case 3://坦克向右
                    if (s.x > enemyTank.getX() && s.x < enemyTank.getX()+60 &&
                            s.y >enemyTank.getY() && s.y < enemyTank.getY()+40){
                        //坦克消失,子弹消失,线程终止
                        enemyTank.isLive = false;
                        s.isLive = false;
                        //坦克被击中爆炸 创建Bomb对象,加入到bombs集合
                        Bomb bomb =  new Bomb(enemyTank.getX(),enemyTank.getY());
                        bombs.add(bomb);
                        enemyTanks.remove(enemyTank);
                    }
                    break;
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {

        }

        //处理 wdsa 键按下的情况
        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(e.getKeyCode());
            if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键
                //改变坦克的方向
                hero.setDirect(0);//
                //修改坦克的坐标 y -= 1
                if (hero.getY() > 0) {
                    hero.moveUp(); //向上
                }
            } else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右
                hero.setDirect(1);
                if (hero.getX() +60 <1000) {
                    hero.moveRight();//向右
                }
            } else if (e.getKeyCode() == KeyEvent.VK_S) {//S键
                hero.setDirect(2);
                if (hero.getY() +60< 750) {
                    hero.moveDown();
                }
            } else if (e.getKeyCode() == KeyEvent.VK_A) {//A键
                hero.setDirect(3);
                if (hero.getX() > 0) {
                    hero.moveLeft();
                }
            }
            //如果用户按下的时J,就发射
            if (e.getKeyCode() == KeyEvent.VK_J){ //J键 射击
                System.out.println("用户按下了J, 开始射击.");
                hero.shotEnemyTank();
            }
            //让面板重绘
            this.repaint();
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }

        @Override
        public void run() { //每隔 100ms  重绘区域, 刷新绘图区域, 子弹就移动
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //判断是否击中了敌人
                if ( hero.shot != null && hero.shot.isLive) {//当我的子弹还活着
                    //遍历敌人坦克
                    for (int i = 0; i < enemyTanks.size(); i++) {
                        EnemyTank enemyTank = enemyTanks.get(i);
                        hitTank(hero.shot, enemyTank);
                    }
                }
                this.repaint();
            }
        }
    }
package com.qinbo.tankgame04;

/**
 * @ClassName Tank
 * @Author :BLWY-1124
 * @Date :2022/3/27 12:29
 * @Description: 父类坦克模板
 * @Version: 1.0
 */
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct; //坦克方向 0 上 1 右 2 下 3 左
    private int speed = 2;
    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 int getDirect() {
        return direct;
    }

    public int getSpeed() {
        return speed;
    }

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

    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;
    }
}
package com.qinbo.tankgame04;

/**
 * @ClassName MyTank
 * @Author :BLWY-1124
 * @Date :2022/3/27 12:29
 * @Description:自己的坦克
 * @Version: 1.0
 */
public class Hero extends Tank {
    //定义一个Shot对象, 表示一个射击(线程)
    Shot shot = null;

    public Hero(int x, int y) {
        super(x, y);
    }
    //射击子弹
    public void shotEnemyTank(){
        //创建 shot 对象,根据当前hero对象的位置和方向来创建Shot
        switch (getDirect()){
            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);
        }
        //启动我们的Shot线程
        new Thread(shot).start();
    }
}
package com.qinbo.tankgame04;

import java.text.BreakIterator;
import java.util.Random;
import java.util.Vector;
import java.util.zip.ZipEntry;

/**
 * @ClassName EnemyTank
 * @Author :BLWY-1124
 * @Date :2022/3/27 18:19
 * @Description: 敌人的坦克
 * @Version: 1.0
 */
public class EnemyTank extends Tank implements Runnable{
    //在敌人坦克类,使用Vector 保存多个Shot
    Vector<Shot> shots = new Vector<>();
    boolean isLive = true;
    public EnemyTank(int x, int y) {
        super(x, y);
    }
  //创建线程
    @Override
    public void run() {
        while (true) {
            //这里我们判断如果shots size() =0, 创建一颗子弹,放入到
            //shots集合,并启动
            if (isLive && shots.size() < 1) {
                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(), getY() + 20, 3);
                }
                shots.add(s);
                //启动我们的Shot线程
                new Thread(s).start();
            }
            //根据坦克的方向来继续激动
            switch (getDirect()) {
                case 0://向上
                    //移动随机步数
                    for (int i = 0; i < (int) (Math.random() * 100); i++) {
                        if (getY() > 0) {
                            moveUp();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1: //向右
                    for (int i = 0; i < (int) (Math.random() * 100); i++) {
                        if (getX() <1000-60) {
                            moveRight();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2: //向下
                    for (int i = 0; i < (int) (Math.random() * 100); i++) {
                        if (getY() <750 - 60) {
                            moveDown();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3: //向左
                    for (int i = 0; i < (int) (Math.random() * 100); i++) {
                        if (getX() > 0) {
                            moveLeft();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
            //然后随机的改变坦克方向 0-3
            setDirect((int) (Math.random() * 4));
            if (!isLive) {
                //听老韩说,写并发程序,一定要考虑清楚,该线程什么时候结束
                break;//退出线程.
            }
        }
    }
}
package com.qinbo.tankgame04;

/**
 * @ClassName Shot
 * @Author :BLWY-1124
 * @Date :2022/3/30 15:48
 * @Description: 射击子弹
 * @Version: 1.0
 */
public class Shot implements Runnable {
    int x; // 子弹横坐标
    int y; //子弹纵坐标
    int direct; 子弹方向 0 上 1 右 2 下 3 左
    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) {

            //线程(子弹)休眠50ms
            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)) {
                isLive = false;
                System.out.println("子弹线程退出");
                break;
            }
        }
    }
}
package com.qinbo.tankgame04;

/**
 * @ClassName Bomb
 * @Author :BLWY-1124
 * @Date :2022/3/31 23:39
 * @Description:
 * @Version: 1.0
 */
public class Bomb {
    int x;
    int 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;
        }
    }
}

我亦无他,惟手熟尔

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

别来无恙blwy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值