线程进阶: 无人机自动防空平台开发教程V2

总纲:

上篇文章我们进行了线程的初步学习,接下来我们将用线程来解决无人机防空平台的开发。我们的目标是建立一个完善的功能系统,包含雷达扫描,追击敌机,补充弹药,停靠机场等功能。

一、窗体

无人机自动防空平台的第一步是要绘制窗体提供一个背景平台。我们目前是要通过按钮来生成无人机和入侵者,所以我们需要在窗体下面设置按钮,因为我们不采取流式布局,接下来添加按钮需要使用Jpanel面板。我会用代码来进行无人机自动防空平台窗体的绘制。

java 复制代码
public class DroneUI extends JFrame {
    ArrayList<Intruder> IntruderArrayList = new ArrayList<>();

    ArrayList<Drone> droneArrayList = new ArrayList<>();

    public DroneUI(){
        setTitle("智能无人机平台");
        setSize(1200,1000);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel jPanel = new JPanel();
        jPanel.setBackground(Color.LIGHT_GRAY);

        JButton button = new JButton("生产无人机");
        jPanel.add(button);

        JButton button1 = new JButton("生产入侵者");
        jPanel.add(button1);

        add(jPanel,BorderLayout.SOUTH);
        setVisible(true);
        Graphics g = this.getGraphics();
        //无人机线程
        DroneThread droneThread = new DroneThread(g);
        //监听器
        DroneListener droneListener = new DroneListener();
        //按钮注册监听
        button.addActionListener(droneListener);
        button1.addActionListener(droneListener);

        //将共享内存空间的数组 传入两个线程中

        droneListener.droneArrayList=droneArrayList;//监听器线程
        droneThread.droneArrayList=droneArrayList;//无人机线程
        droneListener.IntruderArrayList=IntruderArrayList;
        droneThread.IntruderArrayList=IntruderArrayList;
        droneThread.start();


    }
    //绘制窗体 刷新窗体
    public  void paint(Graphics g){
        super.paint(g);

    }

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

二、无人机和入侵者的生成

因为无人机和入侵者的数量是不固定的,所以我们需要将无人机和入侵者设置成类,类中包含无人机入侵者的属性和方法。

无人机

目前我们的无人机防空系统目前是一个很基础的初始板块儿,所以无人机先限制在一个红色框内移动。

属性:
java 复制代码
 //属性
     int x,y;//坐标
    int speedx,speedy;//速度
    int size;//无人机尺寸
    int state;//无人机状态
    int stateSize;//无人机状态圆的大小
    int scanSize;//雷达范围
构造方法:
java 复制代码
//构造方法
    public Drone(int x,int y,int state,int speedx,int speedy){
        this.x = x;
        this.y = y;
        this.state = state;
        this.size = 30;
        this.stateSize = 15;
        this.scanSize = 100;
        this.speedx = speedx;
        this.speedy = speedy;

    }

用构造方法赋予无人机各属性的初始值或指定值。

绘制方法和移动方法:
java 复制代码
// 方法

    public void drawDrone(Graphics bg){
        Color color1 = new Color(0,0,255,60);
        bg.setColor(color1);
        bg.fillOval(x,y,scanSize,scanSize);
        Color color2 = new Color(64, 195, 66);
        bg.setColor(color2);
        bg.fillOval(x+35,y+35,size,size);
        Color color3 = new Color(255, 0, 0);
        bg.setColor(color3);
        bg.fillOval(x+42,y+42,stateSize,stateSize);
    }

    public void move(){
        if(x>600+300||x<200){
            speedx=-speedx;
        }
        if(y>400+175||y<175){
            speedy=-speedy;
        }
        x+=speedx;
        y+=speedy;
    }

这就是无人机类所包含的内容,先定义属性,通过构造方法再赋予属性初始值,再绘制它的外观以及移动方法生成一个初始简易无人机。

入侵者

入侵者类与无人机类的方法大同小异。但是入侵者因为并不在红色框内移动,所以它的移动和反弹范围要有所调整。

属性
java 复制代码
 int x,y,speedx,speedy,size;
    int blood;
构造方法
java 复制代码
public Intruder(int x,int y,int size,int speedx,int speedy){
    this.x = x;
    this.y = y;
    this.speedx = speedx;
    this.speedy = speedy;
    this.size = size;
    this.blood=100;

}
绘制和移动方法
java 复制代码
 public void drawIntruder(Graphics g){
        if(blood<=0){
            return;
        }
        g.setColor(Color.BLACK);
        g.fillOval(x,y,size,size);
//        g.setColor(Color.RED);
//        g.drawOval(x-1,y-1,size+2,size+2);

    }

    public void  move (){
        if(blood<=0){
            return;
        }
        if(x>1200-size||x<10){
            speedx=-speedx;
        }
        if(y>750-size||y<10){
            speedy=-speedy;
        }
        x+=speedx;
        y+=speedy;
    }

}

三、多线程运行

无人机和入侵者的运行在我们的初始代码下会呈现下图状态,这并不是我们想要的结果。所以我们可以把它们绘制在图片上,然后让图片不断的刷新窗体来达到呈现无人机运行轨迹的目的。此时我们就需要用到线程的知识。

java 复制代码
public class DroneThread extends Thread{

    ArrayList<Drone> droneArrayList;
    ArrayList<Intruder> IntruderArrayList;


    Graphics g;

    public DroneThread(Graphics g){

        this.g=g;
    }
    @Override
    public void run() {

        while (true) {

            BufferedImage image = new BufferedImage(1200,750,2);
            Graphics bg = image.getGraphics();
            bg.setColor(Color.WHITE);
            bg.fillRect(0,0,1200,750);
            bg.setColor(Color.RED);
            bg.drawRect(200,175,800,500);

            //遍历无人机数组 取出无人机对象 调用绘制 和移动的方法
            for (int j = 0; j <droneArrayList.size() ; j++) {
                Drone drone = droneArrayList.get(j);
                drone.drawDrone(bg);
                drone.move();
            }

            for (int j = 0; j <IntruderArrayList.size() ; j++) {
                Intruder intruder = IntruderArrayList.get(j);
                intruder.drawIntruder(bg);
                intruder.move();
            }

            // 检测周围是否有颜色变化
            if(droneArrayList.size()>0) {
                //System.out.println("进入检测~");
                Drone drone = droneArrayList.get(0);
                for (int i = drone.x; i <drone.x+ drone.scanSize; i++) {
                    for (int j = drone.y; j < drone.y+drone.scanSize; j++) {
                        int colorNum = image.getRGB(i , j);
                        Color color = new Color(colorNum);
                        if ((color.getRed() + color.getBlue() + color.getGreen()) / 3 < 10) {
                            System.out.println("雷达扫描到了~");
                        }

                    }

                }

            }


            g.drawImage(image,0,0,null);
            try {
                Thread.sleep(15);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }

    }

}

在这里我设置的间隔时间是15ms,使无人机和入侵者的运行速度较为均衡

什么是 ArrayList

复制代码
ArrayList<Drone> droneList = new ArrayList<>(); 

含义:

  • 动态数组

  • 里面装的是 Drone 对象


为什么不用普通数组?

数组 ArrayList
长度固定 可变
不方便增删 很方便

仿真程序一定要用 ArrayList,是多个线程共享的数据

四、监听器

java 复制代码
public class DroneListener implements ActionListener {

    ArrayList<Drone> droneArrayList;
    ArrayList<Intruder> IntruderArrayList;
    Random random = new Random();
    public void actionPerformed(ActionEvent e){
        String ac = e.getActionCommand();


    if (ac.equals("生产无人机")){
        int x = random.nextInt(700)+200;
        int y = random.nextInt(400)+175;
        int speedx = random.nextInt(5)-2;//-2-2
        int speedy = random.nextInt(5)-2;//-2-2
        Drone drone = new Drone(x,y,0,speedx,speedy);

        droneArrayList.add(drone);
        } else if (ac.equals("生产入侵者")) {
        int x = random.nextInt(1150);
        int y = random.nextInt(705);

        while (true){
            if (x<200||x>1000||y<175||y>775) {
                break;
            }
            x = random.nextInt(1150);
            y = random.nextInt(900);

        }

        int speedx = random.nextInt(5)-2;//-2-2
        int speedy = random.nextInt(5)-2;//-2-2
        Intruder intruder = new Intruder(x, y, 45, speedx, speedy);


        IntruderArrayList.add(intruder);
    }
    }
}

完整代码如下:

DroneUI类

java 复制代码
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class DroneUI extends JFrame {
    ArrayList<Intruder> IntruderArrayList = new ArrayList<>();

    ArrayList<Drone> droneArrayList = new ArrayList<>();

    public DroneUI(){
        setTitle("智能无人机平台");
        setSize(1200,1000);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel jPanel = new JPanel();
        jPanel.setBackground(Color.LIGHT_GRAY);

        JButton button = new JButton("生产无人机");
        jPanel.add(button);

        JButton button1 = new JButton("生产入侵者");
        jPanel.add(button1);

        add(jPanel,BorderLayout.SOUTH);
        setVisible(true);
        Graphics g = this.getGraphics();
        //无人机线程
        DroneThread droneThread = new DroneThread(g);
        //监听器
        DroneListener droneListener = new DroneListener();
        //按钮注册监听
        button.addActionListener(droneListener);
        button1.addActionListener(droneListener);

        //将共享内存空间的数组 传入两个线程中

        droneListener.droneArrayList=droneArrayList;//监听器线程
        droneThread.droneArrayList=droneArrayList;//无人机线程
        droneListener.IntruderArrayList=IntruderArrayList;
        droneThread.IntruderArrayList=IntruderArrayList;
        droneThread.start();


    }
    //绘制窗体 刷新窗体
    public  void paint(Graphics g){
        super.paint(g);

    }

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

Drone类

java 复制代码
import java.awt.*;

public class Drone {
    //属性
    int x,y,speedx,speedy,size;
    int state;
    int stateSize;
    int scanSize;

    //构造方法
    public Drone(int x,int y,int state,int speedx,int speedy){
        this.x = x;
        this.y = y;
        this.state = state;
        this.size = 30;
        this.stateSize = 15;
        this.scanSize = 100;
        this.speedx = speedx;
        this.speedy = speedy;

    }

    // 方法

    public void drawDrone(Graphics bg){
        Color color1 = new Color(0,0,255,60);
        bg.setColor(color1);
        bg.fillOval(x,y,scanSize,scanSize);
        Color color2 = new Color(64, 195, 66);
        bg.setColor(color2);
        bg.fillOval(x+35,y+35,size,size);
        Color color3 = new Color(255, 0, 0);
        bg.setColor(color3);
        bg.fillOval(x+42,y+42,stateSize,stateSize);
    }

    public void move(){
        if(x>600+300||x<200){
            speedx=-speedx;
        }
        if(y>400+175||y<175){
            speedy=-speedy;
        }
        x+=speedx;
        y+=speedy;
    }

}

Intruder类

java 复制代码
import java.awt.*;

public class Intruder {
    int x,y,speedx,speedy,size;
    int blood;

    public Intruder(int x,int y,int size,int speedx,int speedy){
        this.x = x;
        this.y = y;
        this.speedx = speedx;
        this.speedy = speedy;
        this.size = size;
        this.blood=100;

    }

    public void drawIntruder(Graphics g){
        if(blood<=0){
            return;
        }
        g.setColor(Color.BLACK);
        g.fillOval(x,y,size,size);
//        g.setColor(Color.RED);
//        g.drawOval(x-1,y-1,size+2,size+2);

    }

    public void  move (){
        if(blood<=0){
            return;
        }
        if(x>1200-size||x<10){
            speedx=-speedx;
        }
        if(y>750-size||y<10){
            speedy=-speedy;
        }
        x+=speedx;
        y+=speedy;
    }

}

线程类

java 复制代码
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class DroneThread extends Thread{

    ArrayList<Drone> droneArrayList;
    ArrayList<Intruder> IntruderArrayList;


    Graphics g;

    public DroneThread(Graphics g){

        this.g=g;
    }
    @Override
    public void run() {

        while (true) {

            BufferedImage image = new BufferedImage(1200,750,2);
            Graphics bg = image.getGraphics();
            bg.setColor(Color.WHITE);
            bg.fillRect(0,0,1200,750);
            bg.setColor(Color.RED);
            bg.drawRect(200,175,800,500);

            //遍历无人机数组 取出无人机对象 调用绘制 和移动的方法
            for (int j = 0; j <droneArrayList.size() ; j++) {
                Drone drone = droneArrayList.get(j);
                drone.drawDrone(bg);
                drone.move();
            }

            for (int j = 0; j <IntruderArrayList.size() ; j++) {
                Intruder intruder = IntruderArrayList.get(j);
                intruder.drawIntruder(bg);
                intruder.move();
            }

            // 检测周围是否有颜色变化
            if(droneArrayList.size()>0) {
                //System.out.println("进入检测~");
                Drone drone = droneArrayList.get(0);
                for (int i = drone.x; i <drone.x+ drone.scanSize; i++) {
                    for (int j = drone.y; j < drone.y+drone.scanSize; j++) {
                        int colorNum = image.getRGB(i , j);
                        Color color = new Color(colorNum);
                        if ((color.getRed() + color.getBlue() + color.getGreen()) / 3 < 10) {
                            System.out.println("雷达扫描到了~");
                        }

                    }

                }

            }


            g.drawImage(image,0,0,null);
            try {
                Thread.sleep(15);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }

    }

}

监听器类

java 复制代码
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

public class DroneListener implements ActionListener {

    ArrayList<Drone> droneArrayList;
    ArrayList<Intruder> IntruderArrayList;
    Random random = new Random();
    public void actionPerformed(ActionEvent e){
        String ac = e.getActionCommand();


    if (ac.equals("生产无人机")){
        int x = random.nextInt(700)+200;
        int y = random.nextInt(400)+175;
        int speedx = random.nextInt(5)-2;//-2-2
        int speedy = random.nextInt(5)-2;//-2-2
        Drone drone = new Drone(x,y,0,speedx,speedy);

        droneArrayList.add(drone);
        } else if (ac.equals("生产入侵者")) {
        int x = random.nextInt(1150);
        int y = random.nextInt(705);

        while (true){
            if (x<200||x>1000||y<175||y>775) {
                break;
            }
            x = random.nextInt(1150);
            y = random.nextInt(900);

        }

        int speedx = random.nextInt(5)-2;//-2-2
        int speedy = random.nextInt(5)-2;//-2-2
        Intruder intruder = new Intruder(x, y, 45, speedx, speedy);


        IntruderArrayList.add(intruder);
    }
    }
}
相关推荐
A懿轩A2 小时前
【Java 基础编程】Java 变量与八大基本数据类型详解:从声明到类型转换,零基础也能看懂
java·开发语言·python
m0_740043732 小时前
【无标题】
java·spring boot·spring·spring cloud·微服务
@ chen3 小时前
Spring事务 核心知识
java·后端·spring
aithinker3 小时前
使用QQ邮箱收发邮件遇到的坑 有些WIFI不支持ipv6
java
星火开发设计3 小时前
C++ 预处理指令:#include、#define 与条件编译
java·开发语言·c++·学习·算法·知识
Hx_Ma163 小时前
SpringMVC返回值
java·开发语言·servlet
Yana.nice3 小时前
openssl将证书从p7b转换为crt格式
java·linux
独自破碎E3 小时前
【滑动窗口+字符计数数组】LCR_014_字符串的排列
android·java·开发语言
想逃离铁厂的老铁3 小时前
Day55 >> 并查集理论基础 + 107、寻找存在的路线
java·服务器