JavaGUI智能无人机仿真系统开发实战:多线程协同与动态作战模拟

在Java GUI开发领域,多线程协同和实时模拟是极具挑战性的课题。本文将带您从零开始构建一个完整的智能无人机仿真系统,通过多线程技术实现无人机与入侵者的动态交互、智能攻击和状态管理,打造一个具备实战模拟能力的智能无人机平台。

目录

一、项目概述与核心设计

[1.1 项目目标](#1.1 项目目标)

[1.2 核心技术架构](#1.2 核心技术架构)

二、核心类功能详解

[2.1 Drone类:无人机实体建模](#2.1 Drone类:无人机实体建模)

[2.2 Intruder类:入侵者实体建模](#2.2 Intruder类:入侵者实体建模)

[2.3 DroneThread类:多线程渲染引擎](#2.3 DroneThread类:多线程渲染引擎)

[2.4 Dronelistener类:事件响应控制器](#2.4 Dronelistener类:事件响应控制器)

[2.5 DroneUI类:主界面与线程管理](#2.5 DroneUI类:主界面与线程管理)

三、多线程协同机制深度解析

[3.1 线程分工与协作](#3.1 线程分工与协作)

[3.2 线程同步与数据安全](#3.2 线程同步与数据安全)

[3.3 攻击冷却机制](#3.3 攻击冷却机制)

四、完整代码

[4.1 Drone](#4.1 Drone)

[4.2 Dronelistener](#4.2 Dronelistener)

[4.3 DroneThread](#4.3 DroneThread)

[4.4 DroneUI](#4.4 DroneUI)

[4.5 Intruder](#4.5 Intruder)

[4.6 Task](#4.6 Task)

[4.7 TaskProThread](#4.7 TaskProThread)

五、总结与展望

[5.1 项目技术成就总结](#5.1 项目技术成就总结)

[5.1.1 多线程架构的理解与应用](#5.1.1 多线程架构的理解与应用)

[5.1.2 面向对象设计能力提升](#5.1.2 面向对象设计能力提升)

[5.1.3 图形界面开发能力](#5.1.3 图形界面开发能力)

[5.2 对初学者的价值与启示](#5.2 对初学者的价值与启示)

[5.2.1 从理论到实践的跨越](#5.2.1 从理论到实践的跨越)

[5.2.2 问题解决能力的培养](#5.2.2 问题解决能力的培养)

[5.3 未来学习方向](#5.3 未来学习方向)

[5.3.1 技术深化方向](#5.3.1 技术深化方向)

[5.3.2 项目扩展方向](#5.3.2 项目扩展方向)


一、项目概述与核心设计

1.1 项目目标

本系统旨在实现一个完整的无人机作战仿真平台,主要功能包括:

  • 无人机自主巡逻:无人机在指定区域内随机巡逻,具备边界检测和方向切换

  • 入侵者智能生成:随机生成入侵者,避免出现在防守区域内

  • 动态攻击系统:无人机自动检测并攻击入侵者,具备完整的血量计算和伤害机制

  • 多线程协同架构:使用多线程技术实现界面渲染、逻辑处理和事件响应的并发执行

  • 可视化状态管理:通过颜色和图形直观展示无人机和入侵者的状态

1.2 核心技术架构

系统采用MVC(模型-视图-控制器)架构模式,将数据模型、界面显示和逻辑控制分离:

复制代码
智能无人机仿真系统架构:
├── 数据模型层(Model)
│   ├── Drone.java      # 无人机实体类
│   ├── Intruder.java   # 入侵者实体类
│   └── Task.java       # 任务实体类(保留结构)
├── 控制层(Controller)
│   ├── Dronelistener.java  # 事件监听器
│   └── TaskProThread.java  # 任务处理线程
├── 视图层(View)
│   ├── DroneUI.java        # 主界面
│   └── DroneThread.java    # 渲染线程
└── 多线程协同层
    ├── 主线程(UI事件)
    ├── 渲染线程(60FPS)
    └── 逻辑处理线程(异步)

二、核心类功能详解

2.1 Drone类:无人机实体建模

Drone类是系统的核心,负责定义无人机的所有属性和行为:

java 复制代码
// 无人机状态定义
int state; // 0:巡逻 1:攻击入侵者 2:处理任务

// 空间属性
int x, y;           // 当前位置坐标
int size = 30;      // 无人机尺寸
int scanSize = 150; // 扫描范围半径
int attackRange = 80; // 攻击范围半径

// 移动属性
int speedx, speedy; // 基础速度
int runSpeedx, runSpeedy; // 实际运行速度

// 战斗属性
int attackPower = 5;    // 攻击力
Intruder targetIntruder = null; // 当前攻击目标

关键方法解析:

  1. drawDrone() 方法:可视化无人机状态

    • 蓝色半透明圆:扫描范围(150像素半径)

    • 红色半透明圆:攻击范围(80像素半径,仅攻击时显示)

    • 绿色实心圆:无人机主体(30像素直径)

    • 中心小圆:状态指示灯(红=巡逻,紫=攻击,绿=任务)

  2. move() 方法:智能移动逻辑

    • 巡逻模式:按预设速度移动,边界反弹

    • 攻击模式:计算与目标的向量,智能追踪

    • 到达攻击范围后停止移动,准备攻击

  3. attackTarget() 方法:攻击逻辑

    • 计算与目标的欧几里得距离

    • 在攻击范围内时,调用入侵者的takeDamage()方法

    • 每次攻击造成5点伤害

2.2 Intruder类:入侵者实体建模

Intruder类定义了入侵者的属性和行为,包含完整的血量系统:

java 复制代码
// 生命值系统
int maxBlood = 100; // 最大血量
int blood = 100;    // 当前血量
boolean isAlive = true; // 存活状态

// 移动系统
int x, y;           // 当前位置
int speedx, speedy; // 移动速度
int size = 45;      // 入侵者尺寸

// 视觉系统
Color本体颜色 = Color.BLACK; // 黑色圆形主体
Color血量条背景 = Color.RED;  // 红色血量背景
Color当前血量 = Color.GREEN;  // 绿色当前血量

血量系统实现细节:

  1. 血量条绘制:在入侵者上方绘制20像素宽的血量条

    • 红色背景表示最大血量

    • 绿色前景按比例显示当前血量

    • 显示具体数值:当前血量/最大血量

java 复制代码
public void takeDamage(int damage) {

    if (isAlive) {
        blood -= damage;
        if (blood <= 0) {
            blood = 0;
            isAlive = false;
            System.out.println("入侵者被消灭!");
        }
    }
}
  1. 移动逻辑:在屏幕边界内随机反弹移动,避免越界

2.3 DroneThread类:多线程渲染引擎

DroneThread是系统的渲染核心,以60FPS的帧率刷新界面:

java 复制代码
@Override
public void run() {
    while (running) {
        // 1. 创建双缓冲图像
        BufferedImage img = new BufferedImage(1200, 950, BufferedImage.TYPE_INT_RGB);
        Graphics bg = img.getGraphics();
        
        // 2. 清空画布并绘制背景
        bg.setColor(Color.WHITE);
        bg.fillRect(0, 0, 1200, 950);
        
        // 3. 绘制防守区域(红色边框)
        bg.setColor(Color.RED);
        bg.drawRect(200, 175, 800, 600);
        
        // 4. 绘制所有游戏实体
        drawAllEntities(bg);
        
        // 5. 执行战斗逻辑
        performCombatLogic();
        
        // 6. 刷新到屏幕
        g.drawImage(img, 0, 0, null);
        
        // 7. 控制帧率(16ms ≈ 60FPS)
        Thread.sleep(16);
    }
}

关键渲染流程:

  1. 双缓冲技术 :使用BufferedImage创建离屏图像,避免画面闪烁

  2. 分层绘制:按照背景→静态元素→动态实体的顺序绘制

  3. 实时更新:每帧重新计算所有实体的位置和状态

2.4 Dronelistener类:事件响应控制器

Dronelistener实现了ActionListenerMouseListener接口,负责处理所有用户交互:

java 复制代码
// 按钮事件处理
@Override
public void actionPerformed(ActionEvent e) {
    String command = e.getActionCommand();
    
    if (command.equals("生产无人机")) {
        // 在防守区域内随机生成无人机
        int x = random.nextInt(700) + 200;  // 200-900
        int y = random.nextInt(500) + 175;  // 175-675
        // 设置随机速度(-2~2,排除0)
        int speedx = adjustSpeed(random.nextInt(5) - 2);
        int speedy = adjustSpeed(random.nextInt(5) - 2);
        
        Drone drone = new Drone(x, y, 0, speedx, speedy);
        synchronized (droneList) {
            droneList.add(drone);
        }
    }
    
    else if (command.equals("生产入侵者")) {
        // 在防守区域外随机生成入侵者
        int x, y;
        do {
            x = random.nextInt(1200 - 205) + 60;
            y = random.nextInt(950 - 205) + 60;
        } while (isInDefenseArea(x, y)); // 确保不在防守区内
        
        Intruder intruder = new Intruder(x, y, 
            adjustSpeed(random.nextInt(5) - 2),
            adjustSpeed(random.nextInt(5) - 2),
            45);
        synchronized (intruderList) {
            intruderList.add(intruder);
        }
    }
}

线程安全处理:

  • 使用synchronized关键字保护共享资源

  • 避免在遍历集合时直接修改,防止ConcurrentModificationException

2.5 DroneUI类:主界面与线程管理

DroneUI是系统的入口点,负责初始化界面和启动所有线程:

java 复制代码
public class DroneUI extends JFrame {
    // 共享数据容器
    ArrayList<Drone> droneList = new ArrayList<>();
    ArrayList<Intruder> intruderList = new ArrayList<>();
    ArrayList<Task> taskList = new ArrayList<>();
    
    // 线程引用
    private DroneThread droneThread;
    private TaskProThread taskProThread;
    
    public DroneUI() {
        // 1. 初始化窗口
        setTitle("智能无人机平台");
        setSize(1200, 1000);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        
        // 2. 创建控制面板
        JPanel btnPanel = new JPanel();
        btnPanel.setBackground(Color.LIGHT_GRAY);
        JButton btnDrone = new JButton("生产无人机");
        JButton btnIntruder = new JButton("生产入侵者");
        btnPanel.add(btnDrone);
        btnPanel.add(btnIntruder);
        add(btnPanel, BorderLayout.SOUTH);
        
        // 3. 显示窗口并等待渲染上下文就绪
        setVisible(true);
        try { Thread.sleep(100); } catch (InterruptedException e) {}
        
        // 4. 初始化监听器并共享数据
        Dronelistener listener = new Dronelistener();
        listener.droneList = droneList;
        listener.intruderList = intruderList;
        listener.taskList = taskList;
        
        // 5. 注册事件监听
        btnDrone.addActionListener(listener);
        btnIntruder.addActionListener(listener);
        
        // 6. 启动渲染线程
        droneThread = new DroneThread(getGraphics());
        droneThread.droneList = droneList;
        droneThread.intruderList = intruderList;
        droneThread.taskList = taskList;
        droneThread.start();
        
        // 7. 启动任务处理线程
        taskProThread = new TaskProThread();
        taskProThread.droneList = droneList;
        taskProThread.taskList = taskList;
        taskProThread.start();
        
        System.out.println("智能无人机平台启动完成");
    }
}

三、多线程协同机制深度解析

3.1 线程分工与协作

系统采用三线程架构,各司其职:

线程名称 职责 运行频率 关键操作
主线程(AWT-EventQueue) UI事件响应、组件管理 事件驱动 按钮点击、窗口操作
渲染线程(DroneThread) 图形渲染、战斗逻辑 60FPS 绘制所有实体、计算攻击
任务线程(TaskProThread) 任务分配与处理 30ms间隔 无人机任务分配、状态更新

3.2 线程同步与数据安全

在多线程环境下,数据共享需要特别注意线程安全:

java 复制代码
// 安全的集合遍历与修改
private void removeDeadIntruders() {
    synchronized (intruderList) {
        for (int i = intruderList.size() - 1; i >= 0; i--) {
            if (!intruderList.get(i).isAlive()) {
                intruderList.remove(i); // 倒序遍历避免索引错位
            }
        }
    }
}

// 战斗逻辑中的同步处理
private void performCombatLogic() {
    // 创建副本避免在迭代时修改原集合
    ArrayList<Intruder> intruderCopy;
    synchronized (intruderList) {
        intruderCopy = new ArrayList<>(intruderList);
    }
    
    synchronized (droneList) {
        for (Drone drone : droneList) {
            // 使用副本进行距离计算
            for (Intruder intruder : intruderCopy) {
                // 计算距离并判断是否攻击
            }
        }
    }
}

3.3 攻击冷却机制

为了防止攻击频率过高,系统实现了攻击冷却机制:

java 复制代码
// 在DroneThread类中
private int attackCooldown = 0;
private final int ATTACK_INTERVAL = 10; // 每10帧攻击一次

// 在循环中
attackCooldown--;
if (attackCooldown <= 0) {
    drone.attackTarget();
    attackCooldown = ATTACK_INTERVAL; // 重置冷却
}

计算说明:假设帧率为60FPS,10帧冷却相当于约166毫秒攻击一次,平衡了游戏性和性能。

四、完整代码

4.1 Drone

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

import java.awt.*;

public class Drone {
    // 属性
    int x, y, speedx, speedy, size;
    int tindex = -1;
    int state; // 0 巡逻 1 跟随/攻击入侵者 2: 处理任务
    int stateSize;
    int scanSize;
    int attackRange = 80; // 攻击范围
    int attackPower = 5; // 每次攻击造成的伤害(从2改为5)
    int fSpeedx, fSpeedy;
    int runSpeedx, runSpeedy;
    Intruder targetIntruder = null; // 当前攻击目标

    // 构造方法
    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 = 150; // 扩大扫描范围
        this.speedy = speedy;
        this.speedx = speedx;
        runSpeedx = speedx;
        runSpeedy = speedy;
    }

    public void drawDrone(Graphics bg) {
        // 计算无人机的中心坐标
        int centerX = x + size / 2;
        int centerY = y + size / 2;

        // 绘制扫描范围(半透明)- 以无人机为中心
        Color color1 = new Color(0, 0, 255, 30);
        bg.setColor(color1);
        bg.fillOval(
                centerX - scanSize / 2,
                centerY - scanSize / 2,
                scanSize,
                scanSize
        );

        // 绘制攻击范围(如果正在攻击)
        if (state == 1 && targetIntruder != null) {
            Color attackColor = new Color(255, 0, 0, 20);
            bg.setColor(attackColor);
            bg.fillOval(
                    centerX - attackRange / 2,
                    centerY - attackRange / 2,
                    attackRange,
                    attackRange
            );
        }

        // 绘制无人机主体
        Color color2 = new Color(64, 195, 66);
        bg.setColor(color2);
        bg.fillOval(x, y, size, size); // 直接使用x,y坐标

        // 绘制状态指示灯 - 在无人机中心
        Color color3;
        switch (state) {
            case 0: // 巡逻
                color3 = new Color(255, 0, 0);
                break;
            case 1: // 攻击
                color3 = new Color(255, 0, 255);
                break;
            case 2: // 处理任务
                color3 = new Color(0, 255, 0);
                break;
            default:
                color3 = Color.WHITE;
        }
        bg.setColor(color3);
        bg.fillOval(
                centerX - stateSize / 2,
                centerY - stateSize / 2,
                stateSize,
                stateSize
        );
    }

    public void move() {
        // 状态0:巡逻
        if (state == 0) {
            runSpeedx = speedx;
            runSpeedy = speedy;

            // 边界检查
            if (x > 300 + 600 || x < 200) {
                runSpeedx = -runSpeedx;
                speedx = -speedx;
                if (x < 200) {
                    x += size;
                } else {
                    x -= size;
                }
            }
            if (y > 175 + 500 || y < 175) {
                runSpeedy = -runSpeedy;
                speedy = -speedy;
                if (y < 175) {
                    y += size;
                } else {
                    y -= size;
                }
            }
        }
        // 状态1:攻击入侵者
        else if (state == 1 && targetIntruder != null && targetIntruder.isAlive()) {
            // 计算无人机中心
            int droneCenterX = x + size/2;
            int droneCenterY = y + size/2;
            int intruderCenterX = targetIntruder.getCenterX();
            int intruderCenterY = targetIntruder.getCenterY();

            // 计算方向向量
            int dx = intruderCenterX - droneCenterX;
            int dy = intruderCenterY - droneCenterY;
            double distance = Math.sqrt(dx * dx + dy * dy);

            // 如果不在攻击范围内,就靠近目标
            if (distance > attackRange) {
                if (distance > 0) {
                    runSpeedx = (int)(dx / distance * 3);
                    runSpeedy = (int)(dy / distance * 3);
                }
            } else {
                // 在攻击范围内,停止移动并攻击
                runSpeedx = 0;
                runSpeedy = 0;
            }
        }

        // 移动
        x += runSpeedx;
        y += runSpeedy;
    }

    // 攻击目标
    public void attackTarget() {
        if (state == 1 && targetIntruder != null && targetIntruder.isAlive()) {
            // 计算距离
            int droneCenterX = x + size/2;
            int droneCenterY = y + size/2;
            int intruderCenterX = targetIntruder.getCenterX();
            int intruderCenterY = targetIntruder.getCenterY();

            int dx = intruderCenterX - droneCenterX;
            int dy = intruderCenterY - droneCenterY;
            double distance = Math.sqrt(dx * dx + dy * dy);

            // 如果在攻击范围内,造成伤害
            if (distance <= attackRange) {
                targetIntruder.takeDamage(attackPower);
                System.out.println("无人机攻击入侵者,造成 " + attackPower + " 点伤害,剩余血量: " + targetIntruder.blood);
            }
        }
    }

    // 设置攻击目标
    public void setTarget(Intruder intruder) {
        this.targetIntruder = intruder;
        this.state = 1;
    }

    // 清除目标
    public void clearTarget() {
        this.targetIntruder = null;
        this.state = 0;
        this.runSpeedx = this.speedx;
        this.runSpeedy = this.speedy;
    }

    // 检查目标是否有效
    public boolean hasValidTarget() {
        return targetIntruder != null && targetIntruder.isAlive();
    }

    // 获取无人机中心坐标(用于距离计算)
    public int getCenterX() {
        return x + size / 2;
    }

    public int getCenterY() {
        return y + size / 2;
    }

    // 修改攻击力的方法(如果需要动态调整)
    public void setAttackPower(int power) {
        this.attackPower = power;
    }

    public int getAttackPower() {
        return attackPower;
    }
}

4.2 Dronelistener

java 复制代码
package yky0206;

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 {
    ArrayList<Task> taskList;
    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;
            int y = random.nextInt(500) + 175;
            int speedx = random.nextInt(5) - 2; // -2~2
            if (speedx == 0) speedx = 1;
            int speedy = random.nextInt(5) - 2;
            if (speedy == 0) speedy = 1;
            Drone drone = new Drone(x, y, 0, speedx, speedy);
            droneList.add(drone);
            System.out.println("生产无人机,位置: (" + x + ", " + y + ")");
        } else if (ac.equals("生产入侵者")) {
            int x = random.nextInt(1200 - 205) + 60;
            int y = random.nextInt(950 - 205) + 60;
            // 确保不在防守区域内
            while (x >= 200 && x <= 900 && y >= 175 && y <= 675) {
                x = random.nextInt(1200 - 205) + 60;
                y = random.nextInt(950 - 205) + 60;
            }
            int speedx = random.nextInt(5) - 2;
            if (speedx == 0) speedx = 1;
            int speedy = random.nextInt(5) - 2;
            if (speedy == 0) speedy = 1;
            Intruder itd = new Intruder(x, y, speedx, speedy, 45);
            intruderList.add(itd);
            System.out.println("生产入侵者,位置: (" + x + ", " + y + "),血量: " + itd.blood);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        Task task = new Task(x, y, 0);
        taskList.add(task);
        System.out.println("生成任务,位置: (" + x + ", " + y + ")");
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}
}

4.3 DroneThread

java 复制代码
package yky0206;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class DroneThread extends Thread {
    public ArrayList<Task> taskList;
    ArrayList<Drone> droneList;
    ArrayList<Intruder> intruderList;
    Graphics g;
    private boolean running = true;
    private int attackCooldown = 0; // 攻击冷却计数器
    private final int ATTACK_INTERVAL = 10; // 攻击间隔(帧数)

    public DroneThread(Graphics g) {
        this.g = g;
    }

    public void stopThread() {
        running = false;
    }

    @Override
    public void run() {
        while (running) {
            BufferedImage img = new BufferedImage(1200, 950, BufferedImage.TYPE_INT_RGB);
            Graphics bg = img.getGraphics();

            // 清空画布
            bg.setColor(Color.WHITE);
            bg.fillRect(0, 0, 1200, 950);

            // 绘制防守区域
            bg.setColor(Color.RED);
            bg.drawRect(200, 175, 800, 600);

            // 绘制任务
            for (int i = 0; i < taskList.size(); i++) {
                Task task = taskList.get(i);
                task.draw(bg);
            }

            // 清理死亡的入侵者
            for (int i = intruderList.size() - 1; i >= 0; i--) {
                if (!intruderList.get(i).isAlive()) {
                    intruderList.remove(i);
                }
            }

            // 绘制并移动入侵者
            for (Intruder intruder : intruderList) {
                intruder.drawIntruder(bg);
                intruder.move();
            }

            // 绘制并移动无人机
            for (Drone drone : droneList) {
                drone.drawDrone(bg);
                drone.move();
            }

            // 无人机检测和攻击入侵者逻辑
            for (Drone drone : droneList) {
                // 只有巡逻状态的无人机才会寻找新目标
                if (drone.state == 0) {
                    Intruder nearestIntruder = null;
                    double minDistance = Double.MAX_VALUE;

                    // 寻找最近的存活入侵者
                    for (Intruder intruder : intruderList) {
                        if (intruder.isAlive()) {
                            // 使用无人机中心坐标计算距离
                            int droneCenterX = drone.getCenterX();
                            int droneCenterY = drone.getCenterY();
                            int intruderCenterX = intruder.getCenterX();
                            int intruderCenterY = intruder.getCenterY();

                            int dx = droneCenterX - intruderCenterX;
                            int dy = droneCenterY - intruderCenterY;
                            double distance = Math.sqrt(dx * dx + dy * dy);

                            // 如果在扫描范围内且更近
                            if (distance < drone.scanSize && distance < minDistance) {
                                minDistance = distance;
                                nearestIntruder = intruder;
                            }
                        }
                    }

                    // 如果找到入侵者,设置为攻击目标
                    if (nearestIntruder != null) {
                        drone.setTarget(nearestIntruder);
                        System.out.println("无人机锁定入侵者!距离: " + minDistance);
                    }
                }

                // 如果无人机有攻击目标
                if (drone.hasValidTarget()) {
                    // 减少攻击冷却
                    attackCooldown--;
                    if (attackCooldown <= 0) {
                        drone.attackTarget();
                        attackCooldown = ATTACK_INTERVAL; // 重置冷却
                    }
                } else if (drone.state == 1) {
                    // 目标已死亡或无效,清除目标
                    drone.clearTarget();
                    System.out.println("无人机目标丢失,返回巡逻状态");
                }
            }

            // 绘制到屏幕
            if (g != null) {
                g.drawImage(img, 0, 0, null);
            }

            try {
                Thread.sleep(16); // 约60FPS
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }
    }
}

4.4 DroneUI

java 复制代码
package yky0206;

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<>();
    private DroneThread droneThread;
    private TaskProThread taskProThread;

    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
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 创建监听器
        Dronelistener droneL = new Dronelistener();

        // 设置共享数据
        droneL.droneList = droneList;
        droneL.intruderList = intruderList;
        droneL.taskList = taskList;

        // 注册监听器
        btn.addActionListener(droneL);
        btn1.addActionListener(droneL);
        addMouseListener(droneL);

        // 启动无人机线程
        droneThread = new DroneThread(getGraphics());
        droneThread.droneList = droneList;
        droneThread.intruderList = intruderList;
        droneThread.taskList = taskList;
        droneThread.start();

        // 启动任务处理线程
        taskProThread = new TaskProThread();
        taskProThread.droneList = droneList;
        taskProThread.taskList = taskList;
        taskProThread.start();

        System.out.println("智能无人机平台启动完成");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new DroneUI();
        });
    }
}

4.5 Intruder

java 复制代码
package yky0206;

import java.awt.*;

public class Intruder {
    int x, y, speedx, speedy, size;
    int blood;
    int maxBlood;
    boolean isAlive = true;

    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.maxBlood = 100;
        this.blood = maxBlood;
    }

    public void drawIntruder(Graphics g) {
        if (!isAlive) {
            return;
        }

        // 绘制入侵者本体
        g.setColor(Color.BLACK);
        g.fillOval(x, y, size, size);

        // 绘制血量条背景
        g.setColor(Color.RED);
        g.fillRect(x - 10, y - 20, size + 20, 8);

        // 绘制当前血量
        g.setColor(Color.GREEN);
        int currentWidth = (int)((blood * 1.0 / maxBlood) * (size + 20));
        g.fillRect(x - 10, y - 20, currentWidth, 8);

        // 绘制血量数值
        g.setColor(Color.BLACK);
        g.setFont(new Font("宋体", Font.BOLD, 10));
        g.drawString(blood + "/" + maxBlood, x + size/2 - 15, y - 10);
    }

    public void move() {
        if (!isAlive) {
            return;
        }

        // 边界反弹
        if (x > 1200 - size - 60 || x < 60) {
            speedx = -speedx;
        }
        if (y > 950 - size - 60 || y < 60) {
            speedy = -speedy;
        }

        x += speedx;
        y += speedy;
    }

    // 受到伤害
    public void takeDamage(int damage) {
        if (isAlive) {
            blood -= damage;
            if (blood <= 0) {
                blood = 0;
                isAlive = false;
                System.out.println("入侵者被消灭!");
            }
        }
    }

    // 检查是否存活
    public boolean isAlive() {
        return isAlive;
    }

    // 获取中心坐标
    public int getCenterX() {
        return x + size / 2;
    }

    public int getCenterY() {
        return y + size / 2;
    }
}

4.6 Task

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

public class Task {
    int x;
    int y;
    int state; // 0 未被分配 1 被分配 2 已完成
    int blood;

    public Task(int x, int y, int state) {
        this.x = x;
        this.state = state;
        this.y = y;
        blood = 10;
    }

    public void draw(Graphics g) {
        if (blood <= 0) {
            state = 2;
            return;
        }
        g.setColor(Color.BLACK);
        g.fillRect(x, y, 80, 80);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

4.7 TaskProThread

java 复制代码
package yky0206;

import java.util.ArrayList;

public class TaskProThread extends Thread {
    ArrayList<Drone> droneList;
    ArrayList<Task> taskList;

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            // 处理未分配的任务
            for (int i = 0; i < taskList.size(); i++) {
                Task t = taskList.get(i);
                if (t.state == 0) {
                    // 找到最近的空闲无人机
                    int min = Integer.MAX_VALUE;
                    int index = -1;

                    for (int j = 0; j < droneList.size(); j++) {
                        Drone d = droneList.get(j);
                        if (d.state == 0) { // 只有空闲无人机才考虑
                            // 使用无人机中心坐标计算距离
                            int droneCenterX = d.getCenterX();
                            int droneCenterY = d.getCenterY();
                            int taskCenterX = t.x + 40; // 任务中心(80x80的任务,中心在40,40)
                            int taskCenterY = t.y + 40;

                            int dis = (int) Math.sqrt(
                                    (taskCenterX - droneCenterX) * (taskCenterX - droneCenterX) +
                                            (taskCenterY - droneCenterY) * (taskCenterY - droneCenterY)
                            );

                            if (dis < min) {
                                min = dis;
                                index = j;
                            }
                        }
                    }

                    // 分配任务给最近的无人机
                    if (index != -1) {
                        Drone drone = droneList.get(index);
                        drone.tindex = i;
                        drone.state = 2; // 设为处理任务状态
                        t.state = 1; // 任务设为已分配

                        // 计算无人机飞向任务的速度
                        int droneCenterX = drone.getCenterX();
                        int droneCenterY = drone.getCenterY();
                        int taskCenterX = t.x + 40;
                        int taskCenterY = t.y + 40;

                        int dx = taskCenterX - droneCenterX;
                        int dy = taskCenterY - droneCenterY;

                        // 归一化速度向量
                        double distance = Math.sqrt(dx * dx + dy * dy);
                        if (distance > 0) {
                            drone.runSpeedx = (int) (dx / distance * 3); // 固定速度3
                            drone.runSpeedy = (int) (dy / distance * 3);
                        }
                        System.out.println("分配任务给无人机,距离: " + min + ",速度: " + drone.runSpeedx + ", " + drone.runSpeedy);
                    }
                }
            }

            // 检查任务完成情况
            for (int i = 0; i < droneList.size(); i++) {
                Drone d = droneList.get(i);
                if (d.state == 2 && d.tindex < taskList.size()) {
                    Task t = taskList.get(d.tindex);
                    // 检查无人机是否到达任务区域
                    if (Math.abs(d.x + 15 - t.x) < 40 && Math.abs(d.y + 15 - t.y) < 40) {
                        d.runSpeedx = 0;
                        d.runSpeedy = 0;
                        t.blood--;

                        if (t.blood <= 0) {
                            d.tindex = -1;
                            d.state = 0; // 恢复空闲状态
                            t.state = 2; // 任务完成
                            System.out.println("任务完成!");
                        }
                    }
                }
            }

            // 清理已完成的任务
            for (int i = taskList.size() - 1; i >= 0; i--) {
                Task t = taskList.get(i);
                if (t.state == 2 && t.blood <= 0) {
                    taskList.remove(i);
                }
            }
        }
    }
}

五、总结与展望

5.1 项目技术成就总结

通过开发这个智能无人机仿真系统,我获得了宝贵的全栈开发经验,主要体现在以下方面:

5.1.1 多线程架构的理解与应用

系统采用三线程协同架构(UI线程、渲染线程、逻辑线程),通过实践深入理解了:

  • 线程安全的重要性及synchronized关键字的正确使用

  • 如何避免常见的多线程问题

  • 合理的线程分工对程序性能和响应速度的影响

5.1.2 面向对象设计能力提升

通过将系统拆分为6个核心类,我实践了面向对象设计原则:

  • DroneIntruder类展示了如何封装实体属性和行为

  • DroneThreadTaskProThread体现了单一职责原则

  • 类间通过接口和共享数据结构协作,降低了耦合度

5.1.3 图形界面开发能力

完成了一个功能完整的GUI项目:

  • 掌握了Swing双缓冲技术消除画面闪烁

  • 学会了通过颜色编码和图形元素提供直观状态反馈

  • 理解了事件驱动编程模型及其实现方式

5.2 对初学者的价值与启示

5.2.1 从理论到实践的跨越

这个项目展示了如何将课堂上的理论知识转化为实际可运行的代码:

  • 算法理论(距离计算、碰撞检测)在具体场景中的应用

  • 多线程编程理论在解决实际问题时的具体实现

  • 面向对象设计原则在项目架构中的体现

5.2.2 问题解决能力的培养

开发过程中遇到的诸多挑战(如线程安全问题、渲染效率问题、对象状态管理问题)都提供了宝贵的调试和问题解决经验。

5.3 未来学习方向

基于此项目,我认为可以进一步深入以下几个方向的学习:

5.3.1 技术深化方向

  1. 更高效的空间分区算法:学习四叉树、BSP树等数据结构,优化大规模对象的碰撞检测效率

  2. 高级AI算法:为无人机和入侵者实现更智能的路径规划和决策逻辑

  3. 性能优化技术:学习JVM性能调优、内存管理高级技巧

5.3.2 项目扩展方向

  1. 网络功能:实现多玩家协同作战或对抗模式

  2. 数据可视化:添加实时数据统计和可视化展示面板

  3. 配置系统:开发图形化配置界面,支持动态调整游戏参数

这个智能无人机仿真系统不仅是一个技术实践项目,更是一个学习过程的具体体现。通过从零开始构建这样一个系统,我深刻体会到理论知识如何转化为实际能力,也为未来的技术学习之路奠定了坚实基础。

相关推荐
寻寻觅觅☆11 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
偷吃的耗子12 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
青云计划12 小时前
知光项目知文发布模块
java·后端·spring·mybatis
赶路人儿12 小时前
Jsoniter(java版本)使用介绍
java·开发语言
化学在逃硬闯CS12 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar12313 小时前
C++使用format
开发语言·c++·算法
探路者继续奋斗13 小时前
IDD意图驱动开发之意图规格说明书
java·规格说明书·开发规范·意图驱动开发·idd
Gofarlic_OMS13 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
夏鹏今天学习了吗13 小时前
【LeetCode热题100(100/100)】数据流的中位数
算法·leetcode·职场和发展
消失的旧时光-194314 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言