Java线程进阶:无人机自动防空平台开发教程

Java线程进阶:无人机自动防空平台开发教程

大家好!今天我们利用上次提到的线程来开发一个无人机自动防空平台,主要功能是无人机巡逻发现并攻击敌机,在过程中可随时添加无人机和敌机,程序中还设有机库,无人机没电或弹药不足即刻前往机库进行恢复。

在这里插入图片描述


第一版本的效果是这样,无人机只在红色矩形内生产和移动,红色矩形表示无人机要巡逻的地方,敌机会从红色矩形外进入。

今天我带大家完成第一部分,无人机和敌机的生成、绘制和移动。

一、绘制窗体

首先我们要把窗体绘制出来,基本的窗体绘制之前的文章有提到,大家自行查看。我们是通过点击按钮来生产无人机和敌机,所以要在窗体下面设置按钮,因为窗体没有用流式布局,若添加按钮,则按钮会占满整个窗体。若只添加一个按钮,则使用边框布局,将按钮放在窗体下面,但若要添加多个按钮还需要添加面板对象JPanel,将按钮添加到面板上,再将面板使用边框布局添加到窗体上。

setTitle("智能无人机指挥系统");setSize(1200,1000);setDefaultCloseOperation(3);setLocationRelativeTo(null);//居中显示//添加面板JPanel btnPanel =newJPanel(); btnPanel.setBackground(Color.LIGHT_GRAY);//设置颜色//添加按钮JButton btn =newJButton("生产无人机"); btnPanel.add(btn);JButton btn1 =newJButton("生产入侵者"); btnPanel.add(btn1);add(btnPanel,BorderLayout.SOUTH);//在窗体上添加面板//因为没有给窗体设置流式布局,所以按钮会占满整个窗体,使用边框布局Borderlayout将按钮放在窗体下面//add(btn,BorderLayout.SOUTH);//因为要添加多个按钮所以此方法不用setVisible(true);

二、无人机的生成

因为要生成多个无人机,所以可以将无人机设置成一个类,在类中添加无人机的属性和方法。

在这里插入图片描述


我们将无人机制作成如图所示的样子。浅绿色表示无人机的雷达范围,在雷达范围中扫描敌机,蓝色表示无人机本机,红色表示无人机的状态,比如电量充足状态,电量不足状态等。

1.无人机的属性

坐标、速度、雷达范围、无人机尺寸、无人机状态等

//属性int x,y;//坐标int speedx,speedy;//速度int size;//无人机尺寸int state;//无人机状态int stateSize;//无人机状态圆的大小int scanSize;//雷达范围

2.无人机的方法

  • 构造方法
    在构造方法中设置好无人机的属性
//构造方法publicDrone(int x,int y,int speedx,int speedy,int state){this.x = x;this.y = y;this.speedx = speedx;this.speedy = speedy;this.state = state;this.scanSize =100;this.size =30;this.stateSize =15;}
  • 绘制方法
    通过画不同的圆绘制无人机,注意圆的大小、位置、颜色要合适。
//绘制无人机方法publicvoiddrawDrone(Graphics bg){Color color1 =newColor(0,255,150,90); bg.setColor(color1); bg.fillOval(x,y,scanSize,scanSize);Color color2 =newColor(62,62,222); bg.setColor((color2)); bg.fillOval(x+35,y+35,size,size);Color color3 =newColor(255,0,0); bg.setColor(color3); bg.fillOval(x+42,y+42,stateSize,stateSize);}
  • 移动方法
    当无人机碰到红色矩形则反弹,速度变为相反数。
//无人机移动方法publicvoidmove(){if(x>1000-scanSize||x<200){//碰到边界 speedx =-speedx;//改变无人机x运动方向}if(y>780-scanSize||y<180){//碰到边界 speedy =-speedy;//改变无人机y运动方向} x+=speedx; y+=speedy;}

三、敌机的生成

和无人机一样,敌机也封装成一个类,包含属性和方法。

publicclassInvader{//属性int x,y;//坐标int speedx,speedy;//速度int size;//尺寸int blood;//方法//构造方法publicInvader(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;}//绘制方法publicvoiddrawInvader(Graphics g){if(blood<=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);}//移动方法publicvoidmove(){if(blood<=0){return;}if(x-1>1200-(size+2)||x-1<0){//碰到边界 speedx =-speedx;//改变x运动方向}if(y-1>960-(size+2)||y-1<20){//碰到边界 speedy =-speedy;//改变y运动方向} x+=speedx; y+=speedy;}}

敌机在红色矩形外产生,所以碰到边界的范围有所变化。

四、无人机线程

当无人机和敌机移动时,并不会跟我们想象的一样移动,移动路程上的图并不会消失,一直留在窗体上,只有当无人机和敌机不再移动窗体才可刷新。

但我们的无人机和敌机需要一直移动,要解决这个问题,我们上篇文章提到的线程就派上用场啦!

这里我们需要创建一个无人机线程,将每一次的移动画到一张缓冲图片上,将图片直接显示到窗体上,在每一次移动之间画一张白饭覆盖之前的图片,就能解决这个问题了。

publicclassDroneThreadextendsThread{ArrayList<Drone> droneList;ArrayList<Invader> invaderList;Graphics g;publicDroneThread(Graphics g){this.g=g;}//重写run方法publicvoidrun(){while(true){try{Thread.sleep(30);//延时处理}catch(InterruptedException e){thrownewRuntimeException(e);}//缓冲图片:将画的过程显示在图片上,画完再将整张图片显示在窗体上//高度960是给按钮留一定位置使按钮不会被刷新BufferedImage img =newBufferedImage(1200,960,2);Graphics bg = img.getGraphics();//画白板 bg.setColor(Color.WHITE); bg.fillRect(0,0,1200,960); bg.setColor(Color.RED); bg.drawRect(200,180,800,600);//800*600 无人机防守范围//遍历无人机数组,取出无人机对象,调用绘制和移动方法for(int i=0;i<droneList.size();i++){Drone drone = droneList.get(i); drone.drawDrone(bg); drone.move();}for(int i =0; i < invaderList.size(); i++){Invader invader = invaderList.get(i); invader.drawInvader(bg); invader.move();} g.drawImage(img,0,0,null);}}}

五、监听器的添加及多线程间的联系

当我们按下不同按钮,对应的物体就会生产出来,所以我们需要给按钮添加动作监听器。

但是怎么做到按一下生产无人机按钮就能生产一个无人机呢?

相信大家看到前面的代码也会有这个疑问?也会想不明白为什么会有ArrayList数组的出现。

在这里插入图片描述


上图就是多线程之间建立联系的方法,创建一个无人机数组,将无人机数组放到内存空间中,并传入监听器和无人机线程中,每点击一次按钮无人机数组就添加一个无人机对象,在无人机线程中遍历该数组画出所有无人机,敌机也是一样的方法。

程序完整代码

DroneUI:

importjavax.swing.*;importjava.awt.*;importjava.util.ArrayList;publicclassDroneUIextendsJFrame{//无人机数组ArrayList<Drone> droneList =newArrayList<>();//入侵者数组ArrayList<Invader> invaderList =newArrayList<>();Graphics g;publicDroneUI(){setTitle("智能无人机指挥系统");setSize(1200,1000);setDefaultCloseOperation(3);setLocationRelativeTo(null);//居中显示//添加面板JPanel btnPanel =newJPanel(); btnPanel.setBackground(Color.LIGHT_GRAY);//设置颜色//添加按钮JButton btn =newJButton("生产无人机"); btnPanel.add(btn);JButton btn1 =newJButton("生产入侵者"); btnPanel.add(btn1);add(btnPanel,BorderLayout.SOUTH);//在窗体上添加面板//因为没有给窗体设置流式布局,所以按钮会占满整个窗体,使用边框布局Borderlayout将按钮放在窗体下面//add(btn,BorderLayout.SOUTH);//因为要添加多个按钮所以此方法不用setVisible(true);//动作监听器DroneListener dl =newDroneListener(); btn.addActionListener(dl);//给按钮添加动作监听器 btn1.addActionListener(dl);//给按钮添加动作监听器 g =getGraphics();//从窗体上获取画笔DroneThread dt =newDroneThread(g);//无人机线程//将共享内存空间中的数组传到两个线程中 dl.droneList = droneList;//监听器线程 dt.droneList = droneList;//无人机线程 dl.invaderList = invaderList; dt.invaderList = invaderList;//启动无人机线程 dt.start();//在无人机所有动作完成后启动无人机线程,使无人机线程启动更加安全}//启动线程不要写到下面这种重复调用的方法里面//paint方法:绘制窗体 刷新窗体publicvoidpaint(Graphics g){//Graphics 图形工具类 提供坐标,就可以绘制图形super.paint(g);}publicstaticvoidmain(String[] args){DroneUI ui =newDroneUI();}}

Drone:

importjava.awt.*;publicclassDrone{//属性int x,y;//坐标int speedx,speedy;//速度int size;//无人机尺寸int state;//无人机状态int stateSize;//无人机状态圆的大小int scanSize;//雷达范围//方法//构造方法publicDrone(int x,int y,int speedx,int speedy,int state){this.x = x;this.y = y;this.speedx = speedx;this.speedy = speedy;this.state = state;this.scanSize =100;this.size =30;this.stateSize =15;}//绘制无人机方法publicvoiddrawDrone(Graphics bg){Color color1 =newColor(0,255,150,90); bg.setColor(color1); bg.fillOval(x,y,scanSize,scanSize);Color color2 =newColor(62,62,222); bg.setColor((color2)); bg.fillOval(x+35,y+35,size,size);Color color3 =newColor(255,0,0); bg.setColor(color3); bg.fillOval(x+42,y+42,stateSize,stateSize);}//无人机移动方法publicvoidmove(){if(x>1000-scanSize||x<200){//碰到边界 speedx =-speedx;//改变无人机x运动方向}if(y>780-scanSize||y<180){//碰到边界 speedy =-speedy;//改变无人机y运动方向} x+=speedx; y+=speedy;}}

Invader:

importjava.awt.*;publicclassInvader{//属性int x,y;//坐标int speedx,speedy;//速度int size;//尺寸int blood;//方法//构造方法publicInvader(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;}//绘制方法publicvoiddrawInvader(Graphics g){if(blood<=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);}//移动方法publicvoidmove(){if(blood<=0){return;}if(x-1>1200-(size+2)||x-1<0){//碰到边界 speedx =-speedx;//改变x运动方向}if(y-1>960-(size+2)||y-1<20){//碰到边界 speedy =-speedy;//改变y运动方向} x+=speedx; y+=speedy;}}

DroneThread:

importjava.awt.*;importjava.awt.image.BufferedImage;importjava.util.ArrayList;publicclassDroneThreadextendsThread{ArrayList<Drone> droneList;ArrayList<Invader> invaderList;Graphics g;publicDroneThread(Graphics g){this.g=g;}//重写run方法publicvoidrun(){while(true){try{Thread.sleep(30);//延时处理}catch(InterruptedException e){thrownewRuntimeException(e);}//缓冲图片:将画的过程显示在图片上,画完再将整张图片显示在窗体上//高度960是给按钮留一定位置使按钮不会被刷新BufferedImage img =newBufferedImage(1200,960,2);Graphics bg = img.getGraphics();//画白板 bg.setColor(Color.WHITE); bg.fillRect(0,0,1200,960); bg.setColor(Color.RED); bg.drawRect(200,180,800,600);//800*600 无人机防守范围//遍历无人机数组,取出无人机对象,调用绘制和移动方法for(int i=0;i<droneList.size();i++){Drone drone = droneList.get(i); drone.drawDrone(bg); drone.move();}for(int i =0; i < invaderList.size(); i++){Invader invader = invaderList.get(i); invader.drawInvader(bg); invader.move();} g.drawImage(img,0,0,null);}}}

DroneListener:

importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.util.ArrayList;importjava.util.Random;publicclassDroneListenerimplementsActionListener{ArrayList<Drone> droneList;ArrayList<Invader> invaderList;//随机数Random ran =newRandom();publicvoidactionPerformed(ActionEvent e){String name = e.getActionCommand();if(name.equals("生产无人机")){int x = ran.nextInt(200,700);int y = ran.nextInt(180,680);int speedx = ran.nextInt(5)-2;//-2~2 5的意思是随机0 1 2 3 4 不包括5int speedy = ran.nextInt(5)-2;//-2~2while(true){if(speedx!=0&&speedy!=0){break;} speedx = ran.nextInt(5)-2;//-2~2 5的意思是随机0 1 2 3 4 不包括5 speedy = ran.nextInt(5)-2;//-2~2}//点击按钮 生产无人机Drone drone =newDrone(x, y, speedx, speedy,0); droneList.add(drone);}elseif(name.equals("生产入侵者")){//入侵者在红框四周产生//防止入侵者在反弹边界生成将x,y值减小一点int x = ran.nextInt(1150);int y = ran.nextInt(21,910);while(true){if(x<200||x>1000||y<180||y>780){break;} x = ran.nextInt(1140); y = ran.nextInt(21,910);}int speedx = ran.nextInt(5)-2;//-2~2 5的意思是随机0 1 2 3 4 不包括5int speedy = ran.nextInt(5)-2;//-2~2while(true){if(speedx!=0&&speedy!=0){break;} speedx = ran.nextInt(5)-2;//-2~2 5的意思是随机0 1 2 3 4 不包括5 speedy = ran.nextInt(5)-2;//-2~2}//点击按钮 生产入侵者Invader invader =newInvader(x,y,speedx,speedy,45); invaderList.add(invader);}}}

以上就是我本次分享,感谢观看!

Read more

Java LLM开发框架全面解析:从Spring AI到Agents-Flex

Java LLM开发框架全面解析:从Spring AI到Agents-Flex

🧑 博主简介:ZEEKLOG博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可关注公众号 “ 心海云图 ” 微信小程序搜索“历代文学”)总架构师,16年工作经验,精通Java编程,高并发设计,分布式系统架构设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。 🤝商务合作:请搜索或扫码关注微信公众号 “ 心海云图 ” Java LLM开发框架全面解析:从Spring AI到Agents-Flex 在人工智能席卷全球的今天,Java开发者无需转向Python生态,也能充分利用大语言模型的强大能力,这得益于日益成熟的Java LLM开发框架。 近年来,随着大语言模型(LLM)技术的迅猛发展,AI能力已成为现代应用开发不可或缺的部分。作为企业

By Ne0inhk
惊了!用 JavaAI 撸电商核心功能,我从 “代码小白“ 变 “项目大神“,3 小时搞定别人 3 天的活

惊了!用 JavaAI 撸电商核心功能,我从 “代码小白“ 变 “项目大神“,3 小时搞定别人 3 天的活

惊了!用JavaAI撸电商核心功能,我从"代码小白"变"项目大神",3小时搞定别人3天的活(附完整流程+代码) 家人们谁懂啊!以前听说要做电商系统,我直接吓得关掉了IDEA——光是"商品管理"“订单流程”“购物车计算"这几个词,就够我啃一周文档。但自从用了JavaAI工具(我用的是飞算JavaAI,亲测好用),我发现开发居然能这么"躺平”:不用死磕SQL,不用纠结逻辑,甚至不用写重复代码,AI直接把"半成品"喂到嘴边,我只需要做"选择题"就行! 今天就带大家手把手用JavaAI开发电商3大核心模块:商品管理(上架/搜索/库存)、购物车(

By Ne0inhk
Java synchronized关键字详解:从入门到原理(两课时)

Java synchronized关键字详解:从入门到原理(两课时)

文章目录 * 适用对象 * 学习目标 * 课程安排 * 第一课时:synchronized基础与使用 * 1.1 从一个线程安全问题开始 * 1.2 synchronized是什么? * 1.3 初识synchronized的三种用法 * 1.3.1 修饰实例方法 * 1.3.2 修饰静态方法 * 1.3.3 修饰代码块 * 1.4 深入理解锁的范围 * 1.4.1 三种锁的对比表格 * 1.4.2 常见面试题解析 * 1.5 synchronized的核心特性 * 1.5.1 可重入性 * 1.5.2 可见性保证 * 1.

By Ne0inhk

手把手教你免费获取豆包 AI API Key 并接入前端项目

文章目录 * 手把手教你免费获取豆包 AI API Key 并接入前端项目(超详细图文版) * 一、先说清楚:豆包 AI API 在哪里申请? * 二、准备工作(2 分钟完成) * 三、正式获取 API Key(5 分钟搞定) * 步骤 1:进入火山方舟平台 * 步骤 2:创建 API Key(最重要) * 步骤 3:开通豆包 AI 模型 * 步骤 4:创建「推理接入点」获取 Endpoint ID * 四、拿到这两个东西就成功了 * 五、前端接入代码示例(Vue3 可直接用)

By Ne0inhk