java毕业设计 您所在的位置:网站首页 平面图形大全愤怒小鸟怎么画简单 java毕业设计

java毕业设计

2024-07-14 21:55| 来源: 网络整理| 查看: 265

基于java+Java awt+swing的愤怒的小鸟游戏设计与实现(毕业论文+程序源码)

大家好,今天给大家介绍基于java+Java awt+swing的愤怒的小鸟游戏设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴,可以进入我的博客主页查看左侧最下面栏目中的自助下载方法哦

文章目录:

基于java+Java awt+swing的愤怒的小鸟游戏设计与实现(毕业论文+程序源码)1、项目简介2、资源详情3、关键词:4、毕设简介5、资源下载

1、项目简介 本文将介绍使用Java语言实现经典的益智类游戏作品“愤怒的小鸟”的开发。游戏将主要实现以下几个功能:游戏玩法功能、页面管理功能、难度和级别功能、碰撞功能、鸟类管理功能、玩家管理功能和备份功能等。此游戏不仅可以给玩家带来欢乐,也会使玩家对开发游戏产生极大地兴趣,让玩家切身体会到Java语言在生活方面的无处不在。 2、资源详情

项目难度:中等难度 适用场景:相关题目的毕业设计 配套论文字数:29900个字81页 包含内容:整套源码+完整毕业论文+答辩PPT+任务书+辅导视频+运行截图

3、关键词: Java;C++;Jbox2D;物理运动;愤怒的小鸟 4、毕设简介

提示:以下为毕业论文的简略介绍,项目源码及完整毕业论文下载地址见文末。

绪论 1.1 游戏开发的背景 省略

1.2 典型的Java游戏介绍 省略

1.3 游戏开发的意义 省略

2 开发环境 2.1 开发语言 Java语言是一种面向对象的编程语言,它不仅拥有着C++语言的长处,而且也将C++中的多重继承和指针等概念进行摒弃,Java语言不仅具有易用实用的特征,同时也是一种功能强大的编程语言。

Java语言的特征大致可以分为以下一些:简单性、面向对象、分布式开发、稳健性、安全性、平台独立性、可移植性和多线程以及动态特性。这些特性以及Java语言本身的强大,是Java语言得以风靡全球的根本原因。 Java语言从外部看起来确实很像C++语言,但是为了使Java语言不那么晦涩难懂和难于学习,开发设计人员将很多原本用于C++语言的功能进行选择性删除。比如:Java语言将重载和多个继承功能中的重载运算符排除在外,并且去除主文件,从而消除了预处理器。再由于Java语言准确的是没有结构的,并且字符串数组是对象,所以指针存在也是不必要的。去除C++语言的糟粕后,Java语言可以自动管理参考对象和间接引用、自动垃圾收集,这些功能都可由使用户不必担心内存管理问题,从在将更多的时间和精力投入到研发开发当中,无疑是大大提升了编程开发效率。

如图2-1为Java语言总体特点: 在这里插入图片描述

图2-1 Java语言特点 由于Java语言是面向对象的语言。所以对于程序员来说,这意味着数据必须在方法中声明和操纵,笼统来说,程序员只需要学习对方法的熟悉和使用,而不是严格的创造方法过程。Java语言的特点使得语句不单单依赖于实现的方面,这种特殊的特点使得Java环境本身对新的硬件平台和操作系统是可移植的,并且起重要作用的Java编译器也是用Java语言所编写的,而且还包括用ANSIC语言编写的Java运行时系统。Java语言旨在适应进化,这说明它是一种动态语言。

由于Java语言的本质,Java游戏不会受到太多来自软件运行平台的诸多限制。假如我们以Java语言进行开发时,哪怕要重新编译成千上万个类,也只不过是花费很少的时间便可以办到的事情,这是CPP编译速度所无法企及的。而Java语言语法在一定程度上要比C语言或者C++语言简洁方便很多,开发者只需要掌握一些基本语法,久而久之的学习,绝大多数人都可以使用Java语言轻易地进行开发程序。本文将以电脑为基础,采用Java语言来编写一款叫做“愤怒的小鸟”的游戏。

2.2 开发工具 Eclipse是一个将源代码的开放、基于Java语言的具有可扩展性的编程开发平台。就其本身而言,它仅仅只有一个框架与一组服务,将其通过插件组件来构建成一个开发环境。比较需要注意的是,Eclipse 还附带着一个标准的插件集,插件集中包含了各种开发工具,比如用于Java语言开发的Java开发工具(Java Development Kit,JDK)。Eclipse是著名的跨平台开发环境和自由集成开发环境的组合。它最初主要是用于Java语言的开发,在Eclipse中通过安装不同的插件,使得Eclipse具有可以支持不同的计算机语言的特性,比如C++语言和Python语言等开发语言。Eclipse简单来说,它本身仅仅只是一个框架平台,但是各种各样插件的支持使得Eclipse具有其他功能死板IDE软件所难以拥有的方便灵动性,这一特性让许多软件开发公司都将以Eclipse作为基本框架来开发属于自己的IDE。

省略

2.3 JDK介绍 JDK是Java语言的软件开发工具包(Java Development Kit),它在java语言开发中占有核心的地位,它包括Java的运行环境,java的基本工具和java的基础库等。

JDK包含的基本组件包括: javac 编译器:javac编译器自动读取由java语言编写而成的类和接口的定义等,并将它们编译成字节代码(class文件)。 jar打包工具:将相关的类文件整合为一个文件 javadoc文档生成器:从源码中将注释提取为一个文档 jdb debugger:调试工具 jav:可将编译后的java程序(.class后缀的程序)运行 appletviewer:可在脱机环境的情况下运行applet。 Javah:创建一个可以被Java程序所调用的C过程的头文件。 Javap:一种进行反编译的工具。 Jconsole: Java中可以对系统进行监控和调试的工具。如下图2-2所示: 在这里插入图片描述

图2-2 JDK基本组成 2.4 Java Awt介绍 AWT(Abstract Window Toolkit),中文翻译是:抽象窗口工具包,该包提供了一个GUI交互的接口,Java提供了用于创建和配置Java GUI的基本工具。AWT中图形操作函数与系统中图形功能之间提供了一对一的关系,称为peeres,当开发者使用AWT编写图形用户界面时,实际上是使用本地操作系统所提供的图形库。由于各种操作系统的风格和功能不同,所以提供的图形库不一样,在一个平台上可能存在的功能反而在另一个平台不存在。为了实现“写一次(编写一次,任意平台都可以运行”)Java语言的概念,AWT必须以牺牲独立平台功能为代价,由各种系统提供的AWT图形功能的交集来作为awt图形功能的可用功能。 如下图为awt的几种基本布局: 在这里插入图片描述

图2-3 awt的几种基本布局

省略

2.5 Java Swing 介绍 Java Swing 作为一个GUI工具包,是专门为Java设计与使用的,也是Java基础类的一部分,其中包含的一些组件如文本框、分割窗格、表格、按钮等

Java Swing可以提供的屏幕显示元素,在某种程度上要比Java Awt提供的要好的多。由于Java Swing使用纯Java语言编写的,在这一点上不与AWT相同,所以Java Swing拥有与Java语言一样的可扩展性,可以在多种平台上使用,并且Java Swing也是JFC的一部分。Java Swing可以对面板和主题进行变更(操作系统中存在着默认的主题,不同操作系统的主题不尽相同),这并不是真正的去使用这种操作系统的设备,只是在一定程度上在表面上模仿。这些特殊的功能导致程序猿可以可以使用Java的任何面板,并且不需要操作系统的限制。如下图2-4为Java swing 基本组成: 在这里插入图片描述

图2-4 Java swing 基本组成

省略

2.6 Java语言开发平台搭建 省略

3系统需求分析 3.1 可行性分析 省略

3.1.1 技术可行性 省略

3.1.2 经济可行性 省略

3.1.3 操作可行性 省略

3.1.4 发展可行性 省略

3.2 性能需求分析 省略

3.3 功能需求分析 省略

在愤怒的小鸟程序中,主要实现以下功能 游戏玩法功能: (1) 能实现发射器创建、发射角度、发射力度等 (2) 可以实现小鸟飞行功能,包括小鸟飞行抛物线、小鸟飞行悬停 (3) 实现游戏中猪的移动功能,包括猪的根据级别不同改变移动速度、猪在哪里移动 (4) 碰撞功能:实现小鸟与障碍的碰撞、小鸟与猪的碰撞、鸡蛋与障碍物的碰撞、鸡蛋与猪的碰撞、猪与障碍物的碰撞 页面管理功能:实现各个页面功能,包括主界面、载入游戏界面、控制帮助界面、跳转界面功能等 难度、级别功能:实现游戏难度功能,难度不同猪的移动速度不同,实现级别功能,级别不同地图难易程度也不同 实体类管理功能:创建游戏中各种实体类,包括鸟的种类、猪、障碍物、草地等

玩家管理功能和备份功能:实现玩家信息管理以及游戏信息保存的功能 如下图3-1所示: 在这里插入图片描述

图3-1 总体功能需求图

3.4 系统UML分析 UML是在面向对象的方法Booch,TMO,OOSE等基础上开发的方法,以及根据许多其他方法和材料的基础从而衍变出来的。 UML符号是为各种图形符号表示,消除混淆、冗余符号或很少使用以及容易导致的图形符号,同时添加一些新的图形符号。

UML是统一建模语言的缩写,也称为统一建模语言。它是用于可视化建模的一种语言。 UML是开发人员用于建模事物的客观标记,同时也为开发人员了解什么样的系统工作以及整个过程做出了准备工作。 现在我们在这个基础上对愤怒的小鸟进行建模分析,UML用例图如下图3-2所示: 在这里插入图片描述

图3-2 UML界面用例图 在这里插入图片描述

图3-3 UML游戏操作用例图 3.5界面需求分析 省略

4 系统设计 4.1系统流程设计 在设计开发基于Java语言的愤怒的小鸟的时候,必须先进行需求分析,这样才可以对系统总体进行概括性规划,从而进行系统功能模块的设计、测试、基于Java语言的愤怒的小鸟的总体设计流程图, 如下图4-1所示: 在这里插入图片描述

图4-1 总体流程设计图

该程序在游戏概念和属性中使用面向对象的模型。 运行程序后,用户可以选择运行选项菜单,屏幕刷新屏幕重新设计一定频率,实时反映游戏状态。

如下图3-2显示了游戏控制的流程图。 首先,当游戏运行时会成为测试的关键角色,同时响应方向。 这是对鸟类在屏幕的主要方向的响应,同时检测释放的鸟类的强度。 如果你摧毁对象超过一个固定的分数,导致游戏结束。 当物体被鸟类摧毁时,根据物体的破坏得到不同的分数。

同时,还有其他检测键,主要用于检测菜单键。 菜单按钮包括检测输出和返回参数。 当游戏检测到退出按钮时,游戏结束。 当检测到游戏的返回键时,游戏将返回到主屏幕。 在这里插入图片描述

图4-2 游戏控制流程图 4.2 系统架构设计 系统架构设计模型采用MVC经典建模模型,使用面向对象设计思想来帮助实现。 MVC全名模型视图控制器(Model-View-Controller),M、V、C分别是指逻辑模型、指视图模型、控制器。MVC已经开发成了用于图形用户界面中常规映射输入,处理和输出逻辑功能的独特结构。

我们参考的模型是一个对应于多个逻辑模型的视图模型,我们使用这个模型将视图模型的代码和逻辑模型的代码分开,以便我们可以以不同的形式实现相同的程序,然后控制台的控制着两者同时工作,其中一个变化, 另一个应该同时更新。

用户对此模型的最大优势是根据自己的方式选择更加适合自己的方式来浏览数据。 对于那些开发人员来说,这种模式的最大优点就是分离界面和应用程序的逻辑层,这个界面和程序员的设计者可以在格子的领域工作,而不会互相干扰。

Model(模型): GameModel():实现游戏主要功能,包括碰撞、发射、得分。 Level():实现游戏难度、地图功能。 LevelNumber():存储地图功能 ListChangedEvent()、ListListener():碰撞功能的监听 Player():玩家备份功能 Entity()、Bird()、Block()、Egg()、Enemy()、EntityThread()、Grass()、HummingBird()、Pig()、Pigeon()、Sparrow() :定义游戏中各种模型的实体类。 在这里插入图片描述

图4-3 游戏实体类图

View(视图): GameView():实现游戏中发射皮筋功能 GameViewMenu():实现背景界面及标题功 MenuDifficultyView():实现难度选择界面 MenuHomeView():实现主界面 MenuLevelView():实现级别选择界面 MenuLoadView():实现确认及删除界面 MenuNewView():实现增加玩家信息界面 MenuOptionsView():实现控制帮助 Controller(控制器): GameController():实现监听事件(键盘,鼠标,更改实体列表) MenuController():实现菜单控制界面跳转等功能 在这里插入图片描述

图4-4 游戏总体类图

5 详细设计 5.1 主界面实现 (见图5-1)当玩家开始游戏时,共有4个选择:开始一个新游戏,加载一个保存的游戏,了解游戏控制或离开游戏。 如果启动新游戏,则需要输入其名称,以创建备份。 如果决定加载保存的游戏,玩家从已经备份的名称中进行选择。如果点击控制帮助选项,玩家将会看到游戏控制的帮助内容,以便更好的了解游戏、更容易上手。如果选择退出游戏,则游戏会立刻关闭。 在这里插入图片描述

图5-1 主界面

部分代码以及相应的页面布局:

public class MenuHomeView extends GameViewMenu { private JButton newButton,loadButton,optionsButton,exitButton; public MenuHomeView() { newButton = new JButton("新游戏"); newButton.setSize(250,40); newButton.setLocation(frameWidth/2-115, 150); loadButton = new JButton("载入游戏"); loadButton.setSize(250,40); loadButton.setLocation(frameWidth/2-115, 225); optionsButton = new JButton("控制帮助"); optionsButton.setSize(250,40); optionsButton.setLocation(frameWidth/2-115, 300); exitButton = new JButton("退出游戏"); exitButton.setSize(250,40); exitButton.setLocation(frameWidth/2-115, 375); backButton.setVisible(false); this.add(newButton,new Integer(1)); this.add(loadButton,new Integer(1)); this.add(optionsButton,new Integer(1)); this.add(exitButton,new Integer(1)); } public JButton getNewButton() { return newButton; } public JButton getLoadButton() { return loadButton; } public JButton getOptionsButton() { return optionsButton; } public JButton getExitButton() { return exitButton; }}

5.2 游戏玩法实现 (见图5-2及5-3)选择一个级别后游戏开始。 首先玩家必须选择弹出一只鸟(游戏中总共有三只鸟供玩家使用),根据鸟的特点,玩家可以决定在飞行期间是否停止鸟,同时鸟也可以扔一个鸟蛋(鸟蛋的数量取决于不同的鸟的种类)。 玩家可以使用鸟蛋碰撞或直接鸟本身碰撞消灭阻碍物。 最后,玩家还可以借助鸡蛋或鸟类本身杀死绿猪,有时可能需要摧毁阻碍物才能到达消灭某些猪的目的。 在这里插入图片描述

图5-2游戏玩法图

图5-3为刚进入游戏时的界面,右上角显示还剩下几种鸟可以使用以及剩余鸟的数量,金色的蛋表示鸟剩余蛋的数量 在这里插入图片描述

图5-3 游戏内容图1

在这里插入图片描述

图5-4 游戏内容图2 图5-4表示鸟在飞行过程中的状态,飞行中可以按S键将小鸟悬停在空中,然后可以按space键释放鸟蛋

部分代码(创建面板以及地图的代码)以及相应的页面布局:

public GameView(ArrayList entities) { setFocusable(true); setDoubleBuffered(true); ImageIcon img1 = new ImageIcon(slingShotName1); slingShotImg1 = img1.getImage(); ImageIcon img2 = new ImageIcon(slingShotName2); slingShotImg2 = img2.getImage(); this.entities = entities; } public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D)g; g2d.drawImage(map.getImage(), 0, 0,frameWidth,frameHeight, this); g2d.drawImage(slingShotImg2, 100,412, this); int k = 0; for(int i = entities.size()-1; i >=0;i--) { Entity e = entities.get(i); if(e instanceof Bird && e != currentBird) { g2d.drawImage(e.getImage(), frameWidth-100-k*15, 100,e.getImageWidth(),e.getImageHeight(), this); k++; } if(e == currentBird) { Egg egg = new Egg(0,0,28,30); for (int j = 0; j if (!(e instanceof Bird)) { g2d.drawImage(e.getImage(), (int) e.getPosition().getX(), (int) e.getPosition().getY(), this); } if(e== currentBird ) { g2d.setStroke(new BasicStroke(7.0f)); g2d.setColor(new Color(54, 28, 13)); //drawLine()划线的方法 if(!currentBird.isFlying()) g2d.drawLine(135,442, (int)e.getPosition().getX()+e.getImageWidth()/2, (int)e.getPosition().getY()+e.getImageHeight()/2); g2d.drawImage(e.getImage(), (int) e.getPosition().getX(), (int) e.getPosition().getY(),e.getImageWidth(),e.getImageHeight(), this); if(!currentBird.isFlying()) g2d.drawLine(120,442, (int)e.getPosition().getX()+e.getImageWidth()/2, (int)e.getPosition().getY()+e.getImageHeight()/2); } g2d.setStroke(new BasicStroke(7.0f)); g2d.setColor(new Color(54, 28, 13)); if(currentBird.isFlying()) g2d.drawLine(135,442,120,442); g2d.setStroke(new BasicStroke(1.0f)); g2d.setColor(new Color(0, 0, 0)); } g2d.drawImage(slingShotImg1, 100, 412, this); g.drawString("Highest Score : " + currentHighestScore, 10, 15); g.drawString("Flying time left : " + currentBird.getFlyingTimeLeft(), 10, 30); Toolkit.getDefaultToolkit().sync(); g.dispose(); } public void setEntityList(ArrayList entities) { this.entities = entities; } public Level getMap() { return map; } public void setMap(Level map) { this.map = map; } public void setCurrentHighestScore(int highestScore) { this.currentHighestScore = highestScore; } @Override public void listChanged(ListChangedEvent event) { entities = event.getEntityList(); currentBird = event.getCurrentBird(); repaint(); } }

5.3 面板管理功能实现 菜单管理通过6个不同的面板进行如图5-5所示: MenuHomeView:游戏启动时的主页 MenuNewView:创建新部分的页面 MenuLoadView:加载游戏页面 MenuControlsView:游戏控制信息页面 MenuDifficultyView:游戏选择页面 MenuLevelView:级别选择页面 在这里插入图片描述

图5-5 管理菜单图 每个面板的实现一个特定的功能,但是它们都继承自GameViewMenu(abstract)类,该类具有所有面板共同的功能,例如Menu背景。 GameViewMenu继承自JLayeredPane类,它允许向放置在面板上的元素分配不同的深度,这使得我们将按钮按照自己的意愿放置在在已经创建好背景上。菜单中的导航按钮通过创建鼠标的各种监听来完成,对于返回按钮的设置,使用 “转义”键通过键盘设置了额外的控制(相当于使用按钮“返回”)。 然后,检测窗口和窗口中的先前显示的面板。 在选择面板的时候,可以从新的游戏或者加载游戏等进行面板的访问。接下来的所示一系列图为各个面板: 创建备份面板:在此处可以输入玩家的用户名,点击确认后可以保存玩家信息 在这里插入图片描述

图5-6创建备份面板 载入游戏面板:在此处玩家可以选择之前的存档,然后接着上次游戏内容继续进行游戏 在这里插入图片描述

图5-7 载入游戏面板

控制游戏面板:此处是整个游戏需要学会的操作方式 在这里插入图片描述

图5-8 控制游戏面板

难度选择面板:此处可以对游戏进行难度选择,选择不同的难度,小猪的移动各不相同,随着难度的提高,小猪的移动速度越来越快 在这里插入图片描述

图5-9 难度选择面板

级别选择面板:此处选择不同的级别,导致进入的关卡不同,随着关卡级别的提高,关卡的地形难度会越来越高 在这里插入图片描述

图5-10 级别选择面板 5.4 等级、级别管理功能实现 创建一个文本文件来管理等级,所有的游戏等级都依赖于这个文本,以下内容为等级管理功能的详细解释: 此功能可用于实现某个级别的鸟类、阻碍物以及猪在这个环境中的位置、鸟类列表列在文件的顶部。

鸟类的等级与其出现顺序相同。在行中的字符串和不同类型的鸟的名字对等,以创建相应的鸟,并将其添加到实体的ArrayList。当程序阅读文本时,遇到“地图(Map)”一词时,程序便可以从该文本中知道可用于该级别的鸟类列表是完整的,并且文件同时也包含表示级别的地图。这些是相同大小的文本行,包含将在二维数组中实现的不同字符(文本文件的每一行对应于2D数组中的一行)。每个元素都包含在具有26 * 26像素的相应图像中,并且在此图像对应的尺寸为1200 * 600像素的窗口中,该表的一行包含47个元素,一列包含22.每个字符对应于不同的元素装饰: “0”表示地图上没有任何内容。 “1”表示地图上现在有一个草块。 “2”表示地图上现在有一块阻碍物。 “3”表示敌方猪的起始位置。

图5-11所示的为游戏的基本地图: 在这里插入图片描述

图5-11 游戏地图

相应的实体(猪,草块或阻碍物)是通过特定元素(“猪”,“草块”或“阻碍物”)创建的。 该实体通过构造函数创建,取其位置x(使用表的列索引和与实体对应的图像的大小计算)及其位置y(以l为单位计算)使用数组的行索引和 与实体对应的图像的大小)。 部分代码以及相应的页面布局:

public class Level { private String backgroundImagePath = "res/images/background.png"; private Image image; private int tabMap[][]; private int tabMapSizeX = 47; private int tabMapSizeY = 22; private int blockSize = 26; private String grassImagePath = "res/images/grass.png"; private Image grass; private String blockImagePath = "res/images/block.png"; private Image block; private boolean isLoaded; private ArrayList entities; private int pigSpeed; public Level(String fileMapPath, String difficulty) { ImageIcon ii = new ImageIcon(backgroundImagePath); image = ii.getImage(); ImageIcon gr = new ImageIcon(grassImagePath); grass = gr.getImage(); ImageIcon bl = new ImageIcon(blockImagePath); block = bl.getImage(); if (difficulty == "easy") pigSpeed = 0; if (difficulty == "medium") pigSpeed = 1; if (difficulty == "hard") pigSpeed = 2; if (difficulty == "extreme") pigSpeed = 3; entities = new ArrayList(); try { FileInputStream ips = new FileInputStream(fileMapPath); isLoaded = true; InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; line = br.readLine(); while (!line.equals("Map")) { if (line.equals("Pigeon")){ entities.add(new Pigeon()); } if (line.equals("Humming Bird")){ entities.add(new HummingBird()); } if (line.equals("Sparrow")){ entities.add(new Sparrow()); } line = br.readLine(); } tabMap = new int[tabMapSizeY][tabMapSizeX]; for (int i = 0; i char car = line.charAt(j); String st = String.valueOf(car); tabMap[i][j] = Integer.parseInt(st); if (tabMap[i][j] == 3) entities.add(new Pig(j * blockSize, i * blockSize, pigSpeed)); if (tabMap[i][j] == 2) entities.add(new Block(j * blockSize, i * blockSize, blockSize, blockSize)); if (tabMap[i][j] == 1) entities.add(new Grass(j * blockSize, i * blockSize, blockSize, blockSize)); } } } catch (Exception e) { isLoaded = false; } }

5.5 碰撞管理功能实现 碰撞管理和与其相关的事件在updateEntity()函数中执行。 创建的每个实体都具有hitBox,也就是说,每个图形对象都被一个碰撞矩形包围。 然后,按照实体的处理,通过测试其hitBox是否与其他人的hitBox相交的方式,来进行碰撞的各种处理。

如果一个元素与另一个元素的冲突导致删除两个对象之一,则程序会将一个或多个元素添加到实体列表(toRemove()调用)。 反过来,这在函数结束时遍历,以执行GameModel中实体的删除。 这使得可以在算法中删除相同级别的所有相关实体,并确保在删除它们之前已经执行了实体上的所有进程。 各种管理冲突如下: 鸡蛋碰撞: •与绿猪:当检测到碰撞时,绿猪和当前的鸡蛋被添加到要删除的实体列表中。 •蛋与阻碍物:在要删除的实体列表中涉及到阻碍物和相关蛋的处理。 •与草块:碰撞导致当前的蛋被地添加到toRemove()列表。 草地是坚不可摧的。 猪碰撞: •与阻碍物: 管理碰撞:碰撞的管理是不同的,在这里,因为在阻碍物与猪的碰撞矩形上没有完成。 实际上,猪可以在阻碍物上自由移动,但是当它们从侧面撞击一块阻碍物时,碰撞必须导致猪的方向移动。 必须能够测试块的hitBox的哪个边缘,猪的hitBox相交。 事件:当猪碰到一块阻碍物的左边缘或右边缘时,猪会改变运动方向(左侧或右侧); 当猪不与其中一块阻碍物(即猪的任何阻碍物上移动)的一个上边缘碰撞时,猪坠落,直到它碰到其中一个块阻碍物或草,则猪会进行反向移动,而块的下边缘猪不会进行改变方向。 猪:当两头猪相遇时,这两头猪就会改变方向。 鸟类碰撞: 阻碍物:当一只鸟与一块阻碍物碰撞时,这两个实体被添加到删除列表中。可以再次证明在功能结束时选择对缺失的处理。只有当鸟类被第一个块的碰撞检测直接攻击时,其他将会崩溃的块将不会被测试。

与猪一起:鸟和猪的碰撞导致在删除列表中添加这两个实体。 在theupdateEntity()函数中,可以看到位置所在的实体(左,右或底部)。 相关要素被添加到删除列表中。

部分代码以及相应的页面布局:

if(entity == currentBird) { Bird bird = (Bird) entity; if(!bird.isVisible()) toRemove.add(bird); Rectangle hitBoxBird = bird.getHitBox(); for(Entity entity2 : entities) { if(entity2 instanceof Block) { Block block = (Block) entity2; Rectangle hitBoxBlock = entity2.getHitBox(); if(hitBoxBird.intersects(hitBoxBlock)) { toRemove.add(block); toRemove.add(bird); } } } for(Entity entity2 : entities) { if (entity2 instanceof Pig) { Pig pig = (Pig) entity2; Rectangle hitBoxPig = pig.getHitBox(); if(hitBoxBird.intersects(hitBoxPig)) { toRemove.add(pig); toRemove.add(bird); boolean win = true; for (Entity entity3 : entities) { if (entity3 instanceof Pig && !toRemove.contains(entity3)) { win = false; break; } } if (win) { for (Entity entity3 : entities) { if (entity3 instanceof Bird) ++score; } win(); } } } } for (Entity entity2 : entities) { if (entity2 instanceof Bird && !toRemove.contains(entity2)) { currentBird = (Bird) entity2; break; } } } } for(Entity entity : toRemove) entities.remove(entity); for(Entity entity4 : entities){ if(entity4 instanceof Bird) birdTest++; if(entity4 instanceof Pig) pigTest++; if(entity4 instanceof Egg) { eggTest++; } } if(birdTest==0 && eggTest==0 && pigTest!=0){ angryView.repaint(); lose(); } }

5.6 鸟类管理功能实现 所有鸟类都继承了抽象类Bird。 创建当前的鸟:当前的鸟,位于弹弓上的鸟是通过浏览实体列表顺序找到的第一只鸟。 要将鸟类定义为当前目录,扫描实体列表,当检测到Bird的第一个实例时,将在该实例上放置currentBird指针。

鸟的状态:当鸟儿飞行时,他们有两个阶段:第一个准备飞行和一秒钟的飞行。 准备不良:鸟类位于抛石机上,玩家有可能试着对弹弓进行拉伸,以确定初始速度和进行鸟投掷的初始角度。 要做到这一点,玩家必须点击弹弓上的鸟,然后拖动它,同时按住鼠标按钮。 当释放鼠标按钮时,鸟类切换到飞行模式(isFlying布尔值设置为true)。

飞行阶段:飞行中的鸟类受到加速度公式,Y中的加速度为9.81(模拟重力)。鸟的位置被修改为时间,角度初始速度和施加的初始速度的函数。 在飞行中,玩家有可能释放鸡蛋(在分配的鸡蛋数量的限制内:eggLeft)。玩家也可以将鸟类允许(鸽子或蜂鸟)悬停。目前的鸟的死亡:当目前的鸟死亡(与块碰撞,与猪碰撞,在窗口中消失或飞行时间用完),鸟被添加到updateEntity函数的删除列表中删除。然后,再次返回列表,以确定新的当前鸟。

部分代码以及相应的页面布局:

public abstract class Bird extends Entity { protected short flyingTime; protected int eggLeft; protected ArrayList eggs; protected boolean isFlying; protected boolean isMoving; private double time; protected Dimension frameSize; private double accelX; private double accelY; protected int startLocationX; protected int startLocationY; private long lastTime; private long flyingTimeLeft; public Bird(int width, int height) { super(100,440,width,height); isMoving = false; time = 0.1; accelX = 0; startLocationX = 100; startLocationY = 440; accelY = 9.81; flyingTimeLeft = 10000; } public int getEggLeft() { return eggLeft; } public void setEggLeft(int i) { this.eggLeft = i; } public int getStartLocationX() { return startLocationX; } public int getStartLocationY() { return startLocationY; } public abstract void hovering(); public boolean isFlying() { return isFlying; } public void move() { if(isFlying){ if(isMoving){ hitBox.x = (int) Math.round(speed*Math.cos(angle)*time+0.5*accelX*time*time+startLocationX); hitBox.y = (int) Math.round(0.5*accelY*time*time-Math.sin(angle)*speed*time+startLocationY); time+=0.1; } long currentTime = System.currentTimeMillis(); flyingTimeLeft -= (currentTime - lastTime); lastTime = currentTime; } if (hitBox.y > (int) frameSize.getHeight() || hitBox.x > (int) frameSize.getWidth() ||flyingTimeLeft accelX+=0.1; } public void moveLeft() { accelX-=0.1; } public long getFlyingTimeLeft() { return flyingTimeLeft; } }

5.7 胜利管理功能实现 每个级别都有一些敌人(猪)。 当所有级别的猪都被杀死(从实体列表中删除)时,游戏将获胜。 胜利测试在updateEntity()函数中执行。 当浏览实体列表时,我们更新猪的行为,或者如果实体列表不再包含任何猪实例,则游戏级别完成。 一旦达到这个级别,该程序将进入WIN()函数,这将允许执行胜利的所有条件。 与胜利管理相同的方式,失败事件在upledateEntity()函数中触发,但在这种情况下,事件不是在实体中的鸟的实例中完成的。 当列表中没有更多的鸟类时,将调用lost()函数。 在这种情况下,首先处理猪是重要的,所以当没有更多的鸟或猪时,不会调用lost()函数(对于win()函数的调用将优先进行)。

在这里插入图片描述

图5-12 胜利后的提示信息

在这里插入图片描述

图5-13 失败后的提示信息

部分代码以及相应的页面布局:

public void win() { javax.swing.JOptionPane.showMessageDialog(null, "祝贺你胜利 ,你的分数是: " + score+"."); currentPlayer.finished(currentLevel, difficulty, score); Level lvl = new Level("res/maps/lvl0" + (currentLevel+1) + ".txt",difficulty); if (lvl.isLoaded()) { angryView.setMap(lvl); this.setMap(lvl); this.setCurrentLevel(currentLevel+1); } else { javax.swing.JOptionPane.showMessageDialog(null, "没有此难度的地图!"); } } public void lose() { javax.swing.JOptionPane.showMessageDialog(null, "游戏结束,再试一次?"); Level lvl = new Level("res/maps/lvl0" + (currentLevel) + ".txt",difficulty); if (lvl.isLoaded()) { angryView.setMap(lvl); this.setMap(lvl); } }

5.8 玩家管理和备份管理功能实现 这个功能目的是为了保存玩家的进度,让他恢复之前所成功进行的游戏。 因此,设置了一个“配置文件”系统:保存文件夹包含每个视图页面的备份文件,其中包含他的名字。 该文件包含对应于游戏的对象的序列化。 Player类专门为此而设计。 游戏可以选择从先前保存的配置文件中选择,或者创建一个新的配置文件。

玩家相关数据:对于每个玩家,希望存储他的名字,他成功的水平以及获得的分数。 因此,Player类包含一个名称的String字段和每个难度和级别的两个ArrayLists,一个包含相应文件的解锁级别,另一个包含后续级别的分数。

序列化:为了在双方之间保存数据,有必要序列化Player类。为此,最简单的方法是使用Java提供的ObjectOutputStream和ObjectInputStream。我们不需要担心对象的序列化实现的细节,或者从文件中读取的细节。这种技术防止备份文件被我们的其他程序读取,但这并不是这个项目的问题。另一个问题可能是游戏的名称:在游戏中,备份文件被命名为“nom.save”,但是在创建新配置文件时输入的名称没有进行验证。 得分:只有最高的分数保留给玩家和给定的水平。当玩家完成一个级别时,Player类的finished()方法被调用,其中级别和score作为参数。完成后检查,看看给定的分数是否是一个新的记录 在这里插入图片描述

图5-14 已经存在的玩家信息

部分代码以及相应的页面布局:

public Player(String name) { this.name = name; easy = new ArrayList(); medium = new ArrayList(); hard = new ArrayList(); extreme = new ArrayList(); easyScores = new ArrayList(); mediumScores = new ArrayList(); hardScores = new ArrayList(); extremeScores = new ArrayList(); highestEasyScores = new ArrayList(); highestMediumScores = new ArrayList(); highestHardScores = new ArrayList(); highestExtremeScores = new ArrayList(); for (int i = 0; i try { FileInputStream fichier = new FileInputStream("save/" + name + ".save"); ObjectInputStream ois = new ObjectInputStream(fichier); Player player = (Player) ois.readObject(); return player; } catch (java.io.IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public void save() { try { File file = new File("save/" + name + ".save"); file.delete(); file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(this); oos.flush(); oos.close(); } catch (java.io.IOException e) { e.printStackTrace(); } } public String toString() { return name; } public boolean isFinished(int level, String difficulty) { if (difficulty.equals("easy")) { return easy.contains(level); } else if (difficulty.equals("normal")) { return medium.contains(level); } else if (difficulty.equals("hard")){ return hard.contains(level); } else if (difficulty.equals("extreme")){ return extreme.contains(level); } return false; } public void finished(int level, String difficulty, int score) { if (difficulty.equals("easy")) { if (!(easy.contains(level))) easy.add(level); easyScores.set(level-1, score); if (score > highestEasyScores.get(level-1)) highestEasyScores.set(level-1, score); } else if (difficulty.equals("medium")) { if (!(medium.contains(level))) medium.add(level); mediumScores.set(level-1, score); if (score > highestMediumScores.get(level-1)) highestMediumScores.set(level-1, score); } else if (difficulty.equals("hard")) { if ( !(hard.contains(level))) hard.add(level); hardScores.set(level-1, score); if (score > highestHardScores.get(level-1)) highestHardScores.set(level-1, score); } else if (difficulty.equals("extreme")) { if (!(extreme.contains(level))) extreme.add(level); extremeScores.set(level-1, score); if (score > highestExtremeScores.get(level-1)) highestExtremeScores.set(level-1, score); } save(); } public String getName() { return name; }

6 系统测试 6.1系统测试简介 省略

图6-1所示为基本系统测试方案: 在这里插入图片描述

图6-1 系统测试方案

6.2 系统测试方法 测试方法系统可以分为静态测试和动态测试两种,测试分为静态检测的计算机以及黑盒测试和白盒测试的动态测试。黑盒测试,也称为功能测试,则测试程序模块为黑盒,即不管内部配置和程序的处理,只对界面操作来测试程序。白盒测试,程序为透明白盒,即了解内部结构和详细的处理步骤,对程序的内部结构进行测试。即设计每个测试所需的逻辑路径,并检查每个循环和每个分支。另外在设计测试用例时,应该根据软件测试的原理,选择那些发现测试数据错误的可能性很大的输入数据。

6.3 本系统测试 6.3.1 测试用例设计 如下表1位测试用例设计表 表1 测试用例设计表 在这里插入图片描述 在这里插入图片描述

6.3.2 测试方法和结论 主要测试系统是当前系统的测试方法,系统要求的总体规格是基于黑盒测试类别。 测试系统是基于计算机系统的要素、硬件项目、外围设备、一些支持软件,数据和人员的组合以及应用程序健康管理正确的功能,调试和其他测试的整体的软件系统。 测试系统的不同功能模块后,结果表明该软件工作良好,达到系统设计目标和功能要求达到预期目标

结论 省略

参考文献 [1] 基于Box2D物理引擎的刚体运动和碰撞模拟[J]. 奚焱. 电脑编程技 巧与 维护. 2011(24) [2] 基于物理引擎三维物理仿真实验的实现方法[J]. 田超,张文俊,张小凤,刘东平. 微型电脑应用. 2010(02) [3] 虚拟现实环境中的物理模拟及物理引擎应用的研究[J].陈定方. 湖北工业大学学报. 2008(02) [4] 游戏音效在物理引擎中的运用[J]. 魏婷,郑豪. 福建电脑. 2008(01) [5] 探析JAVA Swing工具包在图形用户界面设计中的应用[J]. 苏碧霞. 信息与电脑(理论版). 2013(05) [6] Swing可视化组件多线程操作机制研究[J]. 胡家芬. 电脑知识与技术. 2012(31) [7] 一种Swing组件的动态国际化解决方案[J]. 肖荣. 软件导刊. 2009(10) [8] 使用Java Swing组件进行事件处理方法的分析与比较[J]. 张海越,范曦. 软件导刊. 2013(06) [9] Beginning Java ObjectsJacquie Barker 2005- [10] A portable AWT/Swing architecture for Java game development Yi‐ HsienWang Softw: Pract. Exper. 2007(07) [11] Objective viewpoint: Java AWT layout management 101 George Crawford Crossroads 1998(01)

致  谢 省略

附录 外文原文 省略

中文原文 省略

5、资源下载

本项目源码及完整论文如下,有需要的朋友可以点击进行下载。如果链接失效可点击下方卡片扫码自助下载。

序号毕业设计全套资源(点击下载)本项目源码基于java+Java awt+swing的愤怒的小鸟游戏设计与实现(源码+文档)_AWT_Jbox2D_愤怒的小鸟游戏.zip


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有