Java 智能仿真无人机项目 4.0 核心实现
介绍 Java 智能仿真无人机项目 V4 版本的核心升级,包括定点任务处理、鼠标交互、多线程协作及状态机管理。通过新增 Task 实体类、TaskProThread 线程及 DroneListener 监听器,实现了任务生成、分配、执行及完成的闭环流程。内容涵盖项目结构解析、关键代码实现(距离计算、速度适配、状态可视化)及常见问题排查,帮助开发者掌握复杂模块拆分与多线程协同逻辑。

介绍 Java 智能仿真无人机项目 V4 版本的核心升级,包括定点任务处理、鼠标交互、多线程协作及状态机管理。通过新增 Task 实体类、TaskProThread 线程及 DroneListener 监听器,实现了任务生成、分配、执行及完成的闭环流程。内容涵盖项目结构解析、关键代码实现(距离计算、速度适配、状态可视化)及常见问题排查,帮助开发者掌握复杂模块拆分与多线程协同逻辑。

V4 版本在 V3'双向对抗'基础上,新增定点任务处理、鼠标交互、多线程协作、状态机管理四大核心功能,新手需在 V3 基础(集合、线程通信、扫描攻击)上,额外掌握以下知识点:
MouseListener)MouseListener,需重写 5 个方法(重点用 mousePressed:鼠标按压时触发);mousePressed 方法→获取鼠标点击坐标。代码实现:
(int) Math.sqrt((t.x - d.x)*(t.x - d.x) + (t.y - d.y)*(t.y - d.y));
公式:两点(无人机坐标(x1,y1)、任务坐标(x2,y2))距离 dis =
TaskProThread(任务处理线程),与原有 DroneThread(无人机线程)协同工作;droneList 和 taskList,实现'任务生成→分配→执行→完成'的闭环。0(巡逻)、1(跟随入侵者)、2(处理任务);state 属性实现。runSpeedx 和 runSpeedy,让无人机飞向任务点。V4 版本的核心变化是新增'任务体系',实现'鼠标点击生成任务→系统分配给最近无人机→无人机完成任务后回归巡逻'的完整流程,同时保留 V3 的双向对抗功能,形成'任务处理 + 敌对对抗'的复合场景。
| 类名 | 作用 | 核心新增技术点 |
|---|---|---|
Task | 任务实体类(存储任务坐标、状态、生命值) | 任务可视化绘制、状态管理(未分配 / 已分配 / 完成) |
TaskProThread | 任务处理线程(分配任务、监控任务进度) | 距离计算、最近无人机匹配、速度调整 |
Drone | 无人机实体类(新增状态、任务相关属性) | 多状态管理、状态可视化(颜色区分)、速度适配 |
DroneListener | 监听器(新增鼠标监听,生成任务) | MouseListener、鼠标坐标获取 |
DroneThread | 核心线程(保留对抗 + 新增任务绘制) | 状态判断、任务与对抗逻辑兼容 |
DroneUI | 界面搭建(新增任务集合、鼠标监听器注册) | 多集合共享、鼠标监听器绑定 |
Intruder | 入侵者实体类(优化边界、新增生命值显示) | 边界调整、生命值可视化 |
Task(任务类)Task 类是'定点任务'的载体,封装了任务的核心信息,支持可视化绘制和状态管理。
import java.awt.Graphics; import java.awt.Color; public class Task { int x; // 任务点 x 坐标(鼠标点击位置) int y; // 任务点 y 坐标 int state; // 任务状态:0=未分配,1=已分配,2=已完成 int blood; // 任务生命值(需无人机攻击多次完成) // 构造方法:创建任务时初始化坐标和状态 public Task(int x, int y, int state) { this.x = x; this.y = y; this.state = state; this.blood = 10; // 初始生命值 10(需攻击 10 次完成) } // 绘制任务点(可视化,新手能直观看到任务位置) public void draw(Graphics g) { if (blood <= 0) { state = 2; // 生命值为 0,标记为已完成 return; } g.setColor(Color.BLACK); // 绘制任务点:黑色矩形(左上角 (x,y),宽 80,高 80) g.fillRect(x, y, 80, 80); } // Getter/Setter 方法:获取/修改坐标、状态(供其他类访问) 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 getState() { return state; } public void setState(int state) { this.state = state; } }
0-1-2 的状态流转,确保任务不会重复分配,符合'生成→分配→完成'的逻辑;TaskProThread(任务处理线程)这是 V4 版本的核心新增线程,负责'任务分配'和'任务进度监控',是连接'任务生成'和'无人机执行'的桥梁。
import java.util.ArrayList; public class TaskProThread extends Thread { ArrayList<Drone> droneList; // 共享无人机集合 ArrayList<Task> taskList; // 共享任务集合 public void run() { while (true) { // 死循环:持续监控任务 try { Thread.sleep(30); // 每 30 毫秒检查一次,避免频繁计算 } catch (InterruptedException e) { throw new RuntimeException(e); } // 遍历所有任务,寻找未分配的任务(state=0) for (int i = 0; i < taskList.size(); i++) { Task t = taskList.get(i); if (t.state == 0) { // 找到未分配的任务 int minDis = 1000; // 初始化最小距离(足够大即可) int targetDroneIndex = 0; // 最近无人机的索引 // 遍历所有无人机,找到距离任务点最近的空闲无人机(state=0:巡逻中) for (int j = 0; j < droneList.size(); j++) { Drone d = droneList.get(j); // 跳过正在跟随入侵者(state=1)或处理其他任务(state=2)的无人机 if (d.state == 1 || d.state == 2) { continue; } // 勾股定理计算无人机到任务点的距离 int dis = (int) Math.sqrt( (t.x - d.x) * (t.x - d.x) + (t.y - d.y) * (t.y - d.y) ); // 更新最小距离和对应的无人机索引 if (dis < minDis) { minDis = dis; targetDroneIndex = j; } } // 给最近的无人机分配任务 Drone targetDrone = droneList.get(targetDroneIndex); // 计算无人机到任务点的坐标差(用于调整速度方向) int dx = t.x - targetDrone.x; // x 方向差值(任务点 - 无人机 x) int dy = t.y - targetDrone.y; // y 方向差值(任务点 - 无人机 y) // 记录任务索引(无人机执行时需对应任务) targetDrone.tindex = i; // 基础速度(取无人机原有速度的绝对值,保证速度大小不变) int baseSpeedX = Math.abs(targetDrone.speedx); int baseSpeedY = Math.abs(targetDrone.speedy); // 调整 x 方向速度:无人机在任务点左边(dx>0)则向右飞(+baseSpeedX),否则向左(-baseSpeedX) targetDrone.runSpeedx = dx > 0 ? baseSpeedX : -baseSpeedX; // 调整 y 方向速度:同理,确保飞向任务点 targetDrone.runSpeedy = dy > 0 ? baseSpeedY : -baseSpeedY; // 更新状态:任务改为'已分配'(state=1),无人机改为'处理任务'(state=2) t.state = 1; targetDrone.state = 2; } } // 监控任务执行进度:无人机到达任务点后,扣除任务生命值 if (taskList.size() > 0) { for (int i = 0; i < droneList.size(); i++) { Drone d = droneList.get(i); if (d.state == 2) { // 只处理正在执行任务的无人机 Task t = taskList.get(d.tindex); // 获取对应的任务 // 判断无人机是否到达任务点(无人机中心 +120 像素,覆盖任务矩形范围) if (d.x + 120 >= t.x && d.x + 120 <= t.x + 80 && d.y + 120 >= t.y && d.y + 120 <= t.y + 80) { d.runSpeedx = 0; // 到达后停止移动 d.runSpeedy = 0; t.blood--; // 扣除任务生命值(完成一次处理) } // 任务完成(生命值≤0):重置无人机和任务状态 if (t.blood <= 0) { d.state = 0; // 无人机回归巡逻状态 d.tindex = 0; // 清空任务索引 t.state = 2; // 任务标记为已完成 } } } } } } }
任务分配流程
距离计算的意义
Math.sqrt 的代码即可,重点关注'距离对比'的逻辑。速度调整逻辑
dx(x 方向差值)判断无人机在任务点的左 / 右,通过 dy 判断上 / 下;dx>0(任务点在无人机右边),则 runSpeedx=baseSpeedX(向右飞),反之向左飞,确保无人机精准飞向任务点。Drone(多状态管理)V4 版本的 Drone 类新增了状态、任务索引、运行速度等属性,支持'巡逻→跟随→任务'的状态切换,且状态通过颜色可视化。
import java.awt.Graphics; import java.awt.Color; public class Drone { // 原有属性(坐标、速度、尺寸等) int x, y, speedx, speedy, size; // 新增属性:任务相关 int tindex; // 绑定的任务索引(对应 taskList 中的位置) int state; // 状态:0=巡逻,1=跟随入侵者,2=处理任务 // 新增属性:速度控制(runSpeedx/y 是实际运行速度,可动态调整) int runSpeedx, runSpeedy; // 原有属性(雷达范围、状态灯尺寸) int stateSize; int scanSize; // 构造方法:初始化属性,默认状态为 0(巡逻) public Drone(int x, int y, int state, int speedx, int speedy) { this.x = x; this.y = y; this.state = state; // 初始状态:巡逻(0) this.size = 30; this.stateSize = 15; this.scanSize = 100; this.speedx = speedx; this.speedy = speedy; this.runSpeedx = speedx; // 初始运行速度=默认速度 this.runSpeedy = speedy; } // 绘制无人机(新增状态颜色区分,可视化关键) public void drawDrone(Graphics bg) { // 1. 绘制雷达范围(蓝色半透明椭圆,与 V3 一致) Color color1 = new Color(0, 0, 255, 60); bg.setColor(color1); bg.fillOval(x, y, scanSize, scanSize); // 2. 绘制无人机主体(绿色椭圆,与 V3 一致) Color color2 = new Color(64, 195, 66); bg.setColor(color2); bg.fillOval(x + 35, y + 35, size, size); // 3. 绘制状态灯(根据状态改变颜色,新手直观区分) Color color3; if (state == 0) { // 巡逻状态:红色 color3 = new Color(255, 0, 0); } else { // 跟随(1)或处理任务(2):黄色 color3 = new Color(255, 255, 0); } bg.setColor(color3); bg.fillOval(x + 42, y + 42, stateSize, stateSize); } // 移动方法(根据状态调整速度,核心逻辑) public void move() { // 巡逻状态(state=0):使用默认速度,随机运动 if (state == 0) { runSpeedx = speedx; runSpeedy = speedy; } // 边界检测(与 V3 类似,优化反弹逻辑) // 水平边界:左 200,右 800(防守区范围) if (x > 300 + 600 || x < 200) { if (x < 200) { runSpeedx = -runSpeedx; // 反弹 speedx = -speedx; x += size; // 避免卡在边界 } else { runSpeedx = -runSpeedx; speedx = -speedx; x -= size; } } // 垂直边界:上 175,下 675(防守区范围) if (y > 175 + 500 || y < 175) { if (y < 175) { runSpeedy = -runSpeedy; speedy = -speedy; y += size; } else { runSpeedy = -runSpeedy; speedy = -speedy; y -= size; } } // 更新坐标(使用 runSpeedx/y,支持动态速度调整) x += runSpeedx; y += runSpeedy; } }
状态管理与可视化:
state 属性实现(如任务分配时设为 2,任务完成后设为 0);speedx/y 是默认速度(巡逻时用),runSpeedx/y 是实际运行速度(跟随 / 任务时动态调整),避免速度冲突。DroneListener(新增鼠标监听)监听器同时实现 ActionListener(按钮监听)和 MouseListener(鼠标监听),支持'生产无人机 / 入侵者'和'鼠标点击生成任务'两种交互。
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Random; public class DroneListener implements ActionListener, MouseListener { // 共享集合:无人机、入侵者、任务(与 UI 线程、其他线程共用) ArrayList<Drone> droneList; ArrayList<Intruder> intruderList; ArrayList<Task> taskList; Random random = new Random(); // 按钮监听逻辑(与 V3 一致,生产无人机/入侵者) public void actionPerformed(ActionEvent e) { String ac = e.getActionCommand(); if (ac.equals("生产无人机")) { int x = random.nextInt(700) + 200; int y = random.nextInt(500) + 175; int speedx = random.nextInt(5) - 2; int speedy = random.nextInt(5) - 2; droneList.add(new Drone(x, y, 0, speedx, speedy)); // 初始状态 0:巡逻 } else if (ac.equals("生产入侵者")) { int x = random.nextInt(1200 - 205) + 60; int y = random.nextInt(950 - 205) + 60; // 确保入侵者初始在防守区外 while (true) { if (x < 200 || x > 900 || y < 175 || y > 675) { break; } x = random.nextInt(1200 - 205) + 60; y = random.nextInt(950 - 205) + 60; } int speedx = random.nextInt(5) - 2; int speedy = random.nextInt(5) - 2; intruderList.add(new Intruder(x, y, speedx, speedy, 45)); } } // 新增:鼠标按压时触发(生成任务) public void mousePressed(MouseEvent e) { // 获取鼠标点击的坐标(e.getX()=x,e.getY()=y) int x = e.getX(); int y = e.getY(); // 创建任务对象(状态 0:未分配) Task task = new Task(x, y, 0); taskList.add(task); // 存入任务集合 System.out.println("生成任务,坐标:(" + x + "," + y + ")"); } // 以下 4 个方法是 MouseListener 接口必须重写的,无需实现逻辑,留空即可 public void mouseClicked(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }
鼠标监听使用:
MouseListener 的 5 个方法,即使不用也不能删除(否则编译报错);e.getX() 和 e.getY() 获取的是鼠标在窗口内的坐标,直接用于创建任务点,精准对应点击位置;DroneUI 中调用 addMouseListener(droneL),否则鼠标点击无反应。DroneUI(新增任务集合与线程)DroneUI 类新增任务集合(taskList)和任务处理线程(TaskProThread),并注册鼠标监听器,是整个项目的'中枢调度中心'。
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<>(); // 新增集合:任务 ArrayList<Task> taskList = new ArrayList<>(); public DroneUI() { // 窗口基础设置(与 V3 一致) setTitle("智能无人机平台"); setSize(1200, 1000); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null); // 按钮面板(与 V3 一致) JPanel btnPanel = new JPanel(); btnPanel.setBackground(Color.LIGHT_GRAY); JButton btn = new JButton("生产无人机"); JButton btn1 = new JButton("生产入侵者"); btnPanel.add(btn); btnPanel.add(btn1); add(btnPanel, BorderLayout.SOUTH); setVisible(true); // 初始化绘图工具、监听器、线程 Graphics g = this.getGraphics(); DroneThread dt = new DroneThread(g); // 无人机线程 DroneListener droneL = new DroneListener(); // 监听器(按钮 + 鼠标) TaskProThread tpt = new TaskProThread(); // 新增:任务处理线程 // 注册监听 btn.addActionListener(droneL); btn1.addActionListener(droneL); addMouseListener(droneL); // 新增:注册鼠标监听器 // 共享集合传递(关键!所有线程共用同一个集合) droneL.droneList = droneList; droneL.intruderList = intruderList; droneL.taskList = taskList; // 监听器获取任务集合 dt.droneList = droneList; dt.intruderList = intruderList; dt.taskList = taskList; // 无人机线程获取任务集合 tpt.droneList = droneList; // 任务线程获取无人机集合 tpt.taskList = taskList; // 任务线程获取任务集合 // 启动线程(两个线程并行工作) dt.start(); tpt.start(); // 新增:启动任务处理线程 } // 重写 paint 方法 public void paint(Graphics g) { super.paint(g); } public static void main(String[] args) { new DroneUI(); } }
多线程协同:
DroneThread 负责绘制和对抗,TaskProThread 负责任务分配,通过共享集合通信,互不干扰;taskList 传递给监听器(生成任务)、无人机线程(绘制任务)、任务线程(分配任务),否则功能失效。Intruder(边界调整 + 生命值可视化)V4 版本的 Intruder 类优化了边界判断,新增生命值可视化(新手能看到入侵者剩余血量)。
import java.awt.Graphics; import java.awt.Color; public class Intruder { // 入侵者属性 int x, y; // 坐标 int speedx, speedy; // 速度 int 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 } // 行为 1:绘制入侵者 public void drawIntruder(Graphics g) { if (blood <= 0) { // 生命值≤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); // 绘制红色边框 } // 行为 2:入侵者移动 public void move() { if (blood <= 0) { return; } // 边界调整:左 60,右 1200-145,上 60,下 950-145(扩大运动范围,预留安全距离) if (x > 1200 - 145 || x < 60) { speedx = -speedx; } if (y > 950 - 145 || y < 60) { speedy = -speedy; } x += speedx; y += speedy; } // 生命值可视化(在 DroneThread 的入侵者扫描逻辑中添加) g.setColor(Color.BLACK); // 绘制生命值背景框(入侵者上方) g.drawRect(intruder.x, intruder.y - 22, 20, 10); g.setColor(Color.GREEN); // 绘制当前生命值(按比例填充绿色) g.fillRect(intruder.x + 1, intruder.y - 21, (int)(intruder.blood / 100.0 * 20), 8); g.setColor(Color.RED); // 绘制生命值数字(直观显示) g.drawString("" + intruder.blood, intruder.x + 18, intruder.y); }
生命值可视化:
blood 比例变化(如 blood=50 时,填充 10 像素);blood 值,新手无需计算,一眼就能看到入侵者剩余血量。addMouseListener(droneL));mousePressed 方法名写错(如写成 mousePress);MouseListener 的 5 个方法都重写。if (d.state == 1 || d.state == 2)),导致分配给正在跟随 / 处理任务的无人机;state=1 和 state=2 的无人机,只选择 state=0 的空闲无人机。dx>0 时设为 -baseSpeedX,方向相反);runSpeedx/y 未正确赋值,仍使用默认速度;dx>0 时 runSpeedx=baseSpeedX,dx<0 时为 -baseSpeedX。state 重置为 0;TaskProThread 的任务监控逻辑中,添加 d.state = 0(任务完成后重置状态)。taskList 是否为空,直接调用 taskList.get(d.tindex);if (taskList.size() == 0) continue;,避免空集合访问。Supply 类(属性:x、y、type,方法:draw);Supply 对象存入 supplyList;supplyList,无人机靠近补给点时,恢复电量 / 弹药;supplyList 中移除。Task 类新增 priority 属性(1 = 低,2 = 中,3 = 高);TaskProThread 中,先遍历高优先级任务,再处理中、低优先级。TaskProThread 的任务分配逻辑,遍历所有未分配任务,为每个任务分别匹配最近的空闲无人机(避免一个无人机同时处理多个任务)。Task 类新增 createTime 属性(记录生成时间),TaskProThread 中判断当前时间与 createTime 的差值,超过 30 秒则重置任务状态。V4 版本完成了从'单纯对抗'到'任务 + 对抗'的复合场景升级,核心收获如下:
MouseListener 实现鼠标交互,理解'用户操作→事件触发→逻辑执行'的完整链路;对于 Java 新手,V4 版本的学习重点是'模块拆分'和'逻辑协同'—— 复杂项目并非一蹴而就,而是将'任务生成''任务分配''状态管理''对抗逻辑'拆分为多个模块,每个模块负责单一功能,再通过共享数据和线程协作整合。通过本项目,你不仅巩固了多线程、集合、Swing 等基础,还培养了'需求拆解→代码实现→优化迭代'的编程思维,为后续开发更复杂的 Java 应用(如管理系统、小游戏)奠定了坚实基础。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online