巴音郭楞蒙古自治州网站建设_网站建设公司_图标设计_seo优化
2025/12/23 17:50:27 网站建设 项目流程

小游戏制作——飞机大战

java 实现

耗时四天,通过借鉴学习别人,到自己写代码。比较费头发。但最终也还是肝了出来。本来还想弄一个 菜单栏,用该改变战机和子弹,但迫于时间有限。能先写到这里了。等过段时间,我再来完善它!

1.首先 我将英雄机,敌机,子弹,玩家。都分别当做对象来处理。单独写.java文件。
2. 写一个窗口(GUI编程)。存放所有的对象。并行多线程,因为敌机 英雄机 子弹,都需要同时运行。不断检测敌机是否被子击中,英雄机是否碰到敌机。所以:这些对象 都要继承 Thread 重写 run 方法
3. 事件监听器也有写,在英雄机碰到敌机时触发,弹出窗口Gameover 并且关闭所有的窗口。结束进程。
4. 因为 敌机和子弹,在窗口中都会同时出现多个。我使用了vector 集合用来存放对象。 敌机和子弹都会消失,使用集合的 remove 方法就可以。

vector 和 list 的区别:
vector:连续存储结构:vector是可以实现动态增长的对象数组,支持对数组高效率的访问和在数组尾端的删除和插入操作,在中间和头部删除和插入相对不易,需要挪动大量的数据。

它与数组最大的区别就是vector不需程序员自己去考虑容量问题,库里面本身已经实现了容量的动态增长,而数组需要程序员手动写入扩容函数进形扩容。
list:非连续存储结构:list是一个双链表结构,支持对链表的双向遍历。每个节点包括三个信息:元素本身,指向前一个元素的节点(prev)和指向下一个元素的节点(next)。

因此list可以高效率的对数据元素任意位置进行访问和插入删除等操作。由于涉及对额外指针的维护,所以开销比较大。

5. 对方向键 的键值 做出了解。 玩家通过方向键来操控英雄机。需要,switch 语句进行识别 玩家按了哪个键。但同时,英雄机的移动范围也是有限的。不能移出窗口。
6. 将所有的java文件 存放在同一目录下,来自同一个包。

其余的小点:我在代码中有注释。大家多加理解吧!不理解可以私信我哦!

GameFrame.java 文件 窗口文件

package VacationTest.PlaneFight.src; import javax.swing.ImageIcon; import javax.swing.JFrame; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; import java.util.Vector; public class GameFrame extends JFrame { //对英雄机和敌机作提前声明 HeroPlane heroplane; EnemyPlane enemyPlane; // 定义子弹集合 Vector<bullet> bullets = new Vector<>(); //敌机集合 Vector<EnemyPlane> enemys = new Vector<>(); GameFrame frame; public GameFrame() { frame = this ;// 后面 敌机的线程中要使用 // 创建英雄机 heroplane = new HeroPlane(); //启动英雄机线程 heroplane.start(); // 设置窗体的宽高 this.setSize(500, 760); this.setTitle("飞机大战---小帅制作"); this.setResizable(false);//设置 用户是否可以调整窗口的大小 这里设置为 否 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null);//设置窗口 相对于屏幕的位置,null 指:处于屏幕中央 // 窗口可见 this.setVisible(true); // 新建线程,让 画笔 不断 重复 new Thread(new Runnable() {//内部类。 @Override public void run() { while (true) { repaint();//不断重复画 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //产生敌机的线程 new Thread(new Runnable(){ //产生随机数 Random r = new Random(); @Override //重写run 方法 public void run(){ while(true){ EnemyPlane enemyPlane = new EnemyPlane(r.nextInt(500), 0,frame);// 随机产生敌机,并创建敌机对象 enemyPlane.start(); // 启动线程 //随机产生敌机 enemys.add(enemyPlane); // 将 敌机对象 添加到 enemy 集合中 try{ Thread.sleep(500); }catch(InterruptedException e){ e.printStackTrace(); } } } }).start(); } /** * 在窗口上画图片,需要不断重复的画,使用API中 paint 画笔 重写其中的方法 * * @param g */ public void paint(Graphics g) { //System.out.println("绘制画板"); // 画背景 BufferedImage image = (BufferedImage) this.createImage(this.getSize().width, this.getSize().height); // 高效缓存画笔 Graphics pen = image.getGraphics(); pen.drawImage(new ImageIcon("G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\Background.jpg").getImage(),0, 0, null); // 画英雄机 pen.drawImage(heroplane.img, heroplane.x, heroplane.y, heroplane.width, heroplane.height, null); // 飞机发射子弹 for (int i = 0; i < bullets.size(); i++) { //System.out.println("bullet"); // 实例化 子弹对象 b bullet b = bullets.get(i); if (b.y > 0) pen.drawImage(b.img, b.x, b.y -= b.speed, b.width, b.height, null); else // 子弹超出上边界 移除 bullets.remove(b); } //产生敌机 for (int i = 0; i < enemys.size(); i++) { //实例化 敌机对象 ep EnemyPlane ep = enemys.get(i); if (ep.y < 760) pen.drawImage(ep.img, ep.x, ep.y += ep.speed, ep.width, ep.height, null); else enemys.remove(ep); } // 生效 g.drawImage(image, 0, 0, null); } public static void main(String[] args) { GameFrame frame = new GameFrame(); Player player = new Player(frame); //给 玩家注册事件监听器 frame.addKeyListener(player); } }

HeroPlane.java 文件 英雄机文件

package VacationTest.PlaneFight.src; import java.awt.Image; import javax.swing.ImageIcon; public class HeroPlane extends Thread { int x = 230, y = 650; int width = 50, height = 50; int speed = 8; Image img = new ImageIcon( "G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\HeroPlane.png") .getImage(); // 定义方向键标志 up down left right boolean up, down, left, right; // 两种 构造器 public HeroPlane() { } public HeroPlane(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public void run() { while (true) { // 实现 英雄机的 移动 if (up) { if (y > 20) { y -= speed; } else { y -= 0; } } if (down) { if (y < 700) y += speed; else y += 0; } if (left) { if (x > 10) x -= speed; else x -= 0; } if (right) { if (x < 440) x += speed; else x += 0; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }

EnemyPlane.java 文件 敌机文件

package VacationTest.PlaneFight.src; import java.awt.Image; import java.awt.Rectangle; import javax.swing.*; import VacationTest.PlaneFight.src.Gameover.MyFrame;// 导入 游戏结束的 包 自己写的java 文件 public class EnemyPlane extends Thread { public GameFrame gf; // 敌机的位置 大小 速度 int x, y; int width = 50, height = 50; int speed = 3; Image img = new ImageIcon( "G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\EmenyPlane.png") .getImage(); // 构造器 public EnemyPlane(int x, int y, GameFrame gf) { super(); this.x = x; this.y = y; this.gf = gf; } // 构造器 public EnemyPlane(int x, int y, int width, int height, GameFrame gf) { super(); this.x = x; this.y = y; this.width = width; this.height = height; this.gf = gf; } // 重写run方法 在线程启动时 执行 public void run() { while (true) { if (hit()) { // System.out.println("hit............."); // 敌机被击毁后,速度变为0 图片更换为 爆炸图片 this.speed = 0; this.img = new ImageIcon( "G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\boom3.png") .getImage(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 子弹击毁 移除敌机 gf.enemys.remove(this); break; } // 敌机超出下边界 移除敌机 if (this.y > 760) { gf.enemys.remove(this); break; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if (crash()) { this.speed = 0; this.img = new ImageIcon().getImage(); new MyFrame(); //实例化MyFrame对象 gf.enemys.remove(this); gf.heroplane.img = new ImageIcon( "G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\HeroPlaneBoom.png") .getImage(); try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } //gf.heroplane.addActionListener(new broken()); System.exit(0); } } } // 检测碰撞 public boolean hit() { // Swing技术中,已经实现相关算法 // 给出敌机的矩形 Rectangle myrect = new Rectangle(this.x, this.y, this.width, this.height); Rectangle rect = null;// 给出子弹的矩形 for (int i = 0; i < gf.bullets.size(); i++) { bullet b = gf.bullets.get(i); rect = new Rectangle(b.x, b.y, b.width, b.height); // 碰撞检测 if (myrect.intersects(rect)) { return true; } } return false; } // 检测 英雄机和 敌机碰撞 public boolean crash() { Rectangle myrect = new Rectangle(this.x, this.y, this.width, this.height); Rectangle rect2 = new Rectangle(gf.heroplane.x, gf.heroplane.y, gf.heroplane.width, gf.heroplane.height); if (myrect.intersects(rect2)) { return true; } return false; } }

bullet.java文件 子弹文件

package VacationTest.PlaneFight.src; import java.awt.Image; import javax.swing.ImageIcon; public class bullet { int x; int y; int width=30; int height=40; int speed = 15; Image img = new ImageIcon("G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\bullet2.png").getImage(); public bullet(int x,int y){ this.x = x; this.y = y; } public bullet(int x,int y ,int width , int height){ this.x = x; this.y = y; this.width = width; this.height = height; } }

Player.java 文件 玩家文件

package VacationTest.PlaneFight.src; import java.awt.event.*; public class Player extends KeyAdapter{ //传入 frame 对象 也就是 整个窗体中的所有属性值 使用 对象名.方法 进行调用 GameFrame frame; public Player(GameFrame frame){ this.frame = frame; } /** * 定义一个玩家,操作键盘的上下左右。以及 发射子弹 空格 * 38 40 37 39 对应 上下左右 * 重写 keyPressed 和 keyReleased 方法 并使用监听器 判断玩家按哪个键 */ public void keyPressed(KeyEvent e){ int keycode = e.getKeyCode(); //System.out.println(keycode);//利用该语句 可以 知道 键盘上的按键 值是多少。 switch(keycode){ case 38: frame.heroplane.up = true;break; case 40: frame.heroplane.down = true;break; case 37: frame.heroplane.left = true;break; case 39:frame.heroplane.right = true;break; case 32:addBullet();break; } } public void keyReleased(KeyEvent e){ int keycode = e.getKeyCode(); switch(keycode){ case 38: frame.heroplane.up = false;break; case 40: frame.heroplane.down = false;break; case 37: frame.heroplane.left = false;break; case 39:frame.heroplane.right = false;break; } } // 发射子弹方法 在 键值为 32 时 触发 public void addBullet(){ frame.bullets.add(new bullet(frame.heroplane.x+15, frame.heroplane.y-20)); } }

Gameover.java文件 游戏结束文件

package VacationTest.PlaneFight.src; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; public class Gameover{ static GameFrame frame; public static class MyFrame extends JFrame { //创建新类,继承自JFrame private static final long serialVersionUID = 1L; public MyFrame() { Container container = getContentPane(); //创建一个容器 container.setLayout(null); //JLabel jl = new JLabel("这是一个JFrame窗体"); //在窗体中设置标签 //jl.setHorizontalAlignment(SwingConstants.CENTER); //将标签的文字至于标签中间的位置 //container.add(jl); //将标签添加到容器中 JButton jb = new JButton(""); //定义一个按钮 ImageIcon img = new ImageIcon("G:\\Users\\Administrator\\eclipse-workspace\\test\\src\\VacationTest\\PlaneFight\\Image\\Gameover.jpg"); img.setImage(img.getImage().getScaledInstance(350,150,0)); jb.setBounds(0, 0, 350, 150); //设置按钮的大小 jb.setIcon(img); jb.addActionListener(new ActionListener() { //为按钮添加点击事件 @Override public void actionPerformed(ActionEvent e){ try { Thread.sleep(1500); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.exit(0); } }); container.add(jb); setSize(360,180); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setVisible(true); setLocationRelativeTo(null);//设置窗口 相对于屏幕的位置,null 指:处于屏幕中央 } } }

在代码中使用的图片,以及素材,已经放在百度网盘里了。
注意:使用的图片路径 要改。
https://pan.baidu.com/s/1L70YtfqrBg8iWqFxmxB1jA
提取码:p6o2

Java程序员如今深陷技术迭代放缓与行业需求收缩的双重困境,职业发展空间正被新兴技术浪潮持续挤压。面对当前Java程序员可能面临的“发展瓶颈”或行业挑战,更积极的应对策略可以围绕技术升级、方向转型、能力拓展三个核心展开,而非被动接受“不行”的标签,通过调查对比,我发现人工智能大模型是个很好的出路。

技术升级与转型机会

发挥Java在企业级应用中的优势

说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。

结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”

先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。

即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!

如何学习AGI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询