JAVA|智能无人机平台(二)

前言

在上一版智能无人机平台基础上,本次迭代新增入侵者生产与移动、无人机雷达扫描检测、多对象共享内存管理等能力,基于 Java Swing + 多线程技术实现了更贴近实际场景的无人机监控仿真效果。

文章目录

一、功能概述

  1. 可视化窗体:构建 1200*1000 像素的窗体,标题为 "智能无人机平台",底部提供功能按钮区
  2. 无人机模块:支持动态生产无人机(随机初始位置、移动速度),无人机绘制雷达扫描范围
  3. 入侵者模块:支持生产入侵者对象(初始位置限定在监控区域外),入侵者具备独立的绘制、移动及血条属性
  4. 雷达检测:无人机可检测扫描范围内的颜色特征变化,识别入侵者
  5. 多线程与共享数据:通过自定义线程处理无人机 / 入侵者的绘制、移动、检测逻辑,监听器线程与绘制线程共享对象集合,保证数据一致性
  6. 边界反弹:无人机、入侵者在各自限定的窗体范围内移动,触碰边界后反向运动

二、技术栈

  1. 可视化框架:Swing(如 Graphics、Color、事件监听)
  2. 多线程:继承 Thread 类实现自定义绘制线程、ActionListener 事件监听线程
  3. 数据结构:ArrayList 存储无人机、入侵者对象,实现多线程共享数据
  4. 图形绘制:Graphics 类实现椭圆(无人机、入侵者、扫描范围)的绘制,Color 类支持透明色、RGB 色值配置
  5. 随机数:Random 类生成无人机 / 入侵者的初始位置、移动速度

三、核心步骤拆解

1:项目结构与类设计

规划 5 个核心类,职责分工如下:

  • DroneUI:窗体入口类,负责界面初始化、组件布局、线程启动及共享数据初始化;
  • DroneThread:自定义绘制线程,处理无人机 / 入侵者的绘制、移动、雷达检测逻辑;
  • Drone:无人机实体类,封装属性(位置、速度、尺寸、扫描范围)与行为(绘制、移动);
  • Intruder:入侵者实体类,封装属性(位置、速度、尺寸、血量)与行为(绘制、移动);
  • DroneListener:事件监听器类,处理按钮点击事件,生产无人机 / 入侵者对象

2:窗体初始化(DroneUI类)

  1. 初始化共享集合:创建ArrayList<Drone>ArrayList<Intruder>,作为监听器与绘制线程的共享数据容器
  2. 窗体配置:设置标题、尺寸、关闭方式、居中显示,添加底部按钮面板(生产无人机、生产入侵者)
  3. 线程关联:将共享集合赋值给监听器与绘制线程,注册按钮监听器,启动绘制线程
  4. 重写 paint 方法:保证窗体刷新逻辑

3:无人机实体实现(Drone类)

  1. 属性封装:定义位置(x/y)、速度(speedx/speedy)、尺寸(size)、扫描范围(scanSize)等核心属性

  2. 构造方法:初始化位置、状态、速度,默认配置尺寸、扫描范围等固定属性

  3. 绘制逻辑(drawDrone):

    • 浅绿色透明椭圆:雷达扫描范围
    • 灰色椭圆:无人机主体
    • 绿色小椭圆:无人机状态标识
  4. 移动逻辑(move):判断边界,触碰后速度反向,实现反弹效果

4:入侵者实体实现(Intruder类)

  1. 属性封装:位置、速度、尺寸、血量(blood),血量控制是否绘制 / 移动;
  2. 构造方法:初始化位置、速度、尺寸,默认血量 100;
  3. 绘制逻辑(drawIntruder):血量≤0 时不绘制,否则绘制黑色椭圆(主体)+ 红色外框;
  4. 移动逻辑(move):血量≤0 时不移动,判断窗体边界,触碰后速度反向。

5:事件监听与对象生产(DroneListener类)

  1. 共享集合:接收 DroneUI 传递的无人机 / 入侵者集合
  2. 生产无人机:点击 "生产无人机" 时,随机生成初始位置、移动速度,创建 Drone 对象并加入集合
  3. 生产入侵者:点击 "生产入侵者" 时,保证初始位置在监控区域外(x<200 或 x>1000,y<175 或 y>775),随机生成速度,创建 Intruder 对象并加入集合

6:多线程绘制与检测(DroneThread类)

run 方法:

  • 循环执行:通过while(true)持续处理绘制、移动、检测
  • 缓冲画布:创建 BufferedImage 作为缓冲层,避免直接绘制导致的界面闪烁
  • 背景绘制:填充白色背景,绘制红色监控区域边框(200,175,800,600)
  • 对象遍历:循环遍历无人机 / 入侵者集合,调用各自的绘制、移动方法
  • 雷达检测:取首个无人机,遍历其扫描范围内的像素颜色,若像素灰度值 < 10(接近黑色,对应入侵者),输出检测提示
  • 画布渲染:将缓冲画布绘制到窗体,线程休眠 1ms 保证流畅性

四、关键技术点说明

1. 共享数据管理

DroneUI 中初始化的droneListintruderList,分别赋值给 DroneListener 和 DroneThread,实现 "生产 - 绘制" 的数据联动

2. 颜色检测实现雷达扫描

无人机扫描范围为浅绿色透明椭圆,入侵者为黑色椭圆。通过img.getRGB(i,j)获取扫描范围内每个像素的 RGB 值,计算灰度值(R+G+B)/3,若灰度值 < 10(黑色特征),判定扫描到入侵者

3. 边界反弹逻辑

  • 无人机:限定在监控区域(200≤x≤1000、175≤y≤775)内移动,触碰边界后速度取反
  • 入侵者:限定在整个窗体(0≤x≤1200、0≤y≤950)内移动,触碰边界后速度取反
  • speedx = -speedx/speedy = -speedy,实现反向运动

4. 多线程协同

  • DroneThread:负责绘制、移动、检测的后台线程,不阻塞 UI 线程
  • DroneListener:基于 Swing 事件线程,处理按钮点击,生产对象
  • 线程通信:通过共享 ArrayList 间接通信

五、完整代码

1. DroneUI类

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

// 主界面类,创建无人机监控系统的图形界面
public class DroneUI extends JFrame {
    // 监听器与无人机线程共享的数据结构
    // 无人机列表
    ArrayList<Drone> droneList = new ArrayList<>(); 
    // 入侵者列表
    ArrayList<Intruder> intruderList = new ArrayList<>(); 

    public DroneUI() {
        setTitle("智能无人机平台"); // 设置窗口标题
        setSize(1200, 1000); // 设置窗口大小
        setDefaultCloseOperation(EXIT_ON_CLOSE); // 关闭操作
        setLocationRelativeTo(null); // 居中显示

        // 创建按钮面板
        JPanel btnPanel = new JPanel();
        btnPanel.setBackground(Color.LIGHT_GRAY);
        
        // 创建"生产无人机"按钮
        JButton btn = new JButton("生产无人机");
        btnPanel.add(btn);
        
        // 创建"生产入侵者"按钮
        JButton btn1 = new JButton("生产入侵者");
        btnPanel.add(btn1);
        
        // 将按钮面板添加到底部
        add(btnPanel, BorderLayout.SOUTH);
        setVisible(true); // 显示窗口

        // 获取绘图对象
        Graphics g = this.getGraphics();
        
        // 创建无人机绘图线程
        DroneThread dt = new DroneThread(g);
        
        // 创建事件监听器
        DroneListener droneL = new DroneListener();
        
        // 为按钮注册事件监听器
        btn.addActionListener(droneL);
        btn1.addActionListener(droneL);

        // 将共享数据结构分配给监听器和绘图线程
        droneL.droneList = droneList; // 监听器线程访问的无人机列表
        dt.droneList = droneList; // 无人机线程访问的无人机列表
        droneL.intruderList = intruderList; // 监听器线程访问的入侵者列表
        dt.intruderList = intruderList; // 无人机线程访问的入侵者列表
        
        // 启动无人机绘图线程
        dt.start();
    }

    // 绘制窗体,刷新界面
    @Override
    public void paint(Graphics g) {
        super.paint(g);
    }

    public static void main(String[] args) {
        // 启动程序
        new DroneUI();
    }
}

2. DroneThread类

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

// 无人机绘图线程类,负责绘制界面中的无人机和入侵者
public class DroneThread extends Thread {
    // 无人机列表
    ArrayList<Drone> droneList;
    // 入侵者列表
    ArrayList<Intruder> intruderList;
    // 绘图对象
    Graphics g;
    
    // 构造函数
    public DroneThread(Graphics g) {
        this.g = g;
    }
    
    @Override
    public void run() {
        // 持续运行游戏循环
        while (true) {
            // 创建缓冲图像,避免屏幕闪烁
            BufferedImage img = new BufferedImage(1200, 950, 2);
            Graphics bg = img.getGraphics();
            
            // 绘制白色背景
            bg.setColor(Color.WHITE);
            bg.fillRect(0, 0, 1200, 950);
            
            // 绘制红色保护区边界
            bg.setColor(Color.RED);
            bg.drawRect(200, 175, 800, 600); // 800*600保护区
            
            // 绘制并移动所有无人机
            for (int j = 0; j < droneList.size(); j++) {
                Drone drone = droneList.get(j);
                drone.drawDrone(bg); // 绘制无人机
                drone.move(); // 移动无人机
            }
            
            // 绘制并移动所有入侵者
            for (int i = 0; i < intruderList.size(); i++) {
                Intruder intruder = intruderList.get(i);
                intruder.drawIntruder(bg); // 绘制入侵者
                intruder.move(); // 移动入侵者
            }
            
            // 雷达扫描功能:检测无人机周围是否有入侵者
            if(droneList.size()>0) {
                System.out.println("进入检测");
                Drone drone = droneList.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 = img.getRGB(i, j);
                        Color c = new Color(colorNum);
                        // 如果平均颜色值小于10(接近黑色),认为检测到目标
                        if ((c.getRed() + c.getBlue() + c.getGreen()) / 3 < 10) {
                            System.out.println("雷达扫描到了~");
                        }
                    }
                }
            }
            
            // 将缓冲图像绘制到屏幕上
            g.drawImage(img, 0, 0, null);
            
            // 延迟1毫秒,控制动画速度
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3. Drone类

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

// 无人机类,定义无人机的位置、外观和行为
public class Drone {
    // 属性
    int x, y, speedx, speedy, size; // 位置坐标、X轴速度、Y轴速度、显示大小
    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.speedy = speedy;
        this.speedx = speedx;
    }

    // 绘制无人机
    public void drawDrone(Graphics bg) {
        // 绘制扫描范围圆圈(半透明绿色)
        Color color1 = new Color(40, 246, 61, 181);
        bg.setColor(color1);
        bg.fillOval(x, y, scanSize, scanSize);
        
        // 绘制无人机主体(灰色)
        Color color2 = Color.GRAY;
        bg.setColor(color2);
        bg.fillOval(x + 35, y + 35, size, size); // 60*60区域
        
        // 绘制状态指示器(绿色)
        Color color3 = Color.GREEN;
        bg.setColor(color3);
        bg.fillOval(x + 42, y + 42, stateSize, stateSize);
    }

    // 控制无人机移动,当碰到边界时反弹
    public void move() {
        // 在保护区边界内移动,超出则反转方向
        if (x > 300 + 600 || x < 200) { // x > 900 或 x < 200
            speedx = -speedx;
        }
        if (y > 175 + 500 || y < 175) { // y > 675 或 y < 175
            speedy = -speedy;
        }
        x += speedx;
        y += speedy;
    }
}

4. Intruder类

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

// 入侵者类
public class Intruder {
    int x, y, speedx, speedy, size; // 位置坐标、速度、大小
    int blood;  // 血量

    // 构造函数
    public Intruder(int x, int y, int speedx, int speedy, int size) {
        this.x = x;
        this.y = y;
        this.speedx = speedx;
        this.speedy = speedy;
        this.size = size;
        this.blood = 100; // 初始化血量为100
    }

    // 绘制入侵者
    public void drawIntruder(Graphics g) {
        // 如果血量小于等于0,则不绘制
        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() {
        // 如果血量小于等于0,则停止移动
        if (blood <= 0) {
            return;
        }
        // 边界检测
        if (x > 1200-size || x < 0) { // 右边界或左边界
            speedx = -speedx;
        }
        if (y > 950-size || y < 0) { // 下边界或上边界
            speedy = -speedy;
        }
        x += speedx;
        y += speedy;
    }
}

5. DroneListener类

java 复制代码
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> droneList;
    // 入侵者列表,供监听器和绘图线程共享
    ArrayList<Intruder> intruderList;
    
    // 生成随机数
    Random random = new Random();
    
    @Override
    public void actionPerformed(ActionEvent e) {
        // 获取按钮命令字符串
        String ac = e.getActionCommand();

        if (ac.equals("生产无人机")) {
            // 在保护区内随机生成无人机位置
            int x = random.nextInt(700) + 200; // x坐标范围: 200-900
            int y = random.nextInt(500) + 175; // y坐标范围: 175-675
            // 随机生成速度 (-2 ~ 2)
            int speedx = random.nextInt(5) - 2;
            int speedy = random.nextInt(5) - 2;
            
            // 创建新无人机并添加到列表
            Drone drone = new Drone(x, y, 0, speedx, speedy);
            droneList.add(drone);

        } else if (ac.equals("生产入侵者")) {
            // 在整个界面范围内随机生成入侵者位置
            int x = random.nextInt(1150); // x坐标范围: 0-1149
            int y = random.nextInt(905); // y坐标范围: 0-904
            
            // 确保入侵者不会在保护区内生成
            while (true) {
                // 如果位置不在保护区内,则跳出循环
                if (x < 200 || x > 1000 || y < 175 || y > 775) {
                    break;
                }
                // 如果在保护区内,则重新生成位置
                x = random.nextInt(1150);
                y = random.nextInt(900);
            }
            
            // 随机生成速度 (-2 ~ 2)
            int speedx = random.nextInt(5) - 2;
            int speedy = random.nextInt(5) - 2;
            
            // 创建新入侵者并添加到列表
            Intruder itd = new Intruder(x, y, speedx, speedy, 45);
            intruderList.add(itd);
        }
    }
}

六、总结

该版本采用 "实体类 + 控制类 + UI 类" 的分层思路,便于扩展(如新增无人机状态、入侵者攻击逻辑等),通过共享集合实现数据同步,缓冲绘制优化界面体验,雷达检测模拟真实监控场景。

相关推荐
JH30732 小时前
SpringBoot自定义启动banner:给项目加个专属“开机画面”
java·spring boot·后端
嵌入小生0072 小时前
基于Linux系统下的C语言程序错误及常见内存问题调试方法教程(嵌入式-Linux-C语言)
linux·c语言·开发语言·嵌入式·小白·内存管理调试·程序错误调试
假女吖☌2 小时前
限流算法-redis实现与java实现
java·redis·算法
小温冲冲2 小时前
QPixmap 详解:Qt 中的高效图像处理类
开发语言·图像处理·qt
lixin5565562 小时前
基于迁移学习的图像风格增强器
java·人工智能·pytorch·python·深度学习·语言模型
面汤放盐2 小时前
企业权限--系统性方案探究
java·开发语言
what丶k2 小时前
深度解析Redis LRU与LFU算法:区别、实现与选型
java·redis·后端·缓存
悟能不能悟2 小时前
java Date转换为string
java·开发语言
菜宾2 小时前
java-redis面试题
java·开发语言·redis