《飞机大战游戏》实训项目(Java GUI实现)(设计模式)(简易)

目录

一、最终实现后,效果如下。

(1)简单介绍本游戏项目(待完善)

(2)运行效果图(具体大家自己可以试)

初始运行情况。

手动更换背景图。

通过子弹攻击敌机,累计游戏分数。由变量"score"控制。

二、各个类的代码如下

(1)启动类(主类)

(2)自定义的"窗口"类(Frame)extends"JFrame"

(3)自定义"内容面板"类(Panel)extends"JPanel"

(4)"敌机"类(EnemyPlane)

(5)"本人飞机"类(Plane)

(6)"子弹"类(Fire)


一、最终实现后,效果如下。

(1)简单介绍本游戏项目(待完善)
  • 只是学校的简单的实训项目,里面还可以进行很多内容可以补充或者完善。
  • 里面有一个功能,博主实现的时候,"大"的敌机左右移动时,存在"摇摇晃晃"的情况。所以这里博主把这一部分的代码注释了,只让其"y的坐标值"变化。
  • "小"敌机移动速度快,"大"敌机移动速度慢。
  • 游戏界面的背景图,不会随着时间而进行改变(大家可以完善)。
  • "自己飞机"的键盘移动操作不是很流畅,需要完善。
  • "敌机"没有血量,自己操控的飞机没有血量,没有游戏结束"game over"的触发。
  • 只有子弹击中敌机的判定。当子弹的坐标与敌机坐标满足条件,就触发方法,将敌机remove()。
  • 子弹与敌机的创建都用到了线程的知识。并且通过"W"(上)、"S"(下)、"A"(左)、"D"(右)或者鼠标进行操控自己的飞机,进行攻击"x坐标指定范围内"、"y坐标为0"生成的敌机。
  • 基本的技术用到了Java GUI(可视化)提供的类"Panel"、"JFrame",以及其下的方法实现。
  • 当运行到一定的时间,该实训项目会出现报错地方(敌机生成线程、子弹生成线程)。
(2)运行效果图(具体大家自己可以试)
  • 初始运行情况。

  • 手动更换背景图。

  • 通过子弹攻击敌机,累计游戏分数。由变量"score"控制。

二、各个类的代码如下

(1)启动类(主类)
package ui;/*** @Title: Main* @Author HeYouLong* @Package ui* @Date 2024/9/12 上午8:33* @description:*/
public class Main {public static void main(String[] args) {Frame frame = new Frame();Panel panel = new Panel(frame);frame.add(panel);panel.begin();panel.fireBegin();frame.setVisible(true);}
}
(2)自定义的"窗口"类(Frame)extends"JFrame"
  • "JFrame"类是 Java Swing 图形用户界面工具包中的一个非常重要的类,它代表了一个窗口,是顶级容器之一。在 Swing 应用程序中,几乎所有的 GUI 组件都直接或间接地包含在一个"JFrame"窗口中。
  • JFrame 提供了窗口的基本功能,如标题栏、最小化/最大化按钮、关闭按钮以及可调整大小的边框。但是,JFrame 本身不包含任何可视化组件(如按钮、文本框等);这些组件必须被添加到 JFrame 的内容面板(ContentPane)中,而内容面板默认是一个 "JPanel"。
package ui;import javax.swing.*;/*** @Title: Frame* @Author HeYouLong* @Package ui* @Date 2024/9/12 上午8:32* @description:*/
public class Frame extends JFrame {public Frame(){setTitle("设计模式课程飞机大战");setSize(512,768);setLocationRelativeTo(null);//居中setResizable(false);//不准随便改变窗口大小setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口——>退出进程}
}
(3)自定义"内容面板"类(Panel)extends"JPanel"
  • "JPanel" 类是 Java Swing 图形用户界面工具包中的一个非常重要的类,它继承自 JComponent 并实现了 Container 接口。JPanel 是一种轻量级的容器,可以用来组织和管理其他 GUI 组件(如按钮、文本框、标签等)。与 JFrame 不同的是,JPanel 本身不是一个顶级容器,它必须被添加到某个顶级容器(如 JFrame、JDialog 或 JApplet)中才能显示。
  • 这个类的内容比较多,因为是"内容面板"嘛。
package ui;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;/*** @Title: Panel* @Author HeYouLong* @Package ui* @Date 2024/9/12 上午8:38* @description:*/
public class Panel extends JPanel {private BufferedImage bg = GetImg.getImg("bg5.jpg");private Plane plane;private List<EnemyPlane> enemyPlaneList = new ArrayList<>();private List<Fire> fires = new ArrayList<>();//敌机public void begin() {new Thread() {public void run() {while (true) {CreateEp(); //创建敌机 todoMoveEp(); //敌机移动 todohit(); //子弹碰撞try {Thread.sleep(20);} catch (InterruptedException e) {throw new RuntimeException(e);}repaint();//画敌机}}}.start();}private static int score=0;//判断子弹与敌机是否碰撞private void hit() {for (int i = 0; i < enemyPlaneList.size(); i++) {EnemyPlane enemyPlane = enemyPlaneList.get(i);for (int j = 0; j < fires.size(); j++) {Fire fire = fires.get(j);if(fire.x+fire.image.getWidth()/2>enemyPlane.getX() && fire.x<enemyPlane.getX()+enemyPlane.getImg().getWidth() && fire.y+fire.image.getHeight()/2>enemyPlane.getY() && fire.y<enemyPlane.getY()+enemyPlane.getImg().getHeight()){enemyPlaneList.remove(i);fires.remove(j);score++;}}}}//子弹的线程public void fireBegin() {new Thread() {public void run() {while (true) {//创建子弹fireCreate();//子弹移动fireMove();//休息线程try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}//画子弹repaint();}}}.start();}private void fireMove() {for (int i = 0; i < fires.size(); i++) {Fire fire = fires.get(i);fire.y=fire.y-10;}}private static int index = 0;private void fireCreate() {index++;if (index >= 12) {Fire fire = new Fire(plane);fires.add(fire);index = 0;}}private void MoveEp() {for (int i = 0; i < enemyPlaneList.size(); i++) {EnemyPlane enemyPlane = enemyPlaneList.get(i);enemyPlane.move();}}private static int count = 0;private void CreateEp() {count++;if (count >= 12) {EnemyPlane enemyPlane = new EnemyPlane();enemyPlaneList.add(enemyPlane);count = 0;}}public Panel(Frame frame) {plane = new Plane();//鼠标操作mouse();//键盘操作 todokey(frame);}private void key(Frame frame) {KeyAdapter keyAdapter = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);int i = e.getKeyCode();//获得按的键if (i == KeyEvent.VK_A || i == KeyEvent.VK_LEFT) {plane.setX(plane.getX() - 30);if (plane.getX() <= 0) {plane.setX(0);}} else if (i == KeyEvent.VK_D || i == KeyEvent.VK_RIGHT) {plane.setX(plane.getX() + 30);if (plane.getX() >= 395) {plane.setX(395);}} else if (i == KeyEvent.VK_W || i == KeyEvent.VK_UP) {plane.setY(plane.getY() - 30);if (plane.getY() <= 0) {plane.setY(0);}} else if (i == KeyEvent.VK_S || i == KeyEvent.VK_DOWN) {plane.setY(plane.getY() + 30);if (plane.getY() >= 635) {plane.setY(635);}}repaint();}};frame.addKeyListener(keyAdapter);}private void mouse() {MouseAdapter mouseAdapter = new MouseAdapter() {@Overridepublic void mouseMoved(MouseEvent e) {super.mouseMoved(e);plane.setX(e.getX() - plane.getImage().getWidth() / 2);plane.setY(e.getY() - plane.getImage().getHeight() / 2);//重新画repaint();}};addMouseListener(mouseAdapter);addMouseMotionListener(mouseAdapter);}@Overridepublic void paint(Graphics g) {super.paint(g);g.drawImage(bg, 0, 0, null);
//本人飞机初始位置g.drawImage(plane.getImage(), plane.getX(), plane.getY(), null);
//画敌机for (int i = 0; i < enemyPlaneList.size(); i++) {EnemyPlane enemyPlane = enemyPlaneList.get(i);g.drawImage(enemyPlane.getImg(), enemyPlane.getX(), enemyPlane.getY(), null);}//画子弹for (int i = 0; i < fires.size(); i++) {Fire fire = fires.get(i);g.drawImage(fire.image,fire.x, fire.y,fire.image.getWidth()/2,fire.image.getHeight()/2, null);}//画分数g.setColor(Color.white);Font font = new Font("黑体", Font.PLAIN, 22);g.setFont(font);g.drawString("当前游戏分数:"+score, 10, 20);}
}
(4)"敌机"类(EnemyPlane)

控制初始敌机生成的初始x、y坐标位置,控制出现边界,不同类型飞机移动速度等等

package ui;import java.awt.image.BufferedImage;
import java.util.Random;/*** @Title: EnemyPlane* @Author HeYouLong* @Package ui* @Date 2024/9/13 上午10:26* @description:*/
public class EnemyPlane {private int x;private int y;private int z;private BufferedImage img;public void move(){final int MOVE_SPEED = 10; // 固定的移动速度final int ENEMY_WIDTH = this.img.getWidth(); // 敌机图像的宽度if(z<10){y=y+14;return;}else{/*Random random = new Random();int i = random.nextInt(2);if(i==0){x -= MOVE_SPEED; // 假设z也影响移动速度,这里简单地使用z的模和加数来调整if (x <= 0) {x = 512-ENEMY_WIDTH; // 防止敌机移出屏幕左侧}}else {// 向右移动x += MOVE_SPEED; // 同上,调整移动速度if (x >= 512-this.img.getWidth()) {x = 0;}}*/y=y+8;}}public EnemyPlane() {Random random = new Random();int i = random.nextInt(15)+1;String j = i<10?"0"+i:i+"";//文件名String imgName = "ep"+j+".png";this.img=GetImg.getImg(imgName);//随机图片this.y=0;this.z=i;this.x=random.nextInt(512-this.img.getWidth());}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public BufferedImage getImg() {return img;}public void setImg(BufferedImage img) {this.img = img;}public int getZ() {return z;}public void setZ(int z) {this.z = z;}
}
(5)"本人飞机"类(Plane)

设置初始位置、选定飞机图片、getter()、setter()

package ui;import java.awt.image.BufferedImage;/*** @Title: Plane* @Author HeYouLong* @Package ui* @Date 2024/9/12 上午9:05* @description:*/
public class Plane {private int x;private int y;private BufferedImage image;public Plane() {x=200;y=500;image = GetImg.getImg("hero.png");}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public BufferedImage getImage() {return image;}public void setImage(BufferedImage image) {this.image = image;}
}
(6)"子弹"类(Fire)

子弹的初始坐标与飞机的坐标要进行适配,也就是有联系。选定子弹图片

package ui;import java.awt.image.BufferedImage;/*** @Title: Fire* @Author HeYouLong* @Package ui* @Date 2024/9/20 上午10:34* @description:*/
//子弹类
public class Fire {BufferedImage image;int x;int y;public Fire(Plane plane) {image = GetImg.getImg("fire.png");//子弹的坐标x=plane.getX()+plane.getImage().getWidth()/2-image.getWidth()/2/2;y=plane.getY()-image.getHeight()/2/2;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146453.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

java之单链表的基本概念及创建

1.链表的概念: 链表是一种 物理存储结构上非连续 存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 组成结构: 由一系列节点组成&#xff0c;每个节点包含数据域和指向下一个节点的指针。 优点: 动态大小&#xff0c;易于插入和删除操作。 缺点…

无人机集群路径规划:​北方苍鹰优化算法(Northern Goshawk Optimization,NGO)​求解无人机集群路径规划,提供MATLAB代码

一、单个无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化…

51单片机——LED灯篇

一、LED与单片机P2管脚相连 二、点亮一个LED灯 #include <STC89C5xRC.H> void main() { P2 0xFE; //1111 1110 } P2有8个管脚&#xff0c;对应8个二进制位。 LED灯右侧接电源是正极&#xff08;1&#xff09;&#xff0c;左侧给负极&#xff08;0&#xff09;即可…

Web_php_include 攻防世界

<?php show_source(__FILE__); echo $_GET[hello]; $page$_GET[page]; while (strstr($page, "php://")) { 以是否检测到php://为判断执行循环$pagestr_replace("php://", "", $page);//传入空值&#xff0c;替换 } include($page); ?&g…

第四范式发布AIGS Builder企业级软件重构助手,以生成式AI重构企业软件

产品上新 Product Release 今天&#xff0c;第四范式发布企业级软件重构助手——AIGS Builder&#xff0c;可快速重构软件交互体验。传统的企业软件开发&#xff0c;每次迭代通常要以月计。基于第四范式AIGS Builder大模型&#xff0c;用生成式Agent替代复杂的界面&#xff0c;…

AI绘制调整虚线教程

1、打开ai的软件&#xff0c;执行菜单栏中的文件—新建&#xff0c;新建一个大小任意的画板&#xff0c;画板大小根据自己的需要来设置。 2、选择工具箱中的直线段工具&#xff0c;将填充设置为无&#xff0c;描边设置为黑色&#xff0c;描边大小稍微设置大一点&#xff0c;画一…

模拟实现STL的stack、queue、deque等的介绍

文章目录 前言一、模拟实现stack二、模拟实现queue三、 deque总结 前言 模拟实现STL的stack、queue、deque等的介绍 一、模拟实现stack STL的stack是通过增加一个容器的模板参数&#xff0c;不直接实现栈&#xff0c;让容器存储数据&#xff0c;并调用容器的接口实现栈 name…

环形链表问题——力扣141,142

环形链表问题——力扣141&#xff0c;142 141.判断链表是否带环142.给定一个链表&#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 NULL 141.判断链表是否带环 这道题不能用比较链表中的值来判断是否带环&#xff0c;因为链表中不同节点的值可以相同…

Java免税购物商城:Spring Boot技术实现

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterrise JavaBeans&#xff09;的全面支持&#xff0c;java servlet AI&#xff0c;JS&#xff08;java server ages&#xff09…

matlab绘制二维云图,划分区域,并显示每个区域的均值

绘制成图如下&#xff1a; 代码如下&#xff1a; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%创建绘图的数据 ax0;bx1; ay0;by1; nx100; %数据的x轴点数 ny100; %数据的y轴点数 hx(bx-ax)/(nx-1); hy(by-ay)/(ny-1); Xax:hx:bx; Yay:hy:by; da…

有趣的Python-turtle

1 介绍 turtle 是 Python 中用来绘图的标准库&#xff08;Python解释器在安装后import直接使用&#xff09;&#xff0c;它简单且有趣&#xff0c;作为 Python初学者 都可以将它作为第一个学习对象&#xff0c;培养程序学习的兴趣&#xff0c;建立编程带来的成就感&#xff0c…

网络安全-webshell绕过,hash碰撞,webshell绕过原理

目录 一、题目 1.1 1.2 1.3 1.4 1.5 二、绕过动态检测引擎的一次尝试 三、一个比赛中的webshell 四、webshell绕过的原理以及哈希碰撞 五、JSP解释流程导致的绕过&#xff08;QT比赛&#xff09; 5.1环境 5.2例子 一、题目 这里我们通过几道题目来给大家讲解 1.…

Springboot3 + MyBatis-Plus + MySql + Uniapp 实现商品规格选择sku(附带自设计数据库,最新保姆级教程)

Springboot3 MyBatis-Plus MySql Uniapp 实现商品规格选择sku&#xff08;附带自设计数据库&#xff0c;最新保姆级教程&#xff09; 1、效果展示2、数据库设计2.1 商品表2.2 商品价格和规格中间表2.3 商品规格表 3、后端代码3.1 model3.2 vo3.3 mapper、server、serverImp3…

前端-javaScript:jquery补充

jquery绑定事件的方式 1.直接使用事件函数 &("div").click(function(){alert(1)}) 2.用统一的on函数绑定事件 on(事件类型&#xff0c;事件函数) $("div").on("click",function(){alert(2)}) 事件类型以参数的类型传递 --->可以同时绑…

go webapi上传文件 部属到linux

go厉害的地方&#xff0c;linux服务器上无需安装任务依赖就可以运行&#xff0c;大赞&#xff01; 一、编译 #在Goland中cmd中执行 go env -w GOARCHamd64 go env -w GOOSlinux go build main.go # 切换回来 否则无法运行 go env -w GOOSwindows go run main.go 拷贝到linux服…

C++——关联式容器(4):set和map

在接触了诸如二叉搜索树、AVL树、红黑树的树形结构之后&#xff0c;我们对树的结构有了大致的了解&#xff0c;现在引入真正的关联式容器。 首先&#xff0c;先明确了关联式容器的概念。我们之前所接触到的如vector、list等容器&#xff0c;我们知道他们实际上都是线性的数据结…

使用pe工具制作ubuntu备份系统和还原系统

使用pe工具制作ubuntu备份系统和还原系统 备份系统还原系统修复磁盘教程修复引导教程为什么使用pe工具 1,因为我个人觉得这个工具实现起来比systemback软件操作起来报错少些,而且装的快,其他系统同理 实验准备 1,一个电脑,一个pe启动U盘 备份系统 插入U盘,开机进入pe系…

[JavaEE] UDP协议

目录 再谈端口号 一、端口号的划分 二、UDP协议 三、UDP的特点 再谈端口号 一、端口号的划分 0-1023&#xff1a;知名端口号&#xff0c;端口号固定&#xff0c;其中包括HTTP&#xff0c;FTP&#xff0c;SSH等广为使用的应用层协议。 1024-65535&#xff1a;操作系统动态分…

数据结构|二叉搜索树

&#x1f36c; mooridy-CSDN博客 &#x1f36c;数据结构专栏&#xff08;更新中&#xff09; 目录 1. ⼆叉搜索树的概念 2. ⼆叉搜索树的性能分析 3.⼆叉搜索树key和key/value key搜索场景 key/value搜索场景 4. 二叉搜索树的代码实现 4.1 ⼆叉搜索树的插⼊ 4.2 ⼆叉搜索…

java----LinkedHashMap

.由键决定:有序、不重复、无索引 .这里的有序指的是保证存储和去除的元素顺序一致 原理:底层数据结构依然是哈希表,只是每个键值对元素又额外多了一个双链表的机制记录存储的顺序。 内容来自:集合进阶-09-LinkedHashMap_哔哩哔哩_bilibili