《智能仿真无人机平台(多线程 V4.0)技术笔记》(集群进阶:多无人机任务分配与碰撞规避)

本次实现的是一个具备任务分配、入侵者检测与攻击、自主巡逻功能的智能无人机可视化平台,采用多线程机制保证无人机、任务、入侵者的并发运行。整个项目共包含7个核心类,下面逐类进行详细解析。

1. Drone 类(无人机核心实体)

该类是无人机的实体定义,封装了无人机的位置、速度、尺寸、状态等属性,同时提供了绘制、移动、状态修改的核心方法。
packageduoxiancheng.xq0129.dronev4;importjava.awt.*;/** * @author xuqiang * @date 2026/1/22 16:07 * @description 无人机实体类,封装属性与核心行为(绘制、移动) */publicclassDrone{int x,y;// 无人机坐标(左上角)int speedx,speedy;// 横、纵方向速度int size;// 无人机主体尺寸int state;// 无人机状态(0=巡逻,1=攻击/任务执行,2=补充弹药)int stateSize;// 无人机状态指示灯尺寸int scanSize;// 无人机雷达扫描范围尺寸// 构造方法:初始化无人机核心属性,默认赋值尺寸相关常量publicDrone(int x,int y,int state,int speedx,int speedy){this.x=x;this.y=y;this.state=state;this.speedx=speedx;this.speedy=speedy;this.size=30;// 无人机主体固定尺寸30this.stateSize=15;// 状态指示灯固定尺寸15this.scanSize=100;// 雷达扫描范围固定尺寸100(圆形)}// 绘制无人机:雷达→主体→状态指示灯,分层绘制实现可视化publicvoiddrawDrone(Graphics bg){// 1. 绘制半透明蓝色雷达扫描范围(第四个参数60是透明度,实现半透效果)Color radarColor =newColor(0,0,255,60); bg.setColor(radarColor); bg.fillOval(x, y, scanSize, scanSize);// 2. 绘制无人机绿色主体(偏移35像素,让主体位于雷达中心)Color bodyColor =newColor(64,195,66); bg.setColor(bodyColor); bg.fillOval(x +35, y +35, size, size);// 3. 绘制状态指示灯,根据state切换颜色(核心:状态与颜色绑定)Color stateColor;switch(state){case1:// 攻击状态/任务执行状态 - 红色 stateColor =Color.RED;break;case0:// 巡逻状态 - 黄色 stateColor =Color.YELLOW;break;case2:// 补充弹药状态 - 灰色 stateColor =Color.GRAY;break;default:// 默认巡逻状态,防止异常状态无显示 stateColor =Color.YELLOW;break;} bg.setColor(stateColor); bg.fillOval(x +42, y +42, stateSize, stateSize);// 偏移42像素,让指示灯位于主体中心}// 无人机移动方法:边界检测→位置修正→坐标更新,防止卡墙publicvoidmove(){// 1. 先判断边界,反转速度(左右边界200~1000,上下边界175~775)boolean hitX =false;boolean hitY =false;if(x <200||(x + scanSize)>1000){// 雷达右边界不超过1000,避免超出红色区域 speedx =-speedx;// 碰到左右边界,横向速度反转 hitX =true;}if(y <175||(y + scanSize)>775){// 雷达下边界不超过775,避免超出红色区域 speedy =-speedy;// 碰到上下边界,纵向速度反转 hitY =true;}// 2. 如果碰到了边界,先修正位置再移动,避免卡墙(核心:边界修正逻辑)if(hitX){ x =Math.max(200,Math.min(1000- scanSize, x));// 强制将x限制在有效区间内}if(hitY){ y =Math.max(175,Math.min(775- scanSize, y));// 强制将y限制在有效区间内}// 3. 更新坐标,实现移动 x += speedx; y += speedy;}// 新增:方便外部修改无人机状态的方法(提供状态设置入口,解耦外部调用)publicvoidsetState(int state){this.state = state;}// 新增:获取当前状态的方法(提供状态查询入口,支持外部逻辑判断)publicintgetState(){returnthis.state;}}

Drone 类关键点

  1. 属性封装:包含位置(x/y)、速度(speedx/speedy)、尺寸(size/scanSize)、状态(state)三大类核心属性,尺寸相关属性在构造方法中默认赋值,保证一致性。
  2. 分层绘制:按照「雷达→主体→状态指示灯」的层级绘制,雷达设置半透明效果,状态指示灯根据state值切换颜色,实现状态可视化区分。
  3. 安全移动:包含边界检测、位置修正、坐标更新三步逻辑,Math.max()Math.min()结合避免无人机卡墙,提升运行流畅性。
  4. 状态访问器:提供setState()getState()方法,封装state属性的读写,符合面向对象封装原则,方便外部类(如TaskThread)进行状态控制。
  5. 坐标偏移:无人机主体和指示灯通过坐标偏移实现居中显示,让可视化效果更规整。

2. Intruder 类(入侵者核心实体)

该类是入侵者的实体定义,封装了入侵者的位置、速度、尺寸、血量等属性,提供绘制和移动方法,同时支持血量可视化与死亡判定。
packageduoxiancheng.xq0129.dronev4;importjava.awt.*;/** * @author xuqiang * @date 2026/1/22 16:31 * @description 入侵者实体类,封装属性与核心行为(绘制、移动、血量管理) */publicclassIntruder{int x,y;// 入侵者坐标(左上角)int speedx,speedy;// 横、纵方向速度int size;// 入侵者主体尺寸int blood;// 入侵者血量(100为满血,≤0为死亡)publicIntruder(int x,int y,int speedx,int speedy,int size){this.x=x;this.y=y;this.speedx=speedx;this.speedy=speedy;this.size=45;// 入侵者主体固定尺寸45,不依赖传入参数this.blood=100;// 满血初始化为100}// 绘制入侵者:主体→血条,死亡后不进行绘制(核心:血量判定与可视化)publicvoiddrawIntruder(Graphics g){if(blood <=0){// 血量≤0判定为死亡,不绘制任何内容return;}// 1. 绘制入侵者黑色主体 g.setColor(Color.BLACK); g.fillOval(x,y,size,size);// 2. 绘制红色边框,增强辨识度 g.setColor(Color.RED); g.drawOval(x-1,y-1,size+2,size+2);// 3. 绘制血条背景(红色) g.setColor(Color.RED); g.fillRect(x,y+size+5,size,6);// 4. 绘制当前血量(绿色),按比例计算血条宽度(核心:血量比例换算)int bloodWidth =(int)((blood/100.0)*size);// 满血对应血条宽度=入侵者尺寸 g.setColor(Color.GREEN); g.fillRect(x,y+size+5,bloodWidth,6);}// 入侵者移动方法:死亡后停止移动,边界检测后速度反转publicvoidmove(){if(blood <=0){// 死亡后不再执行移动逻辑,节省资源return;}// 边界检测:整体窗口范围(5~1200,25~950),碰到边界反转速度if(x <5||(x+size+5)>1200){ speedx =-speedx;}if(y <25||(y+size+5)>950){ speedy =-speedy;}// 更新坐标,实现移动 x += speedx; y += speedy;}}

Intruder 类关键点

  1. 血量机制:初始血量为100,blood≤0时判定为死亡,停止绘制和移动,减少无效计算。
  2. 血条可视化:采用「红色背景+绿色当前血量」的双层血条设计,通过(blood/100.0)*size实现血量与血条宽度的比例换算,直观展示入侵者存活状态。
  3. 独立边界:入侵者的移动边界为整个窗口(51200,25950),与无人机的有效区域(2001000,175775)区分,符合业务逻辑。
  4. 固定尺寸:入侵者主体尺寸固定为45,构造方法中忽略传入的size参数,保证所有入侵者可视化效果一致。
  5. 边框增强:在主体外围绘制红色边框,提升入侵者在窗口中的辨识度,方便观察无人机与入侵者的交互。

3. Task 类(任务核心实体)

该类是任务的实体定义,封装了任务的位置、状态、血量等属性,提供绘制方法与属性访问器/修改器,支持任务的分配、执行与完成判定。
packageduoxiancheng.xq0129.dronev4;importjava.awt.*;/** * @author xuqiang * @date 2026/1/29 16:29 * @description 任务实体类,封装属性与绘制方法,支持任务生命周期管理 */publicclassTask{int x;// 任务坐标(左上角)int y;// 任务坐标(左上角)int state;// 任务状态(0=未分配,1=已分配,2=已完成)int blood;// 任务血量(1为初始,≤0为完成)// 构造方法:初始化任务坐标与状态,默认血量为1publicTask(int x,int y,int state){this.x = x;this.y = y;this.state = state;this.blood =1;// 任务初始血量为1,扣至≤0即完成}// 绘制任务:完成后标记状态为2并停止绘制,未完成绘制黑色圆形publicvoiddraw(Graphics g){if(blood <=0){// 任务血量≤0判定为完成,标记状态为2并停止绘制this.state =2;return;}// 绘制任务黑色圆形主体,尺寸40 g.setColor(Color.BLACK); g.fillOval(x,y,40,40);}// 属性访问器与修改器:封装所有属性,提供外部读写入口(符合面向对象封装原则)publicintgetX(){return x;}publicvoidsetX(int x){this.x = x;}publicintgetY(){return y;}publicvoidsetY(int y){this.y = y;}publicintgetState(){return state;}publicvoidsetState(int state){this.state = state;}publicintgetBlood(){return blood;}publicvoidsetBlood(int blood){this.blood = blood;}}

Task 类关键点

  1. 任务生命周期:通过state属性管理任务的三个状态(0=未分配、1=已分配、2=已完成),通过blood属性控制任务完成条件,形成「创建→分配→执行→完成」的完整生命周期。
  2. 简化完成逻辑:任务初始血量为1,blood≤0时自动标记为已完成(state=2),停止绘制,逻辑简洁高效。
  3. 完整访问器:为所有属性提供getXXX()setXXX()方法,封装属性读写,方便TaskThread进行任务状态与血量的修改和查询。
  4. 固定可视化:未完成的任务绘制为40尺寸的黑色圆形,样式统一,方便无人机识别与追踪。
  5. 坐标绑定:任务坐标通过鼠标点击传入,限定在无人机有效区域内,保证任务的可执行性。

4. DroneUI 类(窗口界面核心,程序入口)

该类是整个平台的窗口界面载体,基于Swing的JFrame实现,负责初始化窗口、创建组件、管理集合、绑定监听器与启动多线程,是程序的入口与核心调度者。
packageduoxiancheng.xq0129.dronev4;importjavax.swing.*;importjava.awt.*;importjava.util.ArrayList;/** * @author xuqiang * @date 2026/1/22 18:53 * @description 窗口界面类,程序入口,负责界面初始化、组件绑定与线程启动 */publicclassDroneUIextendsJFrame{// 三大核心集合:管理所有无人机、入侵者、任务(全局共享,供多线程访问)ArrayList<Drone> droneList =newArrayList<>();ArrayList<Intruder> intruderList =newArrayList<>();ArrayList<Task> taskList =newArrayList<>();// 任务集合,存储所有创建的任务publicDroneUI(){// 1. 窗口基础配置(标题、尺寸、关闭方式、居中显示)setTitle("智能无人机平台");setSize(1200,1000);setDefaultCloseOperation(EXIT_ON_CLOSE);// 关闭窗口时退出整个程序setLocationRelativeTo(null);// 窗口居中显示// 2. 底部按钮面板创建(存放生产无人机、入侵者按钮)JPanel btnPanel =newJPanel(); btnPanel.setBackground(Color.LIGHT_GRAY);JButton createDroneBtn =newJButton("生产无人机"); btnPanel.add(createDroneBtn);JButton createIntryderBtn =newJButton("生产入侵者"); btnPanel.add(createIntryderBtn);// 3. 面板布局:按钮面板放在窗口底部(BorderLayout.SOUTH)add(btnPanel,BorderLayout.SOUTH);setVisible(true);// 显示窗口Graphics g =this.getGraphics();// 获取窗口绘图上下文,供线程绘制使用// 4. 多线程创建:无人机线程(负责绘制与交互)、任务线程(负责任务分配与执行)DroneThread dt =newDroneThread(g);TaskThread tpt =newTaskThread();// 任务线程,处理任务相关逻辑// 5. 监听器创建与绑定:绑定按钮事件与鼠标点击事件DroneListener droneL =newDroneListener(); droneL.taskList = taskList;// 给监听器注入任务集合,支持鼠标创建任务 createDroneBtn.addActionListener(droneL);// 绑定「生产无人机」按钮点击事件 createIntryderBtn.addActionListener(droneL);// 绑定「生产入侵者」按钮点击事件this.addMouseListener(droneL);// 绑定窗口鼠标点击事件,支持创建任务// 6. 集合注入:将全局集合注入到监听器与线程中,实现数据共享(核心:多线程数据共享) droneL.droneList = droneList; dt.droneList = droneList; droneL.intruderList = intruderList; dt.intruderList = intruderList; dt.taskList = taskList; tpt.droneList = droneList;// 任务线程注入无人机集合 tpt.taskList = taskList;// 任务线程注入任务集合// 7. 启动多线程:开始执行无人机逻辑与任务逻辑 dt.start(); tpt.start();// 启动任务线程}// 重写paint方法:调用父类paint方法,保证窗口重绘时的基础渲染(避免窗口闪烁)publicvoidpaint(Graphics g){super.paint(g);}// 程序主方法:入口函数,创建DroneUI实例启动程序publicstaticvoidmain(String[] args){newDroneUI();}}

DroneUI 类关键点

  1. 全局集合管理:创建droneListintruderListtaskList三个ArrayList集合,用于存储所有无人机、入侵者、任务,为多线程数据共享提供载体。
  2. 界面布局:采用BorderLayout布局,底部创建灰色按钮面板,存放「生产无人机」和「生产入侵者」两个功能按钮,界面简洁清晰。
  3. 多线程调度:创建DroneThread(无人机线程)和TaskThread(任务线程),并完成集合注入,最终调用start()方法启动线程,实现并发逻辑。
  4. 监听器绑定:创建DroneListener监听器,绑定按钮点击事件与鼠标点击事件,同时注入全局集合,实现「生产实体」与「创建任务」的功能触发。
  5. 窗口基础配置:设置窗口标题、尺寸、关闭方式与居中显示,获取窗口绘图上下文供线程使用,重写paint()方法保证窗口重绘稳定性。
  6. 程序入口main()方法中直接创建DroneUI实例,启动整个平台,无需额外配置,运行便捷。

5. DroneListener 类(事件监听器,处理用户交互)

该类实现了ActionListenerMouseListener接口,负责处理用户的按钮点击事件(生产无人机、入侵者)与鼠标点击事件(创建任务),是用户与程序的交互桥梁。
packageduoxiancheng.xq0129.dronev4;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseEvent;importjava.awt.event.MouseListener;importjava.util.ArrayList;importjava.util.Random;/** * @author xuqiang * @date 2026/1/22 16:32 * @description 事件监听器类,处理按钮点击与鼠标点击事件,实现用户交互 */publicclassDroneListenerimplementsActionListener,MouseListener{ArrayList<Drone> droneList;// 无人机集合,接收外部注入ArrayList<Intruder> intruderList;// 入侵者集合,接收外部注入ArrayList<Task> taskList;// 任务集合,接收外部注入Random random =newRandom();// 随机数生成器,用于生成随机坐标与速度@OverridepublicvoidactionPerformed(ActionEvent e){String ac = e.getActionCommand();// 获取按钮点击命令文本if(ac.equals("生产无人机")){// 1. 生成无人机随机坐标:限定在无人机有效区域(200~900,175~675)int x =200+random.nextInt(700);int y =175+random.nextInt(500);// 2. 生成随机速度(-2~2)int speedx = random.nextInt(5)-2;int speedy = random.nextInt(5)-2;// 3. 保证速度非0:避免无人机静止不动(核心:防止无效无人机)while(true){if(speedx !=0|| speedy !=0){break;} speedx = random.nextInt(5)-2; speedy = random.nextInt(5)-2;}// 4. 创建无人机实例,加入无人机集合(初始状态0=巡逻)Drone drone =newDrone(x,y,0,speedx,speedy); droneList.add(drone);}elseif(ac.equals("生产入侵者")){// 1. 生成入侵者随机坐标:窗口全局范围int x = random.nextInt(1150)+5;int y = random.nextInt(879)+25;int intruderSize =45;// 2. 保证入侵者不在无人机有效区域内:避免初始就被无人机攻击(核心:业务逻辑隔离)while(true){if(x + intruderSize <=200|| x>=1000|| y+intruderSize <=175|| y>=775){break;} x = random.nextInt(1150)+5; y = random.nextInt(879)+25;}// 3. 生成随机速度(-2~2)int speedx = random.nextInt(5)-2;int speedy = random.nextInt(5)-2;// 4. 保证速度非0:避免入侵者静止不动while(true){if(speedx !=0|| speedy !=0){break;} speedx = random.nextInt(5)-2; speedy = random.nextInt(5)-2;}// 5. 创建入侵者实例,加入入侵者集合Intruder itd =newIntruder(x,y,speedx,speedy,intruderSize); intruderList.add(itd);}}// 鼠标点击事件:未实现(本次使用鼠标按下事件创建任务)@OverridepublicvoidmouseClicked(MouseEvent e){}@OverridepublicvoidmousePressed(MouseEvent e){// 鼠标按下事件:创建任务(核心:任务创建逻辑)int x = e.getX();// 获取鼠标点击横坐标int y = e.getY();// 获取鼠标点击纵坐标// 1. 限定任务创建区域:无人机有效区域内,避免无效任务if(x >=200&& x <=1000-40&& y >=175&& y <=775-40){// 2. 创建未分配状态(state=0)的任务,与业务逻辑一致Task task =newTask(x,y,0); taskList.add(task);System.out.println("生成任务:("+ x +","+ y +")");// 控制台打印,方便调试}}// 鼠标释放事件:未实现@OverridepublicvoidmouseReleased(MouseEvent e){}// 鼠标进入窗口事件:未实现@OverridepublicvoidmouseEntered(MouseEvent e){}// 鼠标退出窗口事件:未实现@OverridepublicvoidmouseExited(MouseEvent e){}}

DroneListener 类关键点

  1. 双接口实现:同时实现ActionListener(处理按钮事件)和MouseListener(处理鼠标事件),统一管理用户交互,简化代码结构。
  2. 无人机生产逻辑:随机生成有效区域内的坐标与非0速度,初始状态为巡逻(state=0),创建后加入droneList集合,保证无人机可被线程调度。
  3. 入侵者生产逻辑:随机生成全局坐标,且保证初始不在无人机有效区域内,生成非0速度,创建后加入intruderList集合,实现业务逻辑隔离。
  4. 任务创建逻辑:通过mousePressed()事件触发,限定在无人机有效区域内创建未分配任务(state=0),控制台打印调试信息,方便追踪任务创建情况。
  5. 非0速度保证:通过while循环过滤速度全为0的情况,避免无人机或入侵者静止不动,保证程序运行的有效性。
  6. 区域限定:所有实体的创建都做了区域限定,避免无效实体创建,提升程序的稳定性与业务合理性。

6. DroneThread 类(无人机核心线程,处理绘制、移动与交互)

该类是核心业务线程,继承Thread类,负责无人机、入侵者、任务的绘制,无人机与入侵者的交互,无人机碰撞检测,以及画面的刷新,是程序可视化与业务交互的核心。
packageduoxiancheng.xq0129.dronev4;importjava.awt.*;importjava.awt.image.BufferedImage;importjava.util.ArrayList;/** * @author xuqiang * @date 2026/1/22 18:53 * @description 无人机核心线程,负责绘制、移动、交互与画面刷新 */publicclassDroneThreadextendsThread{ArrayList<Drone> droneList;// 无人机集合,接收外部注入ArrayList<Intruder> intruderList;// 入侵者集合,接收外部注入ArrayList<Task> taskList;// 任务集合,接收外部注入Graphics g;// 窗口绘图上下文,用于最终画面绘制// 构造方法:传入窗口绘图上下文publicDroneThread(Graphics g){this.g=g;}publicvoidrun(){// 无限循环:保证线程持续运行,实现实时刷新while(true){// 1. 创建缓冲图片:双缓冲技术,避免窗口闪烁(核心:解决界面闪烁问题)BufferedImage img =newBufferedImage(1200,950,2);Graphics bg = img.getGraphics();// 2. 绘制背景与有效区域:白色背景+红色有效区域边框 bg.setColor(Color.WHITE); bg.fillRect(0,0,1200,950); bg.setColor(Color.RED); bg.drawRect(200,175,800,600);// 3. 绘制并移动所有无人机for(int j =0; j < droneList.size(); j++){Drone drone = droneList.get(j); drone.drawDrone(bg); drone.move();}// 4. 绘制所有任务for(int i =0; i < taskList.size(); i++){Task t = taskList.get(i); t.draw(bg);}// 任务绘制,与无人机绘制分离,逻辑清晰// 5. 绘制并移动所有入侵者for(int i =0; i < intruderList.size(); i++){Intruder intruder = intruderList.get(i); intruder.drawIntruder(bg); intruder.move();}// 6. 无人机雷达扫描入侵者:检测到后调整方向并切换攻击状态(核心:无人机与入侵者交互逻辑)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++){// 限定在有效区域内,避免无效扫描if(i<=1000&& i>=200&& j<=775&& j>=175){int colorNum = img.getRGB(i, j);Color c =newColor(colorNum);// 检测黑色像素(入侵者主体),判定为扫描到入侵者if((c.getRed()+c.getBlue()+c.getGreen())/3<10){// 遍历入侵者,确认扫描到的有效入侵者(满血)for(int l =0; l < intruderList.size(); l++){Intruder itr = intruderList.get(l);if(itr.blood >0&& i<itr.x+itr.size && i>=itr.x && j<itr.y+itr.size && j>= itr.y){// 计算无人机到入侵者的方向向量int dx = itr.x - drone.x;int dy = itr.y - drone.y;double distance =Math.sqrt(dx*dx + dy*dy);if(distance >0){// 归一化方向向量,再乘以固定速度3,调整无人机移动方向 drone.speedx =(int)(dx / distance *3); drone.speedy =(int)(dy / distance *3);// 巡逻状态切换为攻击状态if(drone.getState()==0){ drone.setState(1);}}break;// 找到对应入侵者后跳出循环,提升效率}}}}}}}}// 7. 无人机状态优先级更新:任务>入侵者>巡逻(核心:状态优先级逻辑)for(Drone d : droneList){// 遍历所有无人机,更新状态// 第一步:判断是否有未完成的已分配任务(优先级最高)boolean hasUnfinishedTask =false;for(Task task : taskList){if(task.getState()==1&& task.getBlood()>0){int disToTask =(int)Math.sqrt((task.getX()- d.x)*(task.getX()- d.x)+(task.getY()- d.y)*(task.getY()- d.y));if(disToTask <=125){// 任务追踪范围125像素 hasUnfinishedTask =true;break;}}}// 第二步:如果没有任务,再判断是否有有效入侵者boolean hasValidIntruder =false;if(!hasUnfinishedTask){for(Intruder intruder : intruderList){if(intruder.blood >0){int dis =(int)Math.sqrt((d.x - intruder.x)*(d.x - intruder.x)+(d.y - intruder.y)*(d.y - intruder.y));if(dis <=100){// 入侵者检测范围100像素 hasValidIntruder =true;break;}}}}// 第三步:根据优先级更新状态if(hasUnfinishedTask){ d.setState(1);// 保留任务执行状态}elseif(hasValidIntruder){ d.setState(1);// 无任务,有入侵者,进入攻击状态}else{ d.setState(0);// 无任务无入侵者,恢复巡逻状态}}// 状态更新逻辑结束// 8. 入侵者扣血逻辑:被攻击状态无人机扫描到后扣血(核心:入侵者血量消耗逻辑)for(int i =0; i < intruderList.size(); i++){Intruder intruder = intruderList.get(i);if(intruder.blood <=0){continue;}boolean flag =false;// 遍历入侵者主体像素点,检测是否被无人机扫描for(int j = intruder.x; j < intruder.x+45; j++){for(int k = intruder.y; k < intruder.y+45; k++){int colorNum = img.getRGB(j,k);Color c =newColor(colorNum);int gray =(c.getBlue()+c.getRed()+c.getGreen())/3;// 检测无人机绿色主体像素,判定为被无人机扫描if(gray<200&& gray>0&& c.getRed()<150){ flag =true;break;}}if(flag){break;}}if(flag && intruder.blood >0){// 确认有攻击状态的无人机在攻击范围内boolean isAttacking =false;for(Drone d : droneList){if(d.getState()==1){int dis =(int)Math.sqrt((d.x - intruder.x)*(d.x - intruder.x)+(d.y - intruder.y)*(d.y - intruder.y));if(dis <=100){// 攻击范围100像素内 isAttacking =true;break;}}}if(isAttacking){ intruder.blood--;// 每帧扣1血,实现血量持续消耗}}}// 9. 无人机碰撞检测:避免无人机重叠(核心:碰撞检测与分离逻辑)if(droneList.size()>1){for(int i =0; i < droneList.size(); i++){Drone d1 = droneList.get(i);for(int j = i +1; j < droneList.size(); j++){Drone d2 = droneList.get(j);// 判定是否碰撞(距离<50)if(Math.abs(d1.x - d2.x)<50&&Math.abs(d1.y - d2.y)<50){// 轻微推开:每次只移1,避免碰撞后弹开幅度过大 d1.x += d1.x > d2.x ?1:-1; d1.y += d1.y > d2.y ?1:-1; d2.x -= d1.x > d2.x ?1:-1; d2.y -= d1.y > d2.y ?1:-1;// 边界保护:推开后仍限定在有效区域内 d1.x =Math.max(200,Math.min(1000-100, d1.x)); d1.y =Math.max(175,Math.min(775-100, d1.y)); d2.x =Math.max(200,Math.min(1000-100, d2.x)); d2.y =Math.max(175,Math.min(775-100, d2.y));}}}}// 10. 绘制缓冲图片到窗口,实现画面刷新 g.drawImage(img,0,0,null);try{Thread.sleep(1);// 线程休眠1毫秒,控制刷新帧率,减少资源消耗}catch(InterruptedException e){thrownewRuntimeException(e);}}}}

DroneThread 类关键点

  1. 双缓冲技术:创建BufferedImage作为缓冲画布,先在缓冲画布上完成所有绘制,再一次性绘制到窗口,彻底解决界面闪烁问题,提升可视化流畅度。
  2. 分层绘制逻辑:按照「背景→无人机→任务→入侵者」的顺序绘制,逻辑清晰,避免绘制覆盖导致的显示异常。
  3. 雷达扫描交互:通过遍历雷达范围内的像素点,检测入侵者的黑色主体,计算方向向量调整无人机移动方向,同时切换攻击状态,实现无人机对入侵者的自动追踪与攻击。
  4. 状态优先级:遵循「任务>入侵者>巡逻」的状态优先级,保证无人机优先执行任务,再处理入侵者,最后恢复巡逻,符合业务逻辑。
  5. 入侵者扣血:检测到无人机绿色主体后,确认攻击状态无人机在攻击范围内,实现入侵者血量持续消耗,直到死亡。
  6. 碰撞检测与分离:检测无人机之间的距离,碰撞后进行轻微推开,并做边界保护,避免无人机重叠与卡墙,提升运行稳定性。
  7. 无限循环与休眠:通过while(true)保证线程持续运行,Thread.sleep(1)控制刷新帧率,平衡流畅度与资源消耗。

7. TaskThread 类(任务核心线程,处理任务分配与执行)

该类是任务专属线程,继承Thread类,负责任务的自动分配(给最近的巡逻无人机)、无人机对任务的追踪、任务完成判定与无人机状态恢复,是任务生命周期的核心调度者。
packageduoxiancheng.xq0129.dronev4;importjava.util.ArrayList;/** * @author xuqiang * @date 2026/1/29 16:34 * @description 任务核心线程,负责任务分配、追踪与完成判定 */publicclassTaskThreadextendsThread{ArrayList<Drone> droneList;// 无人机集合,接收外部注入ArrayList<Task> taskList;// 任务集合,接收外部注入publicvoidrun(){// 无限循环:持续处理任务相关逻辑while(true){try{Thread.sleep(30);// 休眠30毫秒,降低任务调度频率,减少资源消耗}catch(InterruptedException e){thrownewRuntimeException(e);}// 1. 任务自动分配:将未分配任务(state=0)分配给最近的巡逻无人机(核心:任务分配逻辑)for(int i =0; i < taskList.size(); i++){Task t = taskList.get(i);if(t.getState()==0){// 只处理未分配的任务int min =1000;// 初始化最小距离为1000(大于最大有效距离)int index =-1;// 初始化目标无人机索引为-1(无有效无人机)// 遍历所有无人机,寻找最近的巡逻状态无人机(state=0)for(int j =0; j < droneList.size(); j++){Drone d = droneList.get(j);// 只选择巡逻状态的无人机,不干扰攻击/补给状态的无人机(核心:任务分配约束)if(d.getState()==0){int dis =(int)Math.sqrt((t.getX()- d.x)*(t.getX()- d.x)+(t.getY()- d.y)*(t.getY()- d.y));if(dis < min){ min = dis; index = j;}}}// 找到可用无人机后,分配任务并设置追踪速度if(index !=-1){Drone drone = droneList.get(index);// 标记任务为已分配(state=1)、无人机为攻击/任务执行状态(state=1) t.setState(1); drone.setState(1);int dx = t.getX()- drone.x;int dy = t.getY()- drone.y;double distance =Math.sqrt(dx * dx + dy * dy);if(distance >0){// 1. 先计算原始的x/y方向速度(未强转,保留小数)double rawSpeedX =(dx / distance)*3;double rawSpeedY =(dy / distance)*3;// 2. 独立处理x方向速度:绝对值<1则强制设±1,否则正常强转(核心:解决单一方向卡壳)if(Math.abs(rawSpeedX)<1){ drone.speedx = dx >0?1:(dx <0?-1:0);}else{ drone.speedx =(int) rawSpeedX;}// 3. 独立处理y方向速度:和x方向逻辑完全一致,彻底解决单一方向卡壳if(Math.abs(rawSpeedY)<1){ drone.speedy = dy >0?1:(dy <0?-1:0);}else{ drone.speedy =(int) rawSpeedY;}}else{// 距离为0,已抵达目标,速度置0 drone.speedx =0; drone.speedy =0;}}}}// 2. 任务完成判定:无人机抵达任务区域后扣减任务血量,完成后恢复无人机巡逻状态(核心:任务完成逻辑)if(taskList.size()>0){for(int i =0; i < droneList.size(); i++){Drone d = droneList.get(i);if(d.getState()==1){// 只处理攻击/任务执行状态无人机Task targetTask =null;int min =1000;// 第一步:找到当前无人机最近的、已分配的任务(专属目标)for(int j =0; j < taskList.size(); j++){Task t = taskList.get(j);if(t.getState()==1){int dx = t.getX()- d.x;int dy = t.getY()- d.y;int dis =(int)Math.sqrt(dx * dx + dy * dy);if(dis < min){ min = dis; targetTask = t;}}}// 第二步:只处理专属目标,判断是否抵达并扣血if(targetTask !=null){int droneCenterX = d.x + d.scanSize /2;// 无人机中心坐标(雷达中心)int droneCenterY = d.y + d.scanSize/2;int targetCenterX = targetTask.getX()+20;// 任务中心坐标int targetCenterY = targetTask.getY()+20;// 计算圆心距离的平方(避免开方,提升性能)double dx = droneCenterX - targetCenterX;double dy = droneCenterY - targetCenterY;double distanceSquard = dx * dx + dy * dy;// 雷达半径50 + 目标半径20,平方后为70*70=4900(攻击范围判定)boolean inAttackRange = distanceSquard <=4900;if(inAttackRange){ d.speedx =0; d.speedy =0;// 抵达任务区域后停止移动 targetTask.setBlood(targetTask.getBlood()-1);// 扣减任务血量// 任务血量为0,标记完成并恢复无人机巡逻状态if(targetTask.getBlood()<=0){ targetTask.setState(2); d.setState(0);// 重置巡逻随机速度,确保非0(与生产无人机时逻辑一致)do{ d.speedx =(int)(Math.random()*5-2); d.speedy =(int)(Math.random()*5-2);}while(d.speedx ==0&& d.speedy ==0);}}}}}}}}}

TaskThread 类关键点

  1. 任务自动分配:只将未分配任务(state=0)分配给最近的巡逻无人机(state=0),不干扰其他状态的无人机,保证分配的合理性与高效性。
  2. 防卡壳速度计算:独立处理x、y方向速度,绝对值<1时强制设为±1,解决无人机在单一方向上无法移动的卡壳问题,提升任务追踪的流畅性。
  3. 专属目标追踪:为每个无人机匹配最近的已分配任务作为专属目标,避免多无人机争抢同一个任务,提升任务执行效率。
  4. 高效距离判定:使用圆心距离的平方进行攻击范围判定,避免开方运算,提升程序运行性能。
  5. 任务完成与状态恢复:任务完成后,自动将无人机状态恢复为巡逻(state=0),并重置随机非0速度,让无人机回归正常巡逻,形成任务执行的闭环。
  6. 低频率调度:线程休眠30毫秒,降低任务调度频率,在保证任务响应性的同时,减少系统资源消耗。

总结

  1. 技术亮点:双缓冲技术解决界面闪烁、状态优先级保证业务逻辑、防卡壳速度计算提升流畅性、碰撞检测避免实体重叠。
  2. 关键业务闭环:(各实体生命周期完整)
无人机【巡逻→任务/入侵者响应→执行→恢复巡逻】
任务【创建→分配→执行→完】
入侵者【创建→被攻击→死亡】

Read more

LobeChat能否实现AI绘画集成?图文生成联动尝试

LobeChat能否实现AI绘画集成?图文生成联动尝试 在智能创作工具不断演进的今天,用户早已不满足于“只聊不画”的纯文本对话。当一句“帮我画个穿宇航服的猫”就能换来一张生动图像时,人机交互的边界正在被重新定义。而开源聊天界面 LobeChat,正悄然成为这场多模态变革中的关键拼图。 它不只是一个长得像 ChatGPT 的前端壳子——其插件化架构和灵活的模型调度机制,让它具备了向“全能型 AI 助手”跃迁的潜力。尤其是面对当前热门的 AI 绘画需求,LobeChat 是否真能打通“文字描述 → 图像生成 → 上下文反馈”的闭环?我们不妨从工程实践的角度深入一探究竟。 为什么是 LobeChat? 市面上的开源聊天项目不少,但多数仍停留在“换皮调 API”的层面。相比之下,LobeChat 的设计思路更接近一个 可编程的 AI 应用框架。它的价值不仅在于美观的 UI 和流畅的动画,更体现在以下几个核心能力上: * 真正的插件系统:

【愚公系列】《AI短视频创作一本通》011-AI 短视频分镜头设计(AI绘画工具的选择)

【愚公系列】《AI短视频创作一本通》011-AI 短视频分镜头设计(AI绘画工具的选择)

💎【行业认证·权威头衔】 ✔ 华为云天团核心成员:特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯:ZEEKLOG博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋:横跨鸿蒙、云计算、AI等前沿领域的技术布道者 🏆【荣誉殿堂】 🎖 连续三年蝉联"华为云十佳博主"(2022-2024) 🎖 双冠加冕ZEEKLOG"年度博客之星TOP2"(2022&2023) 🎖 十余个技术社区年度杰出贡献奖得主 📚【知识宝库】 覆盖全栈技术矩阵: ◾ 编程语言:.NET/Java/Python/Go/Node… ◾ 移动生态:HarmonyOS/iOS/Android/小程序 ◾ 前沿领域:

【AIGC】Claude Code的CLAUDE.md加载时机与书写最佳实践

I. CLAUDE.md 文件:项目级 vs 全局级 完全解析 CLAUDE.md 是 Claude Code 提供的简化版规则配置文件(对比多文件的 rules 文件夹),核心作用是定义 AI 需遵循的代码规范、项目要求等,而「项目根目录的 CLAUDE.md」和「用户主目录的 ~/.claude/CLAUDE.md」的核心区别在于作用域和优先级,下面分维度讲清楚: 一、核心区别(作用域+使用场景) 维度项目根目录 CLAUDE.md用户主目录 ~/.claude/CLAUDE.md作用域仅对当前项目生效(项目内所有文件)对当前用户下的所有项目生效使用场景定义当前项目的专属规则(如项目特有编码规范、业务约束、依赖版本)定义跨项目的通用规则(如个人编码习惯、全项目通用安全规范、

亲测Meta-Llama-3-8B-Instruct:vLLM加速下的多轮对话体验

亲测Meta-Llama-3-8B-Instruct:vLLM加速下的多轮对话体验 1. 引言 随着大语言模型在实际应用中的广泛落地,如何在有限硬件资源下实现高效、流畅的推理服务成为关键挑战。本文基于 Meta-Llama-3-8B-Instruct 模型,结合 vLLM 推理加速框架与 Open WebUI 可视化界面,构建了一套完整的本地化对话系统,并重点测试其在多轮对话场景下的响应速度、上下文保持能力及整体交互体验。 该方案最大亮点在于:单张RTX 3060即可运行GPTQ-INT4量化版本,配合vLLM的PagedAttention机制显著提升吞吐量,适合个人开发者或中小企业快速部署轻量级AI助手。通过本实践,我们验证了Llama-3系列中等规模模型在英文指令理解、代码生成和长上下文处理方面的出色表现。 2. 技术架构与核心组件解析 2.1 Meta-Llama-3-8B-Instruct 模型特性 Meta于2024年4月发布的Llama-3系列包含8B、70B和405B三个版本,其中 Meta-Llama-3-8B-Instruct 是专为指令遵循优化的中等