智能无人机防空平台 V2.0 ——攻击反制

引言

在之前的V1、V2版本中,该平台可动态生成我方无人机敌方入侵者 ,两者均具备自主移动能力,并能通过像素级扫描互相发现与攻击。V3版本在之前版本基础上优化了边界处理、速度随机生成逻辑,并完善了双向扫描机制(无人机扫描入侵者并跟随,入侵者扫描无人机并扣除生命值)。


项目结构

类名 类型 职责
Drone 实体类 表示我方无人机,包含位置、速度、扫描范围等属性,提供绘制与移动方法。
Intruder 实体类 表示敌方入侵者,包含位置、速度、生命值等属性,提供绘制与移动方法。
DroneUI 界面类 继承JFrame,搭建主窗口、按钮面板,并初始化共享数据列表及线程。
DroneListener 监听器类 实现ActionListener,响应按钮点击事件,随机生成无人机或入侵者对象并加入列表。
DroneThread 线程类 继承Thread,在run()中循环刷新图像,执行所有对象的绘制、移动及双向扫描逻辑。

数据共享:DroneUI中维护两个ArrayList分别存储无人机和入侵者对象,通过引用传递给DroneListenerDroneThread,实现多线程间的数据共享。


项目更新具体实现(聚焦V3版本新增功能)

1.事件监听器:DroneListener

复制代码
package Dronev3;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

public class DroneListener implements ActionListener {

    ArrayList<Intruder> intruderList;
    ArrayList<Drone> droneList=new ArrayList<>();
    Random random=new Random();

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Drones Production")){
            int x= random.nextInt(700)+200;
            int y= random.nextInt(500)+175;
            int speedx;
            do {
                speedx = random.nextInt(5) - 2;
            } while (speedx == 0);
            int speedy;
            do {
                speedy = random.nextInt(5) - 2;
            } while (speedy == 0);
            Drone drone=new Drone(x,y,speedx,speedy,0);
            droneList.add(drone);
        } else if (e.getActionCommand().equals("Intruder Production")) {
            int x= random.nextInt(950)+50;
            int y= random.nextInt(800)+50;
            while (true){
                if (x<200 || x>1000 || y<175 || y>775) {
                    break;
                }
                x= random.nextInt(950)+50;
                y= random.nextInt(800)+50;
            }
            int speedx;
            do {
                speedx = random.nextInt(5) - 2;
            } while (speedx == 0);
            int speedy;
            do {
                speedy = random.nextInt(5) - 2;
            } while (speedy == 0);
            Intruder intruder=new Intruder(x,y,speedx,speedy,45,100);
            intruderList.add(intruder);
        }
    }
}

更新解析:

  • 生成无人机 :坐标范围在红色边界框内(x:200~900,y:175~675),使用nextInt(700)+200nextInt(500)+175确保。速度通过do-while保证非零(-2,-1,1,2),避免静止对象。

  • 生成入侵者 :坐标范围全屏(50~1000,x:50~1000,y:50~850),但要求必须位于红色边界框之外 (即x<200或x>1000或y<175或y>775)。使用while(true)循环不断生成直到满足条件。速度同样保证非零。2.

2.核心线程:DroneThread

复制代码
package Dronev3;

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;
    }

    public void run() {
        while (true) {
            BufferedImage image = new BufferedImage(1200, 950, 2);
            Graphics bg = image.getGraphics();
            bg.setColor(Color.WHITE);
            bg.fillRect(0, 0, 1200, 950);
            bg.setColor(Color.RED);
            bg.drawRect(200, 175, 800, 600);

            // 遍历无人机数组,调用无人机的绘制方法
            for (int j = 0; j < droneList.size(); j++) {
                droneList.get(j).drawDrone(bg);
                droneList.get(j).moveDrone();
            }
            // 遍历入侵者数组,调用入侵者的绘制方法
            for (int j = 0; j < intruderList.size(); j++) {
                intruderList.get(j).drawIntruder(bg);
                intruderList.get(j).moveIntruder();
            }

            // 无人机扫描入侵者:每个无人机扫描自己周围区域
            if (droneList.size() > 0) {
                for (int k = 0; k < droneList.size(); k++) {
                    Drone drone = droneList.get(k);
                    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);
                            // 灰度值小于10,认为是入侵者(黑色)
                            if ((color.getRed() + color.getGreen() + color.getBlue()) / 3 < 10) {
                                for (int l = 0; l < intruderList.size(); l++) {
                                    Intruder intruder = intruderList.get(l);
                                    if (i < intruder.x + intruder.size && i >= intruder.x
                                            && j >= intruder.y && j < intruder.y + intruder.size) {
                                        drone.speedx = intruder.speedx;
                                        drone.speedy = intruder.speedy;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // 入侵者扫描无人机:每个活着的入侵者扫描周围区域,检测到无人机则扣血
            for (int i = 0; i < intruderList.size(); i++) {
                System.out.println("入侵者进入检测");
                Intruder intruder = intruderList.get(i);
                if (intruder.HP <= 0) {
                    continue;
                }
                for (int j = intruder.x - 15; j < intruder.x + 70; j++) {
                    boolean flag = false;
                    for (int k = intruder.y - 15; k < intruder.y + 70; k++) {
                        int colorNum = image.getRGB(j, k);
                        Color color = new Color(colorNum);
                        int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
                        // 灰度值在30~150之间且红色分量<100,认为是无人机(紫色)
                        if (gray > 30 && gray < 150 && color.getRed() < 100) {
                            intruder.HP -= 1;
                            System.out.println("入侵者被检测到~" + intruder.HP);
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        break;
                    }
                }
            }

            g.drawImage(image, 0, 0, null);

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
  • 无人机扫描(改进后)

    • 遍历所有无人机(for (int k = 0; k < droneList.size(); k++)),实现多机同时扫描。

    • 扫描区域:从drone.xdrone.x+scanSizedrone.ydrone.y+scanSize

    • 遍历区域内每个像素,计算灰度值,若小于10(接近黑色),则认为是入侵者的黑色像素。

    • 进一步通过坐标判断该像素是否落在某个入侵者的矩形内(入侵者绘制为黑色圆形,但检测时用矩形包围盒),若匹配,则将该无人机的速度设置为该入侵者的速度,实现"跟随"。

  • 入侵者扫描(改进后)

    • 遍历每个活着的入侵者(HP>0)。

    • 扫描范围:从intruder.x-15intruder.x+70intruder.y-15intruder.y+70(约比自身大一圈)。

    • 遍历像素,计算灰度值,若满足gray>30 && gray<150 && color.getRed()<100,则认为检测到无人机(紫色机体RGB约(94,20,223),灰度约112,红色分量小),入侵者HP减1。

    • 一旦检测到,立即跳出循环(避免同一帧多次扣血)。


项目更新涉及知识点

1.入侵者存储与攻击机制

1.1 入侵者的存储方式

入侵者对象的集合在 DroneUI 中初始化:

复制代码
ArrayList<Intruder> intruderList = new ArrayList<>();

随后通过引用传递注入到 DroneThread

复制代码
dt.intruderList = intruderList;

DroneThread 中,使用成员变量持有该引用:

复制代码
ArrayList<Intruder> intruderList;

存储特点:

  • 使用 ArrayList 作为容器,支持动态增删。

  • 该列表被两个线程共享:DroneThread(读取/修改入侵者 HP)和 DroneListener(添加新入侵者)。由于未加同步锁,存在并发修改风险。

  • 每个 Intruder 对象包含坐标、速度、大小、HP 等属性,其中 HP 是攻击机制的核心指标。

1.2 无人机扫描入侵者:发现与追踪

1.2.1 扫描循环结构
复制代码
if (droneList.size() > 0) {
    for (int k = 0; k < droneList.size(); k++) {
        Drone drone = droneList.get(k);
        for (int i = drone.x; i < drone.x + drone.scanSize; i++) {
            for (int j = drone.y; j < drone.y + drone.scanSize; j++) {
                // 像素检测...
            }
        }
    }
}
  • 外层循环:遍历所有无人机。

  • 内层双重循环 :遍历当前无人机扫描区域内的每个像素(scanSize = 100,即 100×100 像素区域)。

1.2.2 像素级判定逻辑
复制代码
int colorNum = image.getRGB(i, j);
Color color = new Color(colorNum);
if ((color.getRed() + color.getGreen() + color.getBlue()) / 3 < 10) {
    // 认为是入侵者(黑色)
    for (int l = 0; l < intruderList.size(); l++) {
        Intruder intruder = intruderList.get(l);
        if (i < intruder.x + intruder.size && i >= intruder.x
                && j >= intruder.y && j < intruder.y + intruder.size) {
            drone.speedx = intruder.speedx;
            drone.speedy = intruder.speedy;
            break;
        }
    }
}

判定依据

  • 入侵者绘制为纯黑色(Color.BLACK),其 RGB 均为 0,灰度值 = 0。代码取阈值 < 10

  • 一旦发现黑色像素,再通过坐标范围判断该像素是否落在某个入侵者的矩形包围盒 内(intruder.xintruder.x+sizey 同理)。

攻击效果

  • 将无人机的速度设置为入侵者的速度,从而实现"跟随"。这并非直接扣血,而是模拟锁定并追踪目标。

1.3 无人机扫描入侵者:扣血攻击

1.3.1 扫描循环结构
复制代码
for (int i = 0; i < intruderList.size(); i++) {
    Intruder intruder = intruderList.get(i);
    if (intruder.HP <= 0) {
        continue;
    }
    for (int j = intruder.x - 15; j < intruder.x + 70; j++) {
        boolean flag = false;
        for (int k = intruder.y - 15; k < intruder.y + 70; k++) {
            // 像素检测...
        }
        if (flag) break;
    }
}
  • 外层循环:遍历所有入侵者。

  • 健康检查 :跳过已死亡(HP <= 0)的入侵者。

  • 扫描区域 :从 x-15x+70y-15y+70。入侵者自身大小为 45,该区域比自身略大(左右各扩大约 15 像素),用于检测靠近的无人机。

1.3.2 像素级判定逻辑
复制代码
int colorNum = image.getRGB(j, k);
Color color = new Color(colorNum);
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
if (gray > 30 && gray < 150 && color.getRed() < 100) {
    intruder.HP -= 1;
    System.out.println("入侵者被检测到~" + intruder.HP);
    flag = true;
    break;
}

判定依据

  • 无人机机体颜色为紫色 (94,20,223),计算其灰度 ≈ (94+20+223)/3 ≈ 112,红色分量 94 < 100。

  • 因此阈值设为 gray > 30 && gray < 150 && color.getRed() < 100,能够匹配紫色区域,同时排除背景白色(灰度 255)和红色边框(红色分量 255)。

攻击效果

  • 入侵者每被检测到一次,HP 减 1。

  • HP 初始为 100,归零后不再绘制和移动,视为被摧毁。


项目运行展示


项目开发阻碍

1.程序运行一段时间后崩溃,报数组越界异常

现象程序运行几分钟,或频繁点击生成按钮后直接崩溃,控制台报ArrayIndexOutOfBoundsException。

根本原因

  1. 多线程并发修改集合:EDT 线程(监听器)往ArrayList里 add 对象,子线程在遍历ArrayList,导致并发修改异常或数组越界
  2. 调用image.getRGB(i,j)时,i 或 j 超出了BufferedImage的 1200x950 范围,导致数组越界
  3. 用 fori 循环遍历集合时,集合中的元素被移除,导致索引超出集合当前长度

解决方案

修改扫描区域、图像边界、无人机移动范围、入侵者移动范围,通过画图计算,不让扫描区域超出图像边界。

(AI提供解决方案:

  1. 对集合的操作加锁,或使用线程安全的集合CopyOnWriteArrayList,避免并发修改问题
  2. 调用getRGB()前,先判断 i 和 j 是否在图片尺寸范围内,超出则直接跳过
  3. 遍历集合时使用迭代器Iterator,或倒序遍历,避免增删元素导致的索引越界)

后续改进方向

1.完善智能对抗策略

  1. 实现需求文档中定义的定点清除移动目标拦截两种对抗模式,针对固定目标和移动目标采用不同的追踪策略
  2. 加入移动目标位置预测,根据入侵者的当前速度和位置,预测下一帧的坐标,提前进行拦截,而非单纯的速度同步
  3. 实现广播机制任务分配机制,让所有无人机共享入侵者信息,每个无人机同一时间只锁定一个目标,避免资源浪费,实现多无人机协同围剿
  4. 加入无人机优先级策略,优先拦截距离防守区最近的入侵者,提升防御效果

2.性能与检测逻辑优化

  1. 优化扫描检测逻辑,采用矩形粗筛 + 像素精检的方式,先判断边界是否相交,再执行像素检测,大大减少循环次数,降低 CPU 占用
  2. 优化颜色识别逻辑,采用特定颜色通道区分目标,提升检测准确率,避免背景干扰
  3. 优化双缓冲逻辑,复用BufferedImage对象,避免每一帧都创建新的对象,减少 GC 压力

3.玩法与 UI 交互扩展

  1. 加入可视化的血量条、得分系统、击杀数统计,提升交互体验
  2. 加入难度等级系统,随着游戏时间增加,入侵者的数量、速度、血量逐步提升,增加游戏挑战性
  3. 加入暂停、继续、重置游戏、调整难度的按钮,完善游戏的基础功能
  4. 给无人机和入侵者加入等级系统,不同等级的无人机有不同的扫描范围、移动速度、攻击力
  5. 加入音效系统,扫描到目标、击杀入侵者时播放对应音效,提升游戏沉浸感
相关推荐
问水っ几秒前
Qt高级编程 第7章 用QtConcurrent实现线程处理
java·开发语言
SimonKing1 分钟前
AI编程工具装了一大堆,Skills 管理乱成粥?这个开源神器一招搞定!
java·后端·程序员
one_love_zfl4 分钟前
java面试-微服务篇
java·微服务·面试
代码中介商5 分钟前
C语言进程管理与内存管理深度解析
c语言·开发语言
郝学胜-神的一滴12 分钟前
系统设计:新鲜事系统扩展与优化
java·python·职场和发展·php·软件工程·软件构建
噜噜噜噜鲁先森13 分钟前
STL——String类
开发语言·c++·算法
爱吃烤鸡翅的酸菜鱼13 分钟前
Maven中BOM(Bill of Materials)的使用详解
java·中间件·maven·源代码管理
matlabgoodboy14 分钟前
ROS代做机械臂导航路径规划激光雷达SLAM三维重建点云无人机视觉
无人机
沐知全栈开发15 分钟前
Bootstrap 下拉菜单
开发语言