版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
绪论1.1背景及意义在所有的游戏类型中,飞行射击游戏可以说是最古老,也是最深入人心的一种游戏。在飞行射击游戏中,玩家往往操作着一架普通飞机,在漫天密集的弹幕中惊险地消灭敌人,充当世界的救世主。或者以宇宙作为背景,驾驶高科技战机在太空中探险。世界上第一款街机游戏就是飞行射击游戏《太空大战》,它是由麻省理工学院学生史蒂夫拉塞尔在1961年设计出来,是真正运行在电脑上的第一款交互游戏。到70年代,FC(红白机)时代,《小蜜蜂》和《沙陀曼蛇》的出现,前者画面上得到显著的提示,后者首次引入吃能量球,通过积攒来升级飞机属性和枪械导弹。90年代初,《雷电》和《彩京》系列相继出世,把“躲子弹,打飞机”推向一个极端的高潮。两者凭借多样战机选择,武器升级设定和高难度弹幕吸引了大多数游戏玩家,很快成为风靡全球的街机游戏。再到后来的《东方project》系列,从弹幕、关卡设计、剧情、画面、音乐等多方面革新,时至如今《东方project》的同人作品还在涌现。 飞行射击游戏是集娱乐、即时操作、锻炼反应力的一类游戏,游戏面对的主要人群是青少年或者需要释放压力的职工。玩法丰富,面对飞向自己战机的敌人和炮火,不禁会让人感到紧张刺激,玩家通过操作躲避子弹并且击败敌机从而释放压力。游戏过程中,随着玩家获得更多经验,解锁不同的战机和子弹,增加游戏可玩性,随着关卡难度的逐渐提升,可以激发玩家的好胜心,获得更好的游戏体验。所以综上所述,基于Unity3D引擎开发一款竖版飞行射击游戏具有重要意义。1.2课题研究现状 随着时代发展,游戏作为一种娱乐方式,进入我们的生活,帮助我们释放压力,丰富我们的休闲时间。而如今5G网络在普及,VR、AR技术在逐渐成熟,游戏行业作为这几个方面都能获益的一方,不久的将来一定会有一次重大的变革。 如今国内比较流行的游戏引擎有Unity3D、虚幻(Unreal)、白鹭(Egret)、Cocos2D等。虚幻引擎注重于数据生成和编程方面,在做FPS和TPS时有完善、集成和统一的工具链。白鹭引擎是一个基于HTML5技术的游戏引擎,具有高效的渲染模块,完善的配套工具。Cocos2D是一个免费开源的游戏引擎,注重于移动端游戏开发。相对于上面几款开发引擎而言,Unity3D引擎支持多种格式的导入,给开发者省去不必要的麻烦。拥有3A级图像渲染引擎,简单易用,灵活高效。支持NVIDIAPhysX物理引擎,支持Java,C#,Boo三种脚本语音等优点。在对于入门者而言,Unity官方能提供个人免费版支持学习,还有在Unity社区里面有很多官方优秀教程。而对于专业开发人员,Unity商店可以提供各色各样的插件,大大减少了开发者的工作量。在游戏发布方面,Unity3D引擎支持多平台发布。对于使用者,Unity3D能满足大部分的需求以及提供足够的便利性。也正是因为如此,该引擎在功能游戏引擎市场上占据了45%的市场份额,具有良好的发展前景。因此熟练掌握和理解和应用Unity3D引擎具有一定意义。1.3论文组织结构 论文从最初构思到分析实践,结合专业游戏开发资料,进行一个竖版飞行射击游戏的设计制作。主要具体介绍游戏的制作步骤,包括游戏的系统功能设计和主要代码的编写。论文分为六章,各章节安排如下: 第一章节:绪论,主要阐述了毕业设计制作的背景目的、课题研究现状以及毕业设计的大概介绍; 第二章节:大致介绍Unity3D和本文制作游戏所用到的开发工具; 第三章节:游戏需求分析和总体设计方案,规划开发方向; 第四章节:游戏详细设计和实现,细化各个模块并且实现; 第五章节:运行游戏并测试,封装打包; 第六章节:总结和对游戏今后的改进方向规划;
第二章开发工具和技术简介 这一章主要介绍游戏实现过程中Unity3D引擎的部分功能,以及对其他使用到的工具做一个简单的介绍。2.1Unity3D游戏引擎2.1.1软件介绍 Unity3D是由UnityTechnologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的综合型游戏开发工具,是一个全面整合的专业游戏引擎。支持Windows、Mac、Android、IOS、PS等共10余种平台,提供非常完美的跨平台系统,大大减少了开发者在平台移植上花费的不必要时间。 Unity的可视化模式为开发者提供直观的图形化程序接口,开发者可以用玩游戏的形式开发游戏。在众多视图窗口中最常见的有5个,分别是Scene、Game、Hierarchy、Project、Inspector。Scene窗口:摆放模型文件,编辑游戏界面。Game窗口:根据摄像机的拍摄,对Scene场景的游戏运行的播放。Hierarchy窗口:负责管理在游戏中使用的相关组件。Project窗口:工程文件窗口,存放放所有工程文件资源。Inspector窗口:显示所有选中对象的组件信息,可以进行编辑。 2.1.2物理引擎介绍 游戏设计都应该具有其物体特性的合理性,游戏才能给人一种真实的感觉。Unity的NVIDIAPhysX的物理引擎系统为开发人员提供了如刚体、碰撞器等游戏组件。在开发的过程中,渲染,光线,颜色的对比度,材质等一系列的组件给我们带来的是视觉上的逼真效果。而在操作上想要获得真实反馈效果则需要物理引擎系统,运用组件修改对象受到的重力,摩檫力,空气阻力等具有物理特性因素外力从而获得在碰撞等物理变化后如同现实世界发生的真实效果体验。 2.1.3GUI(图形用户界面)介绍 GUI是图像用户界面GraphicalUserInterface的缩写,Unity的内置GUI系统被称作UGUI,本文主要使用UGUI来制作界面的开发。UGUI中有大量的界面组件,开发者只需要创建实例,就可以在Scene窗口对其进行大小形状的调整,在Inspector窗口对选中组件进行进一步的细化设置,如锚点定位、交互反馈等。 2.1.4Unity的保存读取数据方式介绍 众多游戏中,玩家们致力于最高的分数、更强的装备和角色进阶的属性,允许玩家主动保存和加载成为了很多游戏必不可少的功能之一。Unity中比较常见的保存读取数据的方法有四种,分别是PlayerPerfs数据持久化方案、数据序列化与反序列化中的:二进制方法,JSON方法和XML方法。PlayerPerfs方法,通过构建一个键,对应的键名存储对应的数据,需要读取数据的时候只需要查找对应的键名就可以,适用于保存少量数据。是一种特殊的CaChingSystem缓存系统,可以在不同的场景之间,有效的保存一些简单的设置和变量。序列化就是把对象的状态或者各个属性转换为另一种格式的自动化过程。二进制方法方便能存储更多的数据,但这方法存储文件的可读性几乎为0,但却能保护数据防止别人篡改。JSON方法传输速度快,占用空间小,可读性比二进制要好。但仅支持简单类型,不支持集合。XML方法,存储文件重复信息多,占用空间大,解析XML文件需要花费较多的资源和时间。本文需要存储数据量较少,因此主要使用PlayerPerfs数据持久化方案来储存游戏数据。 2.1.5Unity常用生命周期函数介绍 Unity3D游戏引擎不像常规程序从Main函数入口运行,而是有一套自己的生命周期函数运行方式顺序,下面会从基本函数运行顺序介绍。 Awake():当一个对象初始实例化时Awake函数被调用; Start():在Awake函数调用后执行,Start函数只在脚本实例被启用时才会执行; Update():在对象运行之后,Update函数每一帧都会被调用; FixedUpdate():固定帧执行函数,跟Update一样,不过能通过设置FixedTime来决定调用次数; OnEnable():对象激活的情况下才能调用; OnDisable():对象未启用或未激活时调用; OnDestroy():销毁对象时调用; 2.2AdobePhotoshopCC2017AdobePhotoshop,简称“PS”,是由AdobeSystems开发和运行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。它是一个集图像扫描、编辑修改、图像制作、广告创意、图像合成、图像输入/输出、网页制作于一体的专业图形处理软件。本文主要使用它完成战机的受损图片制作。2.3C#语言介绍C#语言是微软公司推出的一种高级的、面向对象的语言,它简化了C++语言在类、命名空间、方法重载和异常处理方面的操作,它摒弃了C++的复炸性,更容易使用,更少出错。C#与Java类似,是一种语言,一种工具。在Unity引擎中,C#语言通过Mono的重新实现,让Unity能够使用C#来作为开发语言。2.4VisualStudio2017VisualStudio2017开发环境是微软公司自主推出的。VisualStudio2017集成开发环境是一种创新启动板,可用于编辑、调试并生成代码,然后发布应用。集成开发环境(IDE)是一个功能丰富的程序,可用于软件开发的许多方面。除了大多数IDE提供的标准编辑器和调试器之外,VisualStudio2017还包括编译器、代码完成工具、图形设计器和许多其他功能,以简化软件开发过程。
第三章游戏的需求分析及总体设计方案 编写游戏需求分析和总体设计方案,规划游戏开发方向。3.1竖版飞行射击游戏的需求分析3.1.1玩家需求分析 无论是哪一款游戏,不管它是以什么方式实现,或者出现在某一个领域之中,它最直接的使用者永远都是游戏玩家。而玩家最想要得到的需求就是与游戏有交互性和交互的简易性,即是玩家在做出每一步操作之后都希望能到明显的反馈信息和操作过程中的简便性。此外增加游戏的可玩性和挑战性等,都能更一步满足游戏玩家对玩下去游戏的欲望。3.1.2功能分析 本飞行射击游戏拥有两个核心,自己操作的战机和需要击败的敌机。围绕两个核心去做功能分析,添加功能,完善核心。 首先就战机核心来做分析。战机作为玩家操纵的个体,需要有一个固定的飞行区域,玩家不能把战机开出这个区域。作为个体应该拥有自己的属性,如血量、飞行速度、攻击力等等。单一不会变动的属性是不能吸引玩家的,所以需要添加一个战机升级系统,战机通过击败敌机后获得经验,然后使用经验去升级,升级之后战机的属性提升。战机在不同等级的时候有不同的子弹枪械和战机外貌。不同的枪械搭配各自对应的子弹,形成新的弹幕。在属性提升和拥有新弹幕之后便可以挑战更难的关卡,亦或去刷新以前的挑战记录。 其次就敌机核心来做分析。敌机作为飞行射击游戏的另外一个主角,在面对玩家时如果太容易被击杀那便失去了游戏的挑战性。所以敌机应该如同主角战机一样拥有属性,并且可以把敌机分类别,例如小敌机、中敌机、大敌机以及最后要战胜的Boss领主。不同类型的敌机各自拥有自己的属性,不同的枪械和弹幕。在属性和弹幕等方面分析后,需要思考敌机的生成方式。敌机可以从屏幕的上方生成,向下方飞行。如果只是简单的飞行是满足不了玩家需求的,因此需要一个敌机智能AI系统,敌机与战机两者之间距离少于一定是,敌机会向战机飞去。与普通的敌机不同,Boss应该在一定范围内移动,直到被玩家消灭,所以Boss也应该有自己的移动路线,在该路线上循环移动。最后,分析一下在游戏过程中需要的功能需求。在游戏过程中的菜单暂停功能,给玩家处理其他事情时带来方便。道具功能,战机在获得道具后可以切换成超级武器,增加攻击。局域限制功能,如果敌机未被玩家击败而是飞出了区域外,需要销毁这个对象,减少Unity的资源消耗,同理战机和敌机的子弹也需要。游戏结束的条件判定功能,如果战机血量为0游戏失败,敌机Boss血量为0游戏胜利。游戏数据存储读取功能,在每次游戏结束时保存获得的经验,每次游戏开始时读取战机的属性。 综上所诉,将本文探究研发的游戏功能大致划分为如下几个模块。场景模块:根据上诉玩家需求分析,在场景中,当玩家通过鼠标键盘输入对应指令时,游戏场景内的组件应该做出对应的反应,给出反馈;战机模块:战机控制,飞行有区域限制,具备属性,枪械子弹,战机外貌;敌机模块:敌机分类别,具备属性、枪械子弹,有AI控制其行为;游戏功能模块:暂停功能、道具功能、胜负条件判断、区域限制、保存读取功能;游戏大体功能划分如下图3-1所示。图3-1游戏大体功能规划图3.2游戏的总体方案设计3.2.1游戏结构方案设计基于考虑玩家接触游戏不同类型的时间各有不同,为让玩家能快速上手,本文游戏大体结构不能太过复杂,结合参考大部分游戏,得出结构如下图3-2所示。图3-2游戏大体结构图3.2.2总体结构方案设计 结合上述结论,本游戏总体结构模块框架图如下图3-3所示。
图3-3游戏总体结构模块图 结合上述需求分析,按照游戏总体结构模块图,以Unity3D游戏开发引擎和C#脚本为基础,实现游戏的研发。
第四章游戏详细设计及实现 按照需求分析和总体设计方案,对游戏进行详细设计,细化完善各个模块并且实现。4.1场景模块 本游戏场景模块主要使用Unity3D引擎自带的GUI系统UGUI制作,结合C#脚本实现如场景跳转等功能。为了统一游戏颜色基调,在非游戏场景中,需要把MainCamera中的ClearFlags由Skybox改为SolidColor,把背景颜色调成黑色。然后在Hierarchy面标中点击Create-->UI-->Canvas创建一个画布。 4.1.1开始场景 在开始场景中,在画布组件上鼠标右击UI-->Text创建文本作为游戏名字标题,把Text的锚点固定在中上方。为了开始界面不那么单调适当添加一些游戏角色图片,放在标题下方。右击Canvas-->UI-->Panel,在Panel面板里添加水平布局组,方便为后面放入图片后能自动调整位置,在Panel里面添加三个Image,更换Image精灵。添加三个游戏按钮右击Canvas-->UI-->Button,startgame、resetgame、exitgame。分别对应开始游戏,重置游戏,退出游戏。为了给玩家带来点击按钮反馈,在Button组件面板上进行调整。添加点击音效,在OnClick()上添加声音点击事件。在Transition上选择ColorTint,把HighLightedColor的透明度调低,实现当鼠标放在上面时有颜色反馈的效果。如图4-1所示。按照上述操作,开始界面制作如下图4-2开始场景所示。图4-1按钮设置图图4-2开始场景 4.1.2战机属性场景 战机属性场景主要是展示当前战机的外貌和所有属性,在Canvas上右击选择UI-->Panel创建一个板作为大画板,管理全部的UI。为了显示战机外貌,需要创建图片来显示战机外貌,右键选择UI-->Image,创建Image更名为PlayerImage。把PlayerImage图片精灵更换成战机外貌,锚点设置在左边,调整位置。为了反馈战机当前经验进度,在PlayerImage上右键选择UI-->Text,创建的文本用作后期实现反馈的文本。如图4-3所示。图4-3战机外貌设置图战机属性分为名字、等级、血量、速度、攻击力、当前经验。为了完善经验方面的反馈,再增加升级下一级需要经验和当前拥有可用来升级的经验。在Panel上右键UI-->Panel创建一个新板,改名为Text。在Text板内添加文本,每一个文本对应上述属性的名字。在Text板的Inspector面板上添加组件水平布局组,选择UpperLeft对齐。如图4-4所示图4-4Text板设置图复制一份Text板,改名为Display,用作显示属性对应的数值,水平移动到Text板的右边,为与Text板区分开,把Display板内的文字颜色换成其他颜色。按照上述按钮创建方法,添加一个按钮改名为Start,作为跳转到下一个选择关卡场景的载体。按照上诉操作,战机属性界面如下图4-5所示。图4-5战机属性场景图 4.1.3关卡选择场景 游戏关卡一共设置为三关,分别为绿色峡谷,天空废墟,沙漠戈壁。玩家可以自行选择任一关卡进行游戏。右击Canvas,选择UI-->创建Panel,在Panel中加入水平布局组件,在水平布局组件中选择MiddleCenter。右击Panel,选择UI-->Image,添加三张图片,分别把每张图片的精灵换成对应关卡的背景图。在图片下方添加文本组件,用来描述关卡名字。文本下面添加上述制作的按钮,用来给后续进入关卡做载体,如下图4-6所示。图4-6关卡选择界面Panel设置图添加一个按钮作为回退到战机属性场景的载体,锚点定在左上角。按照上诉操作,关卡选择界面如下图4-7所示。图4-7关卡选择界面图 4.1.4加载场景 在Unity中如果需要加载的游戏场景体积过大,在普通的场景跳转的时候显示屏会黑屏许久,带来不友好的体验。为了在场景加载中给玩家一些反馈信息,本游戏设定在加载游戏场景的时候使用异步加载的方式,而跳转非游戏场景时则使用普通的跳转方式。为了实现异步加载场景,需要新建一个场景,因此便有了加载场景。 在加载场景中,在Canvas画布上如同开始场景制作了三个卡通人物人Panel,增加了场景的趣味性。加载场景最需要给出玩家反馈信息便是加载进度,右击Canvas,选择UI-->Text创建文本,用作显示进度条加载百分比数字。选择UI-->Slider创建滑动条,点开Slider删除HandleSlideArea,修改FillArea下的Fill颜色变成黄色,作为进度条加载时的颜色,如下图4-8所示。图4-8Slider设置图调整Slider长度大小,把固定在Canvas正下方。把Text文本组件移动到Slider上方。按照上诉操作,加载界面如下图4-9所示。图4-9加载界面 4.1.5游戏场景 本游戏共有三个关卡,以制作第一个关卡为例,其余两个关卡UI只与第一个背景图片不一样。 游戏场景中左边为游戏界面,右边为显示其他内容UI。先从左边游戏界面制作开始。作为一个竖版飞行射击游戏,背景是一直在滚动的,为了实现这一个功能在Hierarchy窗口点击Create-->CreateEmpty创建一个空物体,名字改为Background用来存放背景图片。把背景图片拉进Background物体,在背景图片的Inspector窗口下的图片属性下添加几个图层Background层、UI层、Play层,把背景图片的图层选择成Background层。复制粘贴一份,上下调整位置,连成一张大图片。如下图4-10所示。图4-10背景图片设置图 背景滚动需要C#脚本支持,创建一个脚本BackgroundMove.cs。定义一个图片移动速度,当图片的Y轴移动到快要出去摄像机画面的时候,改变它的位置,让它回去到一开始在它上一张图片的位置。这样两张图片交替,形成无限滚动的效果。 右边游戏界面,右击Cavans选择UI-->Panel,观察Game窗口调整Panel的大小,让其与左边游戏脚面紧凑在一起,把图片精灵换成图片,游戏中设有计时器和分数显示,右击Panel选择UI-->Text,创建两个文本作为显示时间和分数的载体。按照4.1.4的进度条制作方法,用Slider制作两个血条,BossHpBar和PlayerHpBar用来反馈血条变化。调整它们之间的位置,游戏界面如下图4-11所示。图4-11游戏界面图 菜单界面制作:菜单的功能有重开游戏和退出游戏。右击Canvas选择UI-->Panel,创建Panel改名为menu。修改menu大小锚点固定Canvas在中间,在menu内添加Text文本,用作提示玩家游戏暂停,文本锚点固定在menu中上方。添加两个按钮一个重玩一个退出。按照上述操作菜单界面如下图4-12所示。图4-12菜单界面图 胜利界面制作:胜利界面主要反馈玩家在这一次战役中获得的经验和分数以及通关时间。右击Canvas选择UI-->Panel,创建Panel改名为Victory并调整大小放置在Canvas中央。添加四个文本,第一个作为标题,第二个显示获得经验,第三个显示分数,第四个显示通关时间。第一个文本字体调大放置在中上方,后三个文本垂直排序放在中左边。添加一个退出按钮作为返回战机属性场景的载体。按照上述操作,胜利界面如图4-13所示图4-13胜利界面图 失败界面制作:失败界面与胜利界面大致一样,不过不需要显示分数和通关时间。复制一份胜利界面,改名为defeat,把分数文本和时间文本删除,调整一下经验文本位置,如图4-14失败界面图所示。图4-14失败界面图4.2战机模块 把战机的一张图片拖拽进Hierarchy窗口,把名字改为Player,添加刚体Rigidbody2D和碰撞体PolygonCollider2D组件。因为是2D游戏,在Rigidbody2D中把GravityScale设为0,在PolygonCollider2D中把isTrigger勾选上。 4.2.1操纵模块 给Player添加脚本Player.cs,使玩家可以通过键盘操纵战机移动。当按下键盘WASD或者上下左右键战机进行移动,通过刚体控制战机发生运动。创建三个变量分别纪录水平左边,垂直坐标和速度。把坐标赋予给新的二维坐标发生移动。 战机飞行区域是有限制的,战机只能在固定区域移动。区域的大小取决于左边游戏界面的大小。在每一帧的判断中,如果机位置超出区域限制时,会强制战机位置变回在限制区域边缘,每一次判断最后重置当前位置。 4.2.2属性模块 在游戏场景中战机的属性有血量,速度,等级,攻击力,战机每升一级的属性都有所增加。在开始游戏时,会读取在战机属性场景中战机的属性,然后赋予给游戏场景中的Player。在Player.cs脚本中有两个血量变量,一个是最大血量playerMaxHp,一个当前血量playerCurrentHp,playerCurrentHp的值与战机血条挂钩。速度限制战机的移动。等级与战机的外观有关,战机一共拥有12级,每隔三级战机会更新外观和子弹枪械。攻击力与战机子弹伤害有关。 4.2.3外观模块 战机一共拥有拥有4个外观,每隔3级更换一次。在Player.cs脚本中创建一个Sprite数组用来存放战机不同阶段的外观。在游戏开始时,根据传过来的等级划分,对应阶段对应外观,如下图4-15。图4-15战机外观精灵数组 4.2.4枪口子弹模块战机不同阶段有不同的枪口,随着等级的提升枪口会越来越多。第一阶段时只有1个正常枪口和1个特殊枪口。二阶段时有1个正常枪口和2个特殊枪口。三阶段有2个正常枪口和2个特殊枪口。四阶段有3个正常枪口2个特殊枪口。在Player组件下创建空物体用作枪口,枪口放置如下图4-16所示。图4-16战机枪口放置图 在进入游戏后战机先会判断自身在那个阶段,判断完成后会根据所在阶段,把该阶段的普通枪口打开。创建脚本Gun.cs,通过实例化函数Instantiate(),实例化子弹预制体,再用InvokeRepeating()函数委托机制来重复实例化子弹。 当玩家操纵战机获得道具的时候,战机会改变枪口或增加枪口的数量,从而得到强化。道具具有时效性,超过时间便由超级枪口变回普通枪口。在Player.cs脚本中定义变量specialGunTime特殊枪口时间,resetGunTime重置时间,gunLevel枪口等级。构建两个方法SpecialGun()特殊枪口,NormalGun()正常枪口。获得道具后,切换成特殊武器,超出时间切换成正常武器。 不同阶段的枪口有不同的子弹,把子弹的图片拖拽进Hirearchy窗口,添加Rigidbody2D和BoxCollider2D组件。把Rigidbody2D里的GravityScale设置为0,BoxCollider2D里勾选上isTrigger。创建PlayerBullet.cs脚本挂载在自己身上。在脚本里设置变量子弹速度bulletSpeed和子弹伤害bulletHit。子弹伤害继承战机选择场景中的攻击。因为子弹是由战机发射,使用transform.Translate()方法向上运动。当子弹超过一定Y轴距离之后用Destroy()方法销毁自己,从而节省资源。当子弹碰到敌机的时候使用OnTriggerEnter2D()方法检测碰撞物体的标签,如果标签是“Enemy”或是“Boss”的时候,显示判断敌机是否死亡,不是死亡则调用Enemy脚本里面的BeHit方法,并销毁自己。 4.2.5碰撞模块 在游戏中,战机会与其他物体发生碰撞。在不考虑与自己子弹碰撞的情况下,会与战机发生碰撞的有道具,敌机,敌机子弹。在这里分析前两者,战机获得道具后道具消失并播放一段音效。碰到敌机时,战机当前生命值减一。碰撞检测使用OnTriggerEnter2D()的方法来处理。给道具加上“Award”标签,敌机加上“Enemy”标签。4.3敌机模块 4.3.1类别属性模块敌机类别大体分为两类,非Boss敌机,Boss敌机。为了增加游戏可玩性,把非Boss敌机细分成三种小敌机,中敌机,大敌机。Boss敌机根据关卡数量设置等数量Boss。把全部敌机图片拖拽Hierarchy窗口,均添加Rigidbody2D和碰撞体BoxCollider2D组件。创建Enemy.cs脚本并挂载在敌机上,在脚本中使用枚举的方法把敌机类别列出,方便后续敌机区分。敌机主要属性有生命值,飞行速度,分数,经验。当战机子弹与敌机发生碰撞后,通过BeHit方法进行生命扣除,当生命值小于等于0敌机销毁。敌机从顶部生成通过transform.Translate方法向底部运动。在敌机本销毁后玩家得到相应的分数和经验。分数会实时在UI界面更新,经验需要在游戏结束后才能查看。4.3.2枪口子弹模块 不同类别的敌机有不用的枪口,小敌机只有一个枪口,中敌机有两个枪口,大敌机有三个枪口,而Boss敌机因具有特殊弹幕只需一个枪口即可。和战机枪口制作类似,通过在敌机组件下创建空物体来作为枪口,在空物体上挂载上Gun脚本。敌机枪口设置如下图4-17所示。图4-17敌机枪口设置图 非Boss敌机枪口开枪原理与战机枪口原理一样,都是通过Instantiate(),实例化子弹预制体,InvokeRepeating()委托来重复实例化子弹。非Boss敌机子弹与战机子弹的不同有两点,敌机子弹是向下运动,敌机子弹碰撞检测的对象是战机。新建脚本EnemyBullet.cs挂载在敌机子弹的预制体上,修改函数transform.Translate()的方向和OnTriggerEnter2D()方法里面的标签判读修改为“Player”即可。与战机子弹一样,在敌机子弹运动到游戏区域外就会自动销毁节省资源。为了增加游戏的挑战难度,每一个Boss拥有自己的弹幕,本游戏一共制作了三种弹幕,分别是散弹弹幕,圆形弹幕,组合圆形弹幕。创建脚本BulletMode.cs,弹幕的实现使用了协程方法。先构造一个子弹生成方法CreatBullet,方法有两个参数方向和生成位置。散弹弹幕:发射方向初始值为枪口方向,构建两个四元素变量,一个向左一个向右。使用for循环嵌套switch循环,发射第一颗子弹后旋转到另外一个位置,如此类推来实现散弹枪子弹的发射。圆形弹幕:发射方向初始化为枪口方向,构建一个四元数变量来记录旋转的角度,使用用for循环在发射一颗子弹后,枪口按照四元数变量的角度进行旋转发射下一颗,形成圆形弹幕。 组合弹幕:发射方向初始化为枪口方向,设置一个四元数变量作为子弹一阶段旋转发射角度,建立一个列表来存放一阶段发射的子弹。按照圆形单发射的原理发射子弹,把一阶段发射出去的子弹放在列表中。使用协程功能停顿1s后在一阶段发射子弹的位置上,调用圆形弹幕生成,让子弹形成2阶段的圆形弹幕。4.3.3敌机AI模块 敌机AI模块分为两个部分,非Boss敌机的寻敌功能和Boss的巡逻功能和弹幕变化功能。 寻敌功能:把敌机当前位置与战机当前位置视为两点,使用Distance()方法来计算他们的间距,当间距少于跟随距离预设值时,敌机通过MoveTowards()方法先战机移动。为了避免当敌机在战机下方时还继续跟随,需先判断敌机的Y轴坐标是否大于战机Y轴坐标,大于则判断是否跟随。 巡逻功能:因为游戏拥有三个关卡,所以需要在boss巡逻前判断当前关卡。在判断结束后执行预定的路线巡逻功能。巡逻功能与上诉跟随功能相似,先确定向一个巡逻点移动,然后使用方法Distance()来判读是否到达巡逻点,MoveTowards()方法来向下一个巡逻点移动。 弹幕变化功能:通过访问图片的fillAmount属性来得到Boss的血条百分比。当百分比大于60%的时候弹幕简单,少于等于60%的时候先把前一个协程关掉再重新运行一个新的弹幕协程,更改协程的参数让弹幕变得复杂。4.4游戏功能模块4.4.1敌机与道具生成模块 制作道具预制体:把道具图片Hirearchy窗口,添加Rigidbody2D和BoxCollider2D组件。道具向下运动,在超出游戏场景范围后销毁自生。创建Award脚本,实现上述功能。 道具与非boss敌机都在游戏场景上方出现,因此可以创建一个新物品作为孵化点放在游戏场景上方。生成的方式与子弹生成一样使用Instantiate()实例化预制体,InvokeRepeating()委托机制重复生成。创建Spawn脚本,定义敌机与道具生成频率变量,关卡变量。更具关卡的不同,生成的敌机也不同。为了让战机生成位置随机在实例化时把X轴的坐标变成一个随机数,实现随机位置生成。 在Boss出现的时候,孵化点停止孵化敌机。构建StopSpawn()方法,调用CancelInvoke()方法来停止委托。 Boss是一直存在在游戏界面上的,一开始通过GetComponent获取Renderer组件和BoxCollider2D组件,把组件里面的enabled值设置成false进行隐藏。当时间超过60秒和布尔值isBoss等于false时,Boss两个组件的enabled值和isBoss变为true,boss显示出来,同时调用StopSpawn方法停止敌机的孵化。4.4.2游戏场景UI更新模块 为了给玩家游戏过程中带来实时的反馈体验,游戏场景中需要实时更新的UI有计时器,分数,boss血量和战机血量。创建脚本GameManage.cs用来管理UI的更新,定义两个文本变量来获取计时器和分数组件,两个int类型变量playscore和exp为后续做好准备。在Awake方法里面先单例化,然后在Update方法里面实现实时更新。 当敌机生命值少于0后销毁自身,通过BeHit方法实现玩家分数和经验的增加 战机血条与Boss血条更新功能一样,通过start方法获得血条的组件,然后获得目标当前生命值与最大生命值的百分比值,把值赋予给滑动条的fillAmount,实现血条的更新。为了能更好的反映血条剩余的值,使用判断语句,当血量在30%以上60%一下的时候显示黄色,少于30%的时候显示红色。4.4.3场景跳转模块 创建LoadingScene.cs脚本,本游戏中除跳转到游戏场景中使用异步加载外,其余均使用SceneManager中LoadScene方法实现场景转换。 实现异步加载场景需要获得想要跳转的的场景名字,把目标场景名字传递给LoadSceneAsync中从而实现异步加载。为了能反馈加载的进度,在start方法中把allowSceneActivation的值设为false,防止场景在进度条没加载完就跳转。在Update方法中临时进度使用线性插值函数Lerp来回去进度条加载百分比的值,加载条的填充值根据临时进度来填充。当填充之到1之后allowSceneActivation值变为true,从Loading场景跳转到目标场景。 在按钮的OnClick事件中选择对应的跳转场景功能。4.4.4暂停与结束功能模块 在GameManager.cs脚本内添加三个Image变量gameMenu,victory,defeat,对应游戏菜单界面,胜利界面,失败界面,在游戏开始时三个界面的SetActive值均设置false。当玩家按下esc键时,通过判断布尔值isPaused,来判读现在是否出于暂停。如果是true,gameMenu的SetActive变为false菜单消失,timeScale等于1游戏回到正常运行。如果是false,gameMenu的Setactive值变为true菜单显示,timeScale等于0游戏暂停。 胜负条件的判断在于战机的血量和Boss的血量,战机血量变为0游戏失败,Boss血量小于等于0游戏胜利。构建Victory和Defeat方法,无论是那种方式结束游戏,把timeScale的值设为0游戏暂停,把对应的胜利失败界面显示出来,更新界面上的文本信息。4.4.5数据保存读取模块 在本游戏中需要保存数据的地方有两个,一个是游戏结束后点击exit按钮退出时需要保存这次游戏过程中获得的经验值。另一个是在战机属性场景中点击Start按钮后跳转到关卡场景时需要保存战机的各种属性。而需要读取数据的地方有两个,一个在进入战机属性场景时需要读取当前战机的属性和拥有可支配经验并显示出来。另一个在进入游戏场景时战机的属性要读取在战机属性场景中保存到的属性。 游戏中因为需要保存的属性数量较少,所以选择使用PlayerPerfs方法。创建SaveAndLoad.cs脚本,使用PlayerPerfs中的setInt方法保存数据,保存经验方法与保存属性方法分开编写。 编写两个方法SaveExp和SavePlay,方便再按钮的OnClick中调用。在方法中分别调用SaveByOverExp(),SaveByPlayer()。在上述场景中的按钮上添加各自需要的功能。 读取数据使用PlayerPerfs中的Haskey方法,在战机属性场景中新建一个空物体,在空物体上挂载一个新脚本PlayerStatus.cs用来管理战机属性。在脚本内按照战机属性场景中名字为Display组件中所有元素创建对应变量。在start方法里面在把保存数据赋值给变量前需要先做判断,在拥有那对应名字的键时才赋予值,否则变量的值为原设置的值。这样做的目的是为了放置第一次进入游戏时,在没通关游戏时保存数据,在读取时没有对应的键而发生报错。 在游戏界面在开始时,在Player.cs脚本中战机读取属性。4.4.6战机升级模块 在战机属性界面中玩家可以通过按下空格键给战机分配经验,当经验满了之后战机升级,在每次升级后战机属性更新。战机最高等级为12级,拥有四个外观,每隔三个等级便会发生外观上的变化。战机每一级升级所需经验通过for循环以1.1倍来增加,并用数组存储起来。 在按下空格键增加经验时需要判断当前拥有可支配经验是否大于200并且战机等级少于12级。满足条件后才能调用加经验方法。在加经验方法中每按下一次战机经验增加,拥有可支配经验减少。再判断当前经验是否超过升级需要经验并且当前等级少于12级,如果是则调用升级方法,完成后调用更新属性方法对面板进行更新。在升级方法中,升级后当前经验减需要减去升级所需经验,战机等级和其他属性需要发生变化并调用更新战机外观方法更新外观。
第五章游戏导出与测试 导出运行游戏并对其进行游戏测试,确保游戏内容的完善和功能的实现。 5.1游戏导出 游戏设计已经完成,接下来便是把游戏打包导出。点击工具栏上方的File,选择BuildSettings,把制作好的场景拖进ScenesInBuild中,然后点击右下方的Build按钮,等待游戏导出。图5-1游戏导出图 5.2游戏测试 双击打开上面导出游戏的exe文件,游戏正常运行。使用黑盒测试对游戏中各个功能做可行性测试,经过多次游戏功能测试后,总结测试结果结果如下表5-1所示。表5-1游戏功能测试结果测试项目描述/操作执行结果可行性战机移动按下WASD/方向键战机发生移动可行场景跳转点击跳转按钮场景发生跳转可行战机升级按下升级键战机升级属性更新可行敌机寻敌控制战机接近敌机敌机跟随战机可行Boss巡逻游戏中等待Boss出现Boss按照规划路线移动可行游戏场景UI更新进行游戏场景中各UI更新正常可行数据保存读取更新一次战机属性后再进入游戏
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 湖南申论模拟108
- 湖南申论模拟215
- 2024年银行个人商业用房贷款抵押借款合同范本
- 2013年6月29日上午面试真题
- 甘肃省公务员面试真题汇编3
- 建筑工程有限公司年度责任目标任务及考核方案
- 山西公务员面试模拟27
- 2024年工资集体协商要约书(范本)
- 地方公务员浙江申论171
- 河北省公务员面试模拟127
- GB/T 10739-2023纸、纸板和纸浆试样处理和试验的标准大气条件
- 康复治疗行业发展趋势
- 27.1.1 圆的基本元素 华师版九年级数学下册学案
- 辛亥革命之意义
- 工业机器人离线编程与仿真(ABB)高职全套教学课件
- 实验1-接触角探测液法测定聚合物表面张力
- MRI核磁理论知识考核试题与答案
- 2023-2024学年福建省厦门十中九年级(上)期中数学试卷
- JET-300-debug-常见-调试-繁体中文版-图文版
- 抵制宗教进校园
- 眼脓肿的护理课件
评论
0/150
提交评论