智能无人机平台V4

V3版本回顾

在V3版本中,实现了无人机的自动索敌追踪、并在扫描到入侵者后将信息"广播"给其他无人机,其他巡逻状态的无人机可以协同该无人机进行"围剿"行为。

V4版本提升

  • 为入侵者加入了可视化的血条,便于玩家更直观的看到入侵者血量减少的过程
  • 加入了"任务系统",现在玩家可以通过点击守卫区中的位置来指挥最近的巡逻状态无人机前往该位置
  • 将无人机的move方法内部的庞大代码分成几个小的方法,并通过不同的限定条件来调用不同的方法。同时为了便于后期功能的添加,现在将无人机移动方案的限定条件改为由状态码的不同来决定无人机的移动方式。

V4版本的具体实现

可视化血条的添加

  • 思路:只需要在入侵者的正上方画出一个矩形边框和一个实心矩形即可,通过改变实心矩形的宽度来达到显示血量的效果

  • 具体实现

    java 复制代码
    Color color3 =new Color(0, 0, 0);
    g.setColor(color3);
    g.drawRect(x, y-5, size, 6);
    Color color4 =new Color(124, 244, 21);
    g.setColor(color4);
    g.fillRect(x+1,y-4,(int) (blood/200.0*(size-1)),5);

任务系统的添加

  • 思路及代码:
  1. 创建Task类,将玩家发布的任务封装起来,类中包括该任务点的坐标、状态属性以及可视化的绘制方法。代码实现如下

    java 复制代码
    package com.nwu.by0129.droneV4;
    
    import java.awt.*;
    
    public class Task {
        int x;
        int y;
        int size=10;
        int state;//0未被领取的任务;1被领取的任务;2已完成的任务
        public Task(int state, int x, int y) {
            this.state = state;
            this.x = x;
            this.y = y;
        }
        public void draw(Graphics g) {
            g.setColor(Color.yellow);
            g.fillRect(x-size/2,y-size/2,size,size);
        }
    }
  2. 创建鼠标监听器,并在DroneListener类中加入鼠标监听器的相关内容。重写mousePressed方法,将鼠标点击的坐标作为参数构建task对象,使用共享内存的思路,并存入tasks动态数组,便于其他无人机领取任务。代码实现如下

    java 复制代码
    public void mousePressed(MouseEvent e) {
    	     int x=e.getX();
    	     int y=e.getY();
    	     Task task = new Task(0,x,y);
    	     //对任务点进行判断,不得超出守卫区的范围
    	     if(!(task.x<200+ task.size/2+50||task.x>1000- task.size/2-50||task.y<100+ task.size+50||task.y>700-task.size-50)) {
    	         tasks.add(task);
    	     }
    	}
  3. 创建任务线程类TaskThread,在类中重写run方法。在run方法中遍历无人机与任务数组,将未被分配的任务分配给距离最近且处于巡逻状态的无人机,任务被分配后将任务的状态设置为已被领取,若此时没有空闲的无人机,则输出"没有可指挥的无人机"来提示玩家。代码实现如下

    java 复制代码
    package com.nwu.by0129.droneV4;
    
    import java.util.ArrayList;
    
    public class TaskThread extends Thread {
        ArrayList<Task> tasks;
        ArrayList<Drone> drones;
    
        @Override
        public void run() {
            for (; ; ) {
                //System.out.println("进入TaskThread");
                if (tasks != null) {
                    if (drones != null) {
                        for (int i = tasks.size() - 1; i >= 0; i--) {
                            Task task = tasks.get(i);
                            if (task.state != 1) {
                                int nearestIndex = -1;
                                double minDis = 1000.0;
                                for (int j = drones.size() - 1; j >= 0; j--) {
                                    Drone drone = drones.get(j);
                                    //找到没有领取任务的无人机(只有巡逻状态的无人机可以接任务)
                                    if (drone.state == 0) {
                                        //计算距离并找出最近的
                                        double currentDis = caculateDis(task, drone);
                                        if (currentDis <= minDis) {
                                            minDis = currentDis;
                                            nearestIndex = j;//把最近的无人机编号取出来
                                        }
                                    }
                                }
                                if (nearestIndex != -1) {
                                    drones.get(nearestIndex).state = 2;//无人机状态设为正在执行任务
                                    drones.get(nearestIndex).targetTask = task;
                                    System.out.println("任务被领取");
                                    task.state = 1;//任务状态设为已被领取
                                } else {
                                    System.out.println("没有可指挥的无人机");
                                    task.state = 0;
                                }
                            }
                        }
                    }
                }
                try {
                    Thread.sleep(16);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    
        double caculateDis(Task task, Drone drone) {
            double dis = Math.sqrt((task.x - drone.x) * (task.x - drone.x) + (task.y - drone.y) * (task.y - drone.y) * 1.0);
            return dis;
        }
    }
  4. 在DroneThread线程中画出任务点,若任务完成,则移除任务对象且不进行绘制。具体代码实现如下

    java 复制代码
    if (tasks != null) {
         for (int i = 0; i < tasks.size(); i++) {
             Task task = tasks.get(i);
             if(task.state==2){
                 tasks.remove(i);
             }else{
                 task.draw(bg);
             }
         }
     }
  5. 在Drone类中构建moveToTask方法,让最近的无人机在接到任务后计算速度并前往,逻辑与追踪入侵者类似,并在无人机中心与任务点距离小于20时,将状态设置为任务完成,并清空任务目标。代码实现如下

    java 复制代码
    public void moveToTask(){
         int dx = targetTask.x+targetTask.size/2-(x+scanSize/2);
         int dy = targetTask.y+targetTask.size/2-(y+scanSize/2);
         double distance = Math.sqrt(dx*dx+dy*dy);
         if(distance>20){
             huntingSpeedx=(int)(dx/distance*huntingSpeed);
             huntingSpeedy=(int)(dy/distance*huntingSpeed);
         }else{
             huntingSpeedx=0;
             huntingSpeedy=0;
             System.out.println("完成任务");
             state=0;//完成任务
             targetTask.state=2;
             targetTask=null; //任务完成后清除任务目标
         }
         //硬限位,防止出界
         int newx = x+huntingSpeedx;
         int newy = y+huntingSpeedy;
         x = Math.max(200, Math.min(1000 - scanSize, newx));
         y = Math.max(100, Math.min(700 - scanSize, newy));
     }

    无人机move方法的优化

    • 在上个版本中,无人机的move方法过于庞大且判定条件没有统一化,导致后续再添加其他功能时非常麻烦,在V4版本中我改进了move方法,让move方法通过状态码来调用对应的移动方法来完成操作。代码实现如下

      java 复制代码
      public void move() {
          if(state == 2){
              moveToTask();
          }else if(state == 1){
              //先判断目标是否在守卫区外,若在守卫区外则不在追逐
              if(target!=null){
                  if(target.x+target.size/2<200||target.x+target.size/2>900||target.y+target.size/2<100||target.y+target.size/2>600){
                      state=0;
                      target=null;
                  }else{
                      moveToHunt();
                  }
              }else{
                  state=0;
              }
          }else if(state == 0){
              moveToFind();
          }
      }
      public void moveToTask(){
          int dx = targetTask.x+targetTask.size/2-(x+scanSize/2);
          int dy = targetTask.y+targetTask.size/2-(y+scanSize/2);
          double distance = Math.sqrt(dx*dx+dy*dy);
          if(distance>20){
              huntingSpeedx=(int)(dx/distance*huntingSpeed);
              huntingSpeedy=(int)(dy/distance*huntingSpeed);
          }else{
              huntingSpeedx=0;
              huntingSpeedy=0;
              System.out.println("完成任务");
              state=0;//完成任务
              targetTask.state=2;
              targetTask=null; //任务完成后清除任务目标
          }
          //硬限位,防止出界
          limit();
           }
      public void moveToHunt(){
          int dx = target.x+target.size/2-(x+scanSize/2);
          int dy = target.y+target.size/2-(y+scanSize/2);
          double distance = Math.sqrt(dx*dx+dy*dy);
          if(distance>20){
              huntingSpeedx=(int)(dx/distance*huntingSpeed);
              huntingSpeedy=(int)(dy/distance*huntingSpeed);
          }else{
              huntingSpeedx=0;
              huntingSpeedy=0;
          }
          //硬限位,防止出界
         limit();
      }
      public void moveToFind(){
          x += speedx;
          y += speedy;
          if (x < 200 || x > 900) {
              speedx = -speedx;
          }
          if (y < 100 || y > 600) {
              speedy = -speedy;
          }
       }
      public void limit(){
          int newx = x+huntingSpeedx;
          int newy = y+huntingSpeedy;
          x = Math.max(200, Math.min(1000 - scanSize, newx));
          y = Math.max(100, Math.min(700 - scanSize, newy));
      }

V4版本完整代码如下

java 复制代码
package com.nwu.by0129.droneV4;

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

public class Drone {
    int x;
    int y;
    int stateSize = 16;
    int scanSize = 100;
    int size = 30;
    int state =0;// 0巡逻中;1追踪中;2执行任务中
    int speedx;
    int speedy;
    int huntingSpeedx;
    int huntingSpeedy;
    int rSquare=scanSize*scanSize/4;
    int huntingSpeed = 4;//设置追逐速度
    Intruder target = null;
    Task targetTask = null;


    public Drone(int x, int y, int speedx, int speedy) {
        this.x = x;
        this.y = y;
        this.speedx = speedx;
        this.speedy = speedy;
    }

    public void drawDrone(Graphics g) {
        Color color1 = new Color(52, 146, 241, 75);
        g.setColor(color1);
        g.fillOval(x, y, scanSize, scanSize);
        Color color2 = new Color(111, 200, 34);
        g.setColor(color2);
        g.fillOval(x + 35, y + 35, size, size);
        Color color3 = new Color(243, 82, 82);
        if(state == 0){
            g.setColor(color3);
            g.fillOval(x + 42, y + 42, stateSize, stateSize);
        }else if(state == 1||state == 2){
            Color color4 = new Color (5, 25, 246);
            g.setColor(color4);
            g.fillOval(x + 42, y + 42, stateSize, stateSize);
        }
    }

    public void move() {
        if(state == 2){
            moveToTask();
        }else if(state == 1){
            //先判断目标是否在守卫区外,若在守卫区外则不在追逐
            if(target!=null){
                if(target.x+target.size/2<200||target.x+target.size/2>900||target.y+target.size/2<100||target.y+target.size/2>600){
                    state=0;
                    target=null;
                }else{
                    moveToHunt();
                }
            }else{
                state=0;
            }
        }else if(state == 0){
            moveToFind();
        }
    }

    public ScanResult scan(int x, int y, int size, BufferedImage img) {
        int distanceSquare;
        for (int i = x; i < x + size; i++) {
            for (int j = y; j < y + size; j++) {
                int roundx=x + scanSize / 2;
                int roundy=y + scanSize / 2;
                distanceSquare = (roundx - i) * (roundx - i) + (roundy - j) * (roundy - j);
                if (distanceSquare < rSquare){
                    try{
                        int colorNum = img.getRGB(i,j);
                        Color color = new Color(colorNum);
                        Color targetColor1 = new Color(213, 15, 15);
                        Color targetColor2 = new Color(0,0,0);
                        if(isIntruderColor(color,targetColor1,25)||isIntruderColor(color,targetColor2,30)){
                            //System.out.println("扫描到入侵者");
                            ScanResult sr= new ScanResult(i,j);
                            return sr ;
                        }
                    }catch(Exception e){
                        // 处理超出图像范围的情况
                        continue;
                    }
                }
            }
        }
        return null;
    }
    //颜色判断方法
    public boolean isIntruderColor (Color c1, Color c2, int tolerance){
        return  Math.abs(c1.getRed()-c2.getRed()) <= tolerance &&
                Math.abs(c1.getGreen()-c2.getGreen()) <= tolerance &&
                Math.abs(c1.getBlue()-c2.getBlue()) <= tolerance;
    }
    public void moveToTask(){
        int dx = targetTask.x+targetTask.size/2-(x+scanSize/2);
        int dy = targetTask.y+targetTask.size/2-(y+scanSize/2);
        double distance = Math.sqrt(dx*dx+dy*dy);
        if(distance>20){
            huntingSpeedx=(int)(dx/distance*huntingSpeed);
            huntingSpeedy=(int)(dy/distance*huntingSpeed);
        }else{
            huntingSpeedx=0;
            huntingSpeedy=0;
            System.out.println("完成任务");
            state=0;//完成任务
            targetTask.state=2;
            targetTask=null; //任务完成后清除任务目标
        }
        //硬限位,防止出界
        limit();
    }
    public void moveToHunt(){
        int dx = target.x+target.size/2-(x+scanSize/2);
        int dy = target.y+target.size/2-(y+scanSize/2);
        double distance = Math.sqrt(dx*dx+dy*dy);
        if(distance>20){
            huntingSpeedx=(int)(dx/distance*huntingSpeed);
            huntingSpeedy=(int)(dy/distance*huntingSpeed);
        }else{
            huntingSpeedx=0;
            huntingSpeedy=0;
        }
        //硬限位,防止出界
        limit();
    }
    public void moveToFind(){
        x += speedx;
        y += speedy;
        if (x < 200 || x > 900) {
            speedx = -speedx;
        }
        if (y < 100 || y > 600) {
            speedy = -speedy;
        }
    }
    public void limit(){
        int newx = x+huntingSpeedx;
        int newy = y+huntingSpeedy;
        x = Math.max(200, Math.min(1000 - scanSize, newx));
        y = Math.max(100, Math.min(700 - scanSize, newy));
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

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 {

    Random rand = new Random();
    ArrayList<Drone> drones;
    ArrayList<Intruder> intruders;
    ArrayList<Task> tasks ;


    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("生产无人机")) {
            int x = rand.nextInt(700)+200;
            int y = rand.nextInt(500)+100;
            int speedx = rand.nextInt(5)-2;
            while(speedx==0) {
                speedx = rand.nextInt(5)-2;
            }
            int speedy = rand.nextInt(5)-2;
            while(speedy==0) {
                speedy = rand.nextInt(5)-2;
            }
            Drone drone = new Drone(x,y,speedx,speedy);
            drones.add(drone);
        }else if(e.getActionCommand().equals("生产入侵者")) {
            int x = rand.nextInt(1160);
            int y = rand.nextInt(760);
            while(true){
                if(y<60||y>700||x<160||x>1000) {
                    break;
                }
                x = rand.nextInt(1160);
                y = rand.nextInt(760);
            }
            int speedx = rand.nextInt(5)-2;
            while(speedx==0) {
                speedx = rand.nextInt(5)-2;
            }
            int speedy = rand.nextInt(5)-2;
            while(speedy==0) {
                speedy = rand.nextInt(5)-2;
            }
            Intruder intruder = new Intruder(x,y,speedx,speedy);
            intruders.add(intruder);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
        int x=e.getX();
        int y=e.getY();
        Task task = new Task(0,x,y);
        //对任务点进行判断
        if(!(task.x<200+ task.size/2+50||task.x>1000- task.size/2-50||task.y<100+ task.size+50||task.y>700-task.size-50)) {
            tasks.add(task);
        }
        /*for (int i = 0; i < tasks.size(); i++) {
            System.out.println(tasks.get(i).x);
        }*/

        //System.out.println(tasks.size());
        //System.out.println("task添加了");
    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}
java 复制代码
package com.nwu.by0129.droneV4;

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

public class DroneThread extends Thread {
    Graphics g;
    ArrayList<Drone> drones;
    ArrayList<Intruder> intruders;
    ArrayList<Intruder> foundedIntruders = new ArrayList<>(); //将所有被扫描到的入侵者存入这里
    ArrayList<Task> tasks;

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

    @Override
    public void run() {
        for (; ; ) {
            BufferedImage image = new BufferedImage(1200, 800, 2);
            Graphics bg = image.getGraphics();
            bg.setColor(Color.white);
            bg.fillRect(0, 0, 1200, 800);
            bg.setColor(Color.red);
            bg.drawRect(200, 100, 800, 600);

            if (drones != null) {
                for (int i = 0; i < drones.size(); i++) {
                    Drone drone = drones.get(i);
                    drone.drawDrone(bg);
                    drone.move();
                }
            }
            if (intruders != null) {
                for (int i = 0; i < intruders.size(); i++) {
                    Intruder intruder = intruders.get(i);
                    intruder.drawIntruder(bg);
                    intruder.move();
                }
            }
            //在这里用bg画笔画出任务点
            if (tasks != null) {
                //System.out.println("进入if");
                for (int i = 0; i < tasks.size(); i++) {
                    Task task = tasks.get(i);
                    if(task.state==2){
                        tasks.remove(i);
                    }else{
                        task.draw(bg);
                    }
                }
            }
            if (drones.size() > 0) {
                for (int k = 0; k < drones.size(); k++) {
                    Drone drone = drones.get(k);
                    ScanResult sr = drone.scan(drone.x, drone.y, drone.scanSize, image);
                    if (sr != null) {//如果扫到目标
                        if(drone.state==2){
                            continue;//正在执行任务中就不处理入侵者
                        }
                        Intruder intruder = getTargetIntruder(sr.targetX, sr.targetY);//通过坐标把这个目标找出来
                        if (intruder != null) {//找到目标后
                            drone.target = intruder;//把自己的目标设置为这个
                            drone.state = 1;
                            foundedIntruders.add(intruder);//把这个目标传入动态数组
                        }
                    } else {//如果没扫描到目标
                        if(drone.state==0 && drone.target==null){
                            if (foundedIntruders != null) {//看看动态数组里面有没有别人发现的目标
                                for (int i = foundedIntruders.size() - 1; i >= 0; i--) {
                                    Intruder intruder = foundedIntruders.get(i);
                                    if (intruder != null) {
                                        if (intruder.blood <= 0 || !isInRange(intruder)) {//先判断这个目标还是否存在或在范围内
                                            foundedIntruders.remove(i);//删掉死亡的或者逃跑的
                                        } else {
                                            drone.target = intruder;//把自己的目标设置成这个目标
                                            drone.state = 1;
                                        }
                                    }
                                }
                            }
                        }
                    }

                }
            }

            if (intruders.size() > 0) {
                //如果该入侵者被某个无人机列为目标,就进行扣血
                for (int k = 0; k < intruders.size(); k++) {
                    Intruder intruder = intruders.get(k);
                    for (int i = 0; i < drones.size(); i++) {
                        if (intruder == drones.get(i).target) {
                            intruder.underAttack();
                            System.out.println("第" + k + "个入侵者被扫到,血量剩余:" + intruder.blood);
                            if (intruder.blood <= 0 || !isInRange(intruder)) {//消灭入侵者
                                intruders.remove(k);
                                for (Drone drone : drones) {
                                    if (drone.target == intruder) {
                                        drone.target = null;
                                        if(drone.state==1){
                                            drone.state = 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            g.drawImage(image, 0, 0, null);

            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
    }

    public Intruder getTargetIntruder(int scannedI, int scannedJ) {
        for (int k = 0; k < intruders.size(); k++) {
            Intruder intruder = intruders.get(k);
            int distanceSquare;
            for (int i = intruder.x; i < intruder.x + intruder.size; i++) {
                for (int j = intruder.y; j < intruder.y + intruder.size; j++) {
                    int roundx = intruder.x + intruder.size / 2;
                    int roundy = intruder.y + intruder.size / 2;
                    distanceSquare = (roundx - i) * (roundx - i) + (roundy - j) * (roundy - j);
                    if (distanceSquare < intruder.rSquare) {
                        if (i == scannedI && j == scannedJ) {
                            return intruder;
                        }
                    }
                }
            }
        }
        return null;
    }

    //判断入侵者是否在守卫区内
    public boolean isInRange(Intruder intruder) {
        if (intruder.x < 200 + intruder.size || intruder.x > 1000 - intruder.size || intruder.y < 100 + intruder.size || intruder.y > 700 - intruder.size) {
            return false;
        } else {
            return true;
        }
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class DroneUI extends JFrame {
    ArrayList<Drone> drones=new ArrayList<>();
    ArrayList<Intruder> intruders=new ArrayList<>();
    ArrayList<Task> tasks=new ArrayList<>();


    public DroneUI() {
        setTitle("智能无人机平台4.0");
        setSize(1200,900);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        JButton button1 = new JButton("生产无人机");
        JButton button2 = new JButton("生产入侵者");
        JPanel panel = new JPanel();
        panel.setBackground(Color.lightGray);
        panel.add(button1);
        panel.add(button2);
        add(panel,BorderLayout.SOUTH);
        setVisible(true);

        Graphics g=this.getGraphics();
        //创建按钮监听器
        DroneListener droneListener = new DroneListener();
        //在创建监听器后立刻为集合赋值,让集合真正可用
        droneListener.drones=drones;
        droneListener.intruders=intruders;
        droneListener.tasks=tasks;

        button1.addActionListener(droneListener);
        button2.addActionListener(droneListener);

        //创建鼠标监听器
        addMouseListener(droneListener);

        //创建无人机线程
        DroneThread droneThread = new DroneThread(g);
        //创建任务线程
        TaskThread taskThread = new TaskThread();

        //将共享内存的数组传入到两个线程中
        droneThread.drones=drones;
        droneThread.intruders=intruders;
        droneThread.tasks=tasks;//要先将DroneUI类中的tasks传入给droneThread,这样才能在执行DroneThread的时候保证此时的tasks不是null

        taskThread.drones=drones;
        taskThread.tasks=tasks;

        droneThread.start();
        taskThread.start();

    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
    }

    public static void main(String[] args) {
        new DroneUI();
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

import java.awt.*;


public class Intruder {
    int x;
    int y;
    int speedx;
    int speedy;
    int size=30;
    int blood=200;
    int rSquare=size*size/4;
    public Intruder(int x, int y, int speedx, int speedy) {
        this.x = x;
        this.y = y;
        this.speedx = speedx;
        this.speedy = speedy;
    }
    public void drawIntruder(Graphics g) {
        if (blood>0){
            Color color1 =new Color(0, 0, 0);
            g.setColor(color1);
            g.fillOval(x, y, size, size);
            Color color2 =new Color(213, 15, 15);
            g.setColor(color2);
            g.fillOval(x+5, y+5, size-10, size-10);
            Color color3 =new Color(0, 0, 0);
            g.setColor(color3);
            g.drawRect(x, y-5, size, 6);
            Color color4 =new Color(124, 244, 21);
            g.setColor(color4);
            g.fillRect(x+1,y-4,(int) (blood/200.0*(size-1)),5);
        }
    }
    public void move(){
        x+=speedx;
        y+=speedy;
        if(x<=0||x>=1160){
            speedx=-speedx;
        }
        if(y<=0||y>=760){
            speedy=-speedy;
        }
    }
    public void underAttack(){
        this.blood--;
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

public class ScanResult{
    int targetX;
    int targetY;

    public ScanResult(int targetX,int targetY) {
        this.targetY = targetY;
        this.targetX = targetX;
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

import java.awt.*;

public class Task {
    int x;
    int y;
    int size=10;
    int state;//0未被领取的任务;1被领取的任务;2已完成的任务
    public Task(int state, int x, int y) {
        this.state = state;
        this.x = x;
        this.y = y;
    }
    public void draw(Graphics g) {
        g.setColor(Color.yellow);
        g.fillRect(x-size/2,y-size/2,size,size);
    }
}
java 复制代码
package com.nwu.by0129.droneV4;

import java.util.ArrayList;

public class TaskThread extends Thread {
    ArrayList<Task> tasks;
    ArrayList<Drone> drones;

    @Override
    public void run() {
        for (; ; ) {
            //System.out.println("进入TaskThread");
            if (tasks != null) {
                if (drones != null) {
                    for (int i = tasks.size() - 1; i >= 0; i--) {
                        Task task = tasks.get(i);
                        if (task.state != 1) {
                            int nearestIndex = -1;
                            double minDis = 1000.0;
                            for (int j = drones.size() - 1; j >= 0; j--) {
                                Drone drone = drones.get(j);
                                //找到没有领取任务的无人机(只有巡逻状态的无人机可以接任务)
                                if (drone.state == 0) {
                                    //计算距离并找出最近的
                                    double currentDis = caculateDis(task, drone);
                                    if (currentDis <= minDis) {
                                        minDis = currentDis;
                                        nearestIndex = j;//把最近的无人机编号取出来
                                    }
                                }
                            }
                            if (nearestIndex != -1) {
                                drones.get(nearestIndex).state = 2;//无人机状态设为正在执行任务
                                drones.get(nearestIndex).targetTask = task;
                                System.out.println("任务被领取");
                                task.state = 1;//任务状态设为已被领取
                            } else {
                                System.out.println("没有可指挥的无人机");
                                task.state = 0;
                            }
                        }
                    }
                }
            }
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    double caculateDis(Task task, Drone drone) {
        double dis = Math.sqrt((task.x - drone.x) * (task.x - drone.x) + (task.y - drone.y) * (task.y - drone.y) * 1.0);
        return dis;
    }
}

运行结果截图及视频演示

  1. 运行截图
  1. 视频演示

智能无人机V4视频演示

总结

在本次V4版本的开发中,我加深了对于面向对象的理解,对于大部分重复的代码,我们可以通过一个方法来将其封装起来,重复调用即可;同时我也认识到了代码前期设计的重要性,前期的设计要规范化,要为之后的功能添加留出充足的拓展空间。

相关推荐
小高Baby@2 小时前
Go语言中面向对象的三大特性之继承的理解
开发语言·后端·golang
小高Baby@2 小时前
Go语言中面向对象的三大特性之封装的理解
开发语言·后端·golang
木卫二号Coding2 小时前
第七十七篇-V100+llama-cpp-python-server+Qwen3-30B+GGUF
开发语言·python·llama
半夏知半秋2 小时前
lua5.5版本新特性学习
开发语言·笔记·学习
木卫二号Coding2 小时前
第七十六篇-V100+llama-cpp-python+Qwen3-30B+GGUF
开发语言·python·llama
枫叶丹42 小时前
【Qt开发】Qt系统(十二)-> Qt视频
c语言·开发语言·c++·qt·音视频
AI量化价值投资入门到精通2 小时前
数据清洗:大数据领域的必备技能
大数据·开发语言·ai·php
青云交2 小时前
Java 大视界 -- Java 大数据在智能教育在线考试系统中的考试结果分析与教学反馈优化中的应用
java·在线考试·java大数据·智能教育
Ivanqhz2 小时前
向量化计算
开发语言·c++·后端·算法·支持向量机·rust