赞
踩
国内的三维游戏开发技术正处于赶超国外的关键时期,以大型的游戏作为主流。但是,小游戏的制作,还是不断在扩展。大部分的电脑用户,都是闲暇时进行游戏,所以一个有乐趣的小游戏已经足够满足他们的需求。
本游戏的开发目的,就是为了满足这部分的用户。
大型游戏一个很重要吸引用户的地方,是能给用户拥有自己创造的人物模型,趋于这个目的,本游戏提供了一个能给用户制作人物模型的编辑器,大大吸引了用户。
游戏和模型编辑器的模型运用的是自定义的数据结构,所以游戏能绘制编辑器编辑出来的模型。
本游戏是基于OpenGL库的运用,结合面向对象方法开发的。
OpenGL定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。OpenGL的英文全称是“Open Graphics Library”,顾名思义,OpenGL便是“开放的图形程序接口”。OpenGL仍然是唯一能够取代微软对3D图形技术的完全控制的API。
通过利用OpenGL的三维图形软件包,深入了解运用Visual C++制作一个拥有可供用户自行定义游戏关卡的3D飞行射击游戏。体现人机交互。充分运用项目开发、面向对象、算法等。
关键词:OpenGL 游戏 设计 VisualC++ 飞行射击
OPENGL BASED ON THE ARCADE-STYLE GAME DEVELOPMENT AND DESIGNS
In three-dimensional space development of technology was crucial in emulation of foreign, in large game as the mainstream. But little game, or in developing steadily. the majority of computer users, it is time to games, so a fun little game enough to meet their requirements.
This game development purpose is to satisfy the part of the user.
Large game a very important to attract users, is to give users have created a model, to this end, this game a model for making characters on the user's editor, has greatly attracted to the user.
Game and the model editor model using a custom data structure of the game, so you can draw the editor to edit out of the model.
This game is based on OpenGL the storehouse the utilization, the object orientation of development.
OpenGL defines a programming language, and stepped across the programmatic interface to specifications. It is a three-dimensional image(2d also). Opengl is a professional graphics applications, is a powerful call to the ground floor, a library. opengl english name is "open graphics library," suggests, is "open interface graphics program”. Opengl only with 3d graphics able to replace the microsoft technology complete control of the API.
OpenGL by using 3-d graphics package, the probe to use visual c making a definition for users on the stage of the 3d arcade-style game. That interaction full use of the man-machine development, designing object-oriented and algorithms.
Key words:OpenGL game design VisualC++ firepowerex
目 录
5.2.2 OpenGL窗口创建(OpenGL.h、OpenGL.cpp)
5.2.3游戏控制器(Contral.h、Contral.cpp)
5.2.4机体对象基本类(ObjData.h、ObjData.cpp)
5.2.5敌机对象类(ObjBaseData.h、ObjBaseData.cpp)
5.2.6敌机对象控制器(AiObj.h、AiObj.cpp)
5.2.7战机对象控制器(SelfObj.h、SelfObj.cpp)
5.2.8子弹对象类(BulletObj.h、BulletObj.cpp)
5.2.9子弹对象控制器(BulletMenager.h、BulletMenager.cpp)
5.2.10文件读取控制器(FioMenager.h、FioMenager.cpp)
5.2.11文字显示类(CGLFont.h、CGLFont.cpp)
5.2.12火花对象类(Grain.h、Grain.cpp)
5.2.13火花对象控制器(GrainMenager.h、GrainMenager.cpp)
5.2.14碰撞检测(Hitexamina.h、Hitexamina.cpp)
5.2.15模型控制器(modeMenager.h、modeMenager.cpp)
5.3.1MFC窗口(CMakeFlyModeDlg.h、CMakeFlyModeDlg.cpp)
5.3.2OpenGL窗口创建(OpenGL.h、OpenGL.cpp)
5.3.3子模型管理(BaseGraphics.h、BaseGraphics.cpp)
5.3.4子模型类(GraphicsObj.h、GraphicsObj.cpp)
软件系统名称:飞行射击游戏
本项目是根据毕业设计的要求,经过本人实践及深思熟虑后提出,结合所学知识所作出的最终决定。
OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。IRIS GL是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL。OpenGL的英文全称是“Open Graphics Library”,顾名思义,OpenGL便是“开放的图形程序接口”。Open GL仍然是唯一能够取代微软对3D图形技术的完全控制的API。
由于 Linux 操作系统平台的大力推广,基于Linux 的各种应用软件也不断壮大,因此基于跨平台图形库的跨平台三维游戏开发也越来越受重视。OpenGL(open graphics library)是一种独立的平台无关的三维图形开发库,在各种语言下进行主框架开发并结合应用OpenGL 函数都可以开发出三维游戏。但是由于框架开发的平台相关性使游戏无法跨平台编译运行,因此glut+OpenGL 的方式成了一种很好的选择。但是在对复杂框架和各种媒体的支持方面,glut 并不理想。在Linux 下可以采用FLTK 等框架平台技术实现包括按钮在内的比较复杂的框架功能,但是需要专门的Linux 开发环境,众多的Window 环境下的KDE 爱好者明显对此无法适从。相反,SDL(Simple DirectMedia Layer)作为免费的跨平台多媒体应用编程接口,已经被人们广泛用于开发二维游戏,其优秀的消息框架支持、文件支持和声音支持等都使得它成为能与微软DirectX 匹敌的最为成熟的技术之一。
国内的三维游戏开发技术正处于赶超国外的关键时期,从创意、策划、研究开发与实现,到游戏的运营与维护,都有大量的知识值得学习和摸索。
一个优秀的游戏,不但画面漂亮,游戏性能好,而且游戏有特色,娱乐性好。
性能的好坏是基于良好的游戏架构跟算法,研究开发一个OpenGL游戏能更好的探索和巩固当中的奥秘。
优秀的游戏给人带来娱乐,休闲之余带来更多的乐趣。对计算机要求低,可供更多的游戏玩家享乐。
通过利用OpenGL的三维图形软件包,深入了解运用Visual C++制作一个拥有可供用户自行定义游戏关卡的3D飞行射击游戏。体现人机交互。充分运用项目开发、面向对象、算法等的运用。
经过对某些游戏亲身体验,分析和研究后,运用计算机技术,结合飞行射击游戏的实际特点,开发了这飞行射击游戏。一个好的游戏,给人带来娱乐,休闲之余带来更多的乐趣。对计算机要求低,可供更多的游戏玩家享乐。玩家可以通过游戏附带的模型制造工具来制作自己喜爱的飞机模型。为了能让玩家可以制作模型,不需开发一个操作简单的游戏模型制作器,导出模型信息,并能被游戏识别。
本游戏通过Microsoft Visual C++ 6.0集成开发环境,使用C++语言及OpenGL库、STL库进行开发基本达到要求。
C++这个词在中国大陆的程序员圈子中通常被读做“C加加”,而西方的程序员通常读做“C plus plus”,“CPP”。 它是一种使用非常广泛的计算机编程语言。C++是一种静态数据类型检查的,支持多重编程范式的通用程序设计语言。它支持过程化程序设计、数据抽象、面向对象程序设计、制作图标等等泛型程序设计等多种程序设计风格。
C语言之所以要起名为“C”,是因为它是主要参考那个时候的一门叫B的语言,它的设计者认为C语言是B语言的进步,所以就起名为C语言;但是B语言并不是因为之前还有个A语言,而是B语言的作者为了纪念他的妻子,他的妻子名字的第一个字母是B; 当C语言发展到顶峰的时刻,出现了一个版本叫C with Class,那就是C++最早的版本,在C语言中增加class和类,那个时候有很多版本的C都希望在C语言中增加类的概念;后来C标准委员会决定为这个版本的C起个新的名字,那个时候征集了很多种名字,最后采纳了其中一个人的意见,以C语言中的++运算符来体现它是C语言的进步,所以就叫C++,也成立了C++标准委员会;
一开始C++是作为C语言的增强版出现的,从给C语言增加类开始,不断的增加新特性。虚函数(virtual function)、运算符重载(operator overloading)、多重继承(multiple inheritance)、模板(template)、异常(exception)、RTTI、命名空间(name space)逐渐被加入标准。1998年国际标准组织(ISO)颁布了C++程序设计语言的国际标准ISO/IEC 1488-1998。C++是具有国际标准的编程语言,通常称作ANSI/ISO C++。1998年是C++标准委员会成立的第一年,以后每5年视实际需要更新一次标准,下一次标准更新将是在2009年,目前我们一般称该标准C++0x。遗憾的是,由于C++语言过于复杂,以及他经历了长年的演变,直到现在(2009年)只有Visual C++ 2010 CTP开发环境的编译器完全符合这个标准。
另外,就目前学习C++而言,可以认为他是一门独立的语言;他并不依赖C语言,我们可以完全不学C语言,而直接学习C++。根据《c++编程细想》(Thinking in C++)一书所评述的,C++与C的效率往往相差在正负5%之间。所以有人认为在大多数场合C++ 完全可以取代C语言(然而我们在单片机等需要谨慎利用空间、直接操作硬件的地方还是要使用C语言)。
OpenGL - 高性能图形算法行业标准
OpenGL™ 是行业领域中最为广泛接纳的 2D/3D 图形 API, 其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。OpenGL™ 是独立于视窗操作系统或其它操作系统的,亦是网络透明的。在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL™ 帮助程序员实现在 PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。
OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。IRIS GL是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL。OpenGL的英文全称是“Open Graphics Library”,顾名思义,OpenGL便是“开放的图形程序接口”。
OpenGL是个与硬件无关的软件接口,可以在不同的平台如windows 95、 windows NT、Unix、Linux、MacOS、OS/2之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。由于OpenGL是图形的底层图形库,没有提供几何实体图元,不能直接用以描述场景。但是,通过一些转换程序,可以很方便地将Auto CAD、3DS/3DSMAX等3D图形设计软件制作的DXF和3DS模型文件转换成OpenGL的顶点数组。
在OpenGL的基础上还有Open Inventor、Cosmo3D、Optimizer等多种高级图形库,适应不同应用。其中,Open Inventor应用最为广泛。该软件是基于OpenGL面向对象的工具包,提供创建交互式3D图形应用程序的对象和方法,提供了预定义的对象和用于交互的事件处理模块,创建和编辑3D场景的高级应用程序单元,有打印对象和用其它图形格式交换数据的能力。
STL = Standard Template Library,标准模块库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL现在是C++的一部分,因此不用额外安装什么。它被内建在你的编译器之内。
在C++标准中,STL被组织为下面的13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。
算法:
大家都能取得的一个共识是函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了相当多的有用算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。
STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。这样一来,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。
算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。<algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。<functional>中则定义了一些模板类,用以声明函数对象。
容器:
在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。STL容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模版类,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化。
容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过下表总结一下它们和相应头文件的对应关系。
数据结构 描述 实现头文件
向量(vector) 连续存储的元素 <vector>
列表(list) 由节点组成的双向链表,每个结点包含着一个元素 <list>
双队列(deque) 连续存储的指向不同元素的指针所组成的数组 <deque>
集合(set) 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 <set>
多重集合(multiset) 允许存在两个次序相等的元素的集合 <set>
栈(stack) 后进先出的值的排列 <stack>
队列(queue) 先进先出的执的排列 <queue>
优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 <queue>
映射(map) 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 <map>
多重映射(multimap) 允许键对有相等的次序的映射 <map>
迭代器:
下面要说的迭代器从作用上来说是最基本的部分,可是理解起来比前两者都要费力一些(至少笔者是这样)。软件设计有一个基本原则,所有的问题都可以通过引进一个间接层来简化,这种简化在STL中就是用迭代器来完成的。概括来说,迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
迭代器部分主要由头文件<utility>,<iterator>和<memory>组成。<utility>是一个很小的头文件,它包括了贯穿使用在STL中的几个模板的声明,<iterator>中提供了迭代器使用的许多方法,而对于<memory>的描述则十分的困难,它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制,<memory>中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
VC++是微软公司开发的一个IDE (集成开发环境),换句话说,就是使用c++的一个开发平台.有些软件就是这个编出来的...另外还有VB,VF.只是使用不同语言...但是,
vc++是Windows平台上的C++编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC Win32 API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。
VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VC++不是门语言,虽然它和C++之间有密切的关系,如果形象点比喻的话,可以把C++看作为一种“工业标准”,而VC++则是某种操作系统平台下的“厂商标准”,而“厂商标准”是在遵循“工业标准”的前提下扩展而来的。
VC++应用程序的开发主要有两种模式,一种是WIN API方式,另一种则是MFC方式,传统的WIN API开发方式比较繁琐,而MFC则是对WIN API再次封装,所以MFC相对于WIN API开发更具备效率优势,但为了对WINDOWS开发有一个较为全面细致的认识,笔者在这里还是以讲解WIN API的相关内容为主线。
话说到这里可能更多人关心的是学习VC++需要具备什么条件,为什么对于这扇门屡攻不破呢?
要想学习好VC必须具备良好的C/C++的基础,必要的英语阅读能力也是必不可少的,因为大量的技术文档多以英文形式发布。
VC基于C,C++语言,主要由是MFC组成,是与系统联系非常紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高,几乎可说VC在 Windows平台无所不能。 最大缺点是开发效率不高。
VC适用范围
1、 VC主要是针对Windows系统,适合一些系统级的开发,可以方便实现一些底层 的调用。在VC里边嵌入汇编语言很简单。
2、 VC主要用在驱动程序开发
3、 VC执行效率高,当对系统性能要求很高的时候,可用VC开发。
4、 VC主要适用于游戏开发
5、 VC多用于单片机,工业控制等软件开发,如直接对I/O地址操作,就要用C++。
6、 VC适用开发高效,短小,轻量级的COM组件,DLL。比如WEB上的控件。
7、 VC可以开发优秀的基于通信的程序。
8、 VC可以开发高效灵活的文件操作程序。
9、 VC可以开发灵活高效的数据库操作程序。
10、 VC是编CAD软件的唯一选择!!!包括AUTOCAD,UG的二次开发。
11、VC在多线程、网络通信、分布应用方面,VC++有不可比拟的优势。
可行性研究的目的是用最小的代价,在尽可能短时间内确定问题是否能够解决,它的目的不是解决问题,而是确定问题是否值得去解决,可行性从以下四个方面来考虑:
飞行射击游戏和模板编辑器是用应用程序实现的。本系统使用微软公司的Microsoft Visual C++ 6.0开发,并且应用OpenGL和STL库。本人经过多年的学习,已熟练掌握这几种软件的开发技术,在以前的实践中也开发过一些相关的软件产品,并且有许多相关技术的资料,再加上指导老师的悉心帮助,所以在技术上是可行的。
经济可行性指的是对组织的经济状况和投资能力进行分析,对系统建设、运行和维护费用进行估算,对系统建成后可能取得的社会及经济效益进行估计。
本游戏的开发由本人利用毕业设计的机会开发,开发费用可以忽略不计。
本游戏的开发需要资金少。由于基本引擎已经射击完场,游戏开发运行后,可以轻松的进行各项信息的发布与管理,节省了人力、物力和财力,减少无意的错误,节省了大量的时间,更新效率也大幅度提高。本游戏小,且娱乐性高,具有一定的市场占有率,因此,在经济上是可行的。所带来的效益远远大于游戏的开发成本。在经济上完全可行。
本游戏直观易懂,使用非常方便,用户可以直接上手,操作本游戏没有太大的问题。
本系统开发不会侵犯他人、集体或国家利益,不存在侵权等问题,不违反国家法律,因此具有法律可行性。
综上所述,从技术上、经济上、法律上、可操作性上都是可行的,而且要求不高,所以该系统的开发是可行的。
在软件工程的历史中,很长时间里人们一直认为需求分析是整个软件工程中最简单的一个步骤,但在过去十年中越来越多的人认识到它是整个过程中最关键的一个过程。假如在需求分析时分析者们未能正确地认识到顾客的需要的话,那么最后的软件实际上不可能达到顾客的需要,或者软件无法在规定的时间里完工。
飞行射击游戏要求有一个可碰撞检测、并可以计分、击杀敌机、任务升级、机体改造、模型选择、用户菜单、绘制编辑器编辑出来的模型等功能。
模型制造器要求提供用户可自行编辑、修改、制造飞机模型等功能。其可以记录用户选择的子模型,对子模型进行增加、修改、删除等操作。提供用户一个可360度观察模型的功能。并能导出飞行射击游戏可识别的模型文件。
1. 运行操作系统 Windows XP或以上
2. 分辨率 最佳效果 800×600
(1)开发环境 Microsoft Visual C++ 6.0 集成开发环境
(2)开发语言 Visual C++
(3)开发环境运行平台 Windows XP(SP3)
(1)保证制作出来的模型可被识别
(2)要求游戏能快速响应用户
(3)准确无误的计算统计数据
飞行射击游戏功能需求:
(1)碰撞检测
(2)可以计分
(3)击杀敌机
(4)任务升级
(5)机体改造
(6)模型选择
(7)用户菜单
(8)绘制编辑器编辑出来的模型
模型制造器功能需求:
(1)可以记录用户选择的子模型
(2)对子模型进行增加
(3)对子模型进行修改
(4)对子模型进行删除
(5)提供用户一个可360度观察模型的功能
(6)能导出飞行射击游戏可识别的模型文件
飞行射击游戏:
图3-1 飞行射击游戏需求框架图
模型制造器:
图3-2 模型制造器需求框架图
图3-3 开始游戏程序流程图
图3-4 开始游戏数据流图
图3-5 模型选择程序流程图
图3-6 模型选择数据流图
图3-7 进行游戏程序流程图
图3-8 进行游戏数据流图
图3-9 飞行射击游戏总程序流程图
图3-10 飞行射击游戏总数据流图
图3-11 模型编辑器总程序流程图
图3-12 模行编辑器总数据流图
4.1概述
本阶段设计的基本目标是解决系统如何实现问题,也叫做概要设计,本阶段主要任务是划分出系统的物理元素及设计软件的结构,完成软件定义时期的任务之后就应该对系统进行总体设计,即根据系统分析产生的分析结果来确定这个系统由哪些系统和模块组成,这些系统和模块又如何有机的结合在一起,每个模块的功能如何实现。系统设计的目标是使系统实现拥有所要求的功能,同时,力争达到高效率、高可靠性、可修改性,并且容易掌握和使用。
模块化的依据是:把复杂问题分解成许多容易解决的小问题。原来的问题也就变得容易解决。模块化设计是把大型软件按照一定的原则划分成一个较小的相对功能独立又相关联的模块。每个模块完成一个特定的子功能。把这些模块结合起来组成一个整体。完成指定的功能,满足问题的要求。采用模块化原理的优点在于可以使软件结构清晰,容易测试和调试。从而提高软件的可靠性,可修改性。有助于软件开发的组织管理。一个大型软件可分别编写不同的模块。模块化理论的几个重要概念如下:
(1) 抽象
抽象就是抽象出事物的本质特性而暂时不考虑它们的细节。处理复杂系统唯一有效的方法是用层次的方式构造和分析它。一个复杂的动态系统首先可以用一些高级的抽象概念构造和理解,这些高级概念又可以用一些较低级的理解,直到最低层次的具体元素。
(2) 信息隐蔽和局部化
信息隐蔽是指在设计和确定模块时,应使得一个模块内包含的信息对于不需要这些信息的模块来说,是不能访问。
局部化是指把一些关系密切的软件元素物理的放得彼此靠近。局部化有助于实现信息隐蔽。
信息隐蔽原理和局部化有助于在测试期间以及软件维护期间修改软件。因为绝大多数数据和过程对于软件的其它部分而言是隐蔽的,从而由疏忽引入的错误就很少可能传播到软件的其它部分。
(3) 逐步求精的模块化概念
逐步求精和模块化的抽象是密切相关的。软件结构每一层中模块表示对软件抽象层次的次细化。用自顶向下,逐步求精的方法由抽象到具体的方式分配控制,简化了软件设计和实施,提高了软件的可理解性和可测试性,并使得软件更容易维护。
在软件的设计中应追求尽可能松散的耦合。内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展,理想内聚的模块只做一件事情。在设计时应力求做到高内聚。
1 界面设计友好、美观,数据存储安全、可靠。
2提供一个可游戏的平台
3用户可通过击杀敌机获得分数。
4用户可通过分数升级敌机
5 拥有用户菜单,执行系统功能。
6 提供一个选择模型的平台
7能正确获得用户提供的模型
8 有很好的数据处理能力。
本项目采用的是三层结构,分别为表示层,业务逻辑层,数据访问层,此模型使项目的结构更加清楚,分工更明确,有利于后期的更新升级和维护。
(1)表示层:提供对应用程序的访问,也叫界面层。本系统表示层实现统一的界面模板,主界面点击相应功能工具连接到各个子页面,使整个页面简洁,操作方便以及提高系统安全性及系统运行速度。
(2)游戏逻辑层:为实现游戏应用程序的逻辑功能,核心部分。
(3)数据访问层:为表示层或业务逻辑层提供数据服务,对所有数据操作进行封装。
经过对游戏的分析,将游戏分为四部分:开始菜单、模型选择、进行游戏、用户菜单。
图4-1 游戏功能划分
开始菜单可分为三部分:开始游戏、游戏说明、退出游戏。
图4-2 开始菜单
模型选择只有一个模块:模型选择。
进行游戏可分为四部分:任务升级、模型显示、碰撞检测、数据统计。
图4-3 进行游戏
用户菜单可分为三个模块:机体升级、返回游戏、退出游戏。
图4-4 用户菜单
飞行射击游戏提供了一个普通小游戏所拥有的一般功能和普通小游戏所没有的特殊功能的游戏平台。用户可根据自己的喜好去选择模型来进行游戏,并提供了游戏升级功能了和机体升级功能,使游戏更有趣味。游戏可以通过调整视角进行多角度的观察和游戏。
开始菜单有三个部分:开始游戏、游戏说明、退出游戏。
开始游戏是当用户选择此选项,则跳转到飞机模型选择界面。
游戏说明是对游戏的游戏方法,功能,以及一些细节作出说明,使用户更轻松的进行游戏。
退出游戏是当用户选择此选项,则清除游戏所有信息,退出游戏。
模型选择模块的功能是多角度展示模型库里的模型,用户可以通过多角度观察飞机模型来决定选择自己的模型,当用户选择了所要的模型时,则记录所选的模型信息。
进行游戏有四部分:任务升级、模型显示、碰撞检测、数据统计。
任务升级是当用户击毁敌机到达一定数量的时候,任务会自动升级,敌机的攻击力,生命等属性都会增加,随着任务等级的升高,敌机也会越来越厉害,击毁敌机所获得的分数也会越来越多。
模型显示是显示用户所选的模型,并提供一个多角度观察功能,使用户能通过不同角度来进行游戏。
碰撞检测是当用户发射子弹的时候所进行的检测。其检测用户是否攻击到了敌机,敌机是否攻击到了用户的机体,是游戏的根本。
数据统计是统计用户的分数,血量,机会,所使用的子弹,任务等级,敌机数量等多方面的数据。
用户菜单有三个模块:机体升级、返回游戏、退出游戏。
机体升级是用户可用击毁敌机所获得的分数来对飞机的一定速度,生命,子弹威力等进行修改升级。
返回游戏是用户退出用户菜单,返回到游戏当中继续游戏。
退出游戏是用户选择后,则退出整个游戏,返回开始菜单。
图4-5 模型编辑器功能划分
模型编辑器主要分成五部分:删除子模块、修改子模块、添加子模型、导出模块、改变观察视角。
模型编辑器是一个可供用户编辑自己喜好的飞机模型的游戏配套工具。
添加子模型是用户选定好所要添加的子模块时,将子模型添加到模型,整体显示给用户看。并将子模型插入到子模型列表中。
修改子模块是用户可以改变子模型的位置、大小、颜色、高度、宽度等属性。
删除子模块是将用户所选的子模型从子模型列表中删除。
改变观察视角是用户可以改变观察视角来观察自己所做的模型。
导出模块是将用户所选的所有子模型按照一定格式导出到模型文件当中,以便游戏中选择。
详细设计阶段的根本目标是确定应该怎样具体的实现所要求的系统,也就是说,经过这个阶段的设计工作,应该得出目标系统的精确描述,从而在编码阶段可以把这个描述直接翻译成用某种程序设计语言书写的程序。详细设计的目标不仅仅是逻辑上正确地实现每个模块的功能,更重要的是设计的处理过程应该尽可能简明易懂。
对于游戏,首先,由于游戏和编辑器的模型绘制需求,要设计好数据结构。并编写一个文件读写类,将数据结果的信息写入文件或从文件中读取出来。
接下来,设计一个很好的游戏规则。即用户通过控制机体击打敌机核心从而获得分数,用户可以将获得的分数进行对机体的升级。
为了更好的实现游戏,必须将对象抽象出来。所以,从中抽象了机体对象、火花对象和子弹对象。因为所有机体都有共同的属性,即位置、大小、旋转角度、速度、子弹威力、生命值等,也有共同的方法,即发射子弹、检测生命、继续前进等,所以所有机体都继承同一个对象。因为所有子弹都有共同的属性,即位置、大小、旋转角度、速度、生命值等,也有共同的方法,即检测生命、继续前进等,所以所有子弹都继承同一个对象。一个大火花对象,包含很多个小火花。而每一个小火花都有自己的生命、加速度方向、该方向的加速度等属性,也都有检测生命、继续前进等方法,所以每一个小火花都继承同一个火花对象,而一个大火花是由很多个小火花组成,所以一个大火花对象中有一个小火花对象数组来存储每一个小火花,并有一个爆炸方法每次都会没有结束生命的小火花进行跟新数据。
将对象抽象出来后,必须有相应的控制器去控制这些对象。因此,就制作了机体对象控制器、子弹对象控制器和火花对象控制器。这些控制器都是对其所控制的对象执行添加对象、检测生命、更新数据和删除对象。
为了提高绘制模型的效率,需要将所有模型在计算后统一绘制出来。因此,创建一个模型绘制类是必要的。该类的工作主要是在游戏开始使通过自定义数据结构的信息建立模型列表。然后根据传入的模型号,显示相应的模型。
为了提供用户一个对角度的观察视角,建立了一个世界控制类。改类通过监听用户对视觉的变换,而改变观察角度。并且显示世界环境,如整体游戏界面等。
游戏需要一个流程控制,去监听用户操作,并调用相关的类或方法,记录相关的信息。因此必须创建游戏控制类。
将所需要的类规划好后,接下来是画类图,将类的关系表示出来,以方便更好的实现这些类。
对于模型编辑器,除了一个通用数据结构外,还需要其他的类。
为了方便记录,将一个大模型划分为很多个子模型的组合。所以,需要创建一个子模型对象。该对象包括子模型的基本信息,即长、宽、高、位置、旋转角度、半径、名字等属性外,还包括对子模型的修改方法。
了提高绘制模型的效率,需要将所有模型在计算后统一绘制出来。因此,创建一个模型绘制类是必要的。该类根据传入的子模型的信息,绘制相应的模型。
为了提供用户一个对角度的观察视角,建立了一个世界控制类。改类通过监听用户对视觉的变换,而改变观察角度。并且显示世界环境,如整体游戏界面等。
游戏需要一个流程控制,去监听用户操作,并调用相关的类或方法,记录相关的信息。因此必须创建游戏控制类。
将所需要的类规划好后,接下来是画类图,将类的关系表示出来,以方便更好的实现这些类。
游戏开始菜单:
图5-1 游戏开始菜单界面
模型选择菜单:
图5-2 模型选择菜单界面
游戏进行:
图5-3 游戏进行界面
游戏说明:
图5-4 游戏说明界面
机体升级:
图5-5 机体升级界面
游戏需要展示给用户看和使用,所以必须创建一个窗口来实现这个功能。其包含三个函数LRESULT WINAPI MsgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam )消息处理函数。INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,INT )程序入口。void GameLoop()消息循环控制。
5.2.2 OpenGL窗口创建(OpenGL.h、OpenGL.cpp)
游戏需要一个特殊的窗口(OpenGL窗口)来显示通过OpenGL库函数创造出来的模型图形。该窗口包括函数SetupPixelFormat(HDC hDC0)检测安装OpenGL。函数init(int Width, int Height)根据传入的高度和宽度来初始化OpenGL窗口。Render()图形处理函数,在该函数中可编写需要显示的图形或界面。:CleanUp()清除OpenGL,当游戏结束时释放所有空间。
5.2.3游戏控制器(Contral.h、Contral.cpp)
游戏需要一个控制器来控制整个游戏的进行过程和事件处理。该类包括了根据用户的选择对相对应的类或方法进行调用的功能。对每个菜单定制一个标记,然后按照权重进行检测。通过监听用户的动作,就可知道用户所选择的菜单。
游戏执行是一个过程化的循环程序,通过不同的监听用户动作,来调用函数对对象进行操作。
5.2.4机体对象基本类(ObjData.h、ObjData.cpp)
该类是将机体对象抽象出来,以后的扩展机体只需要继承该类即可获得机体基本的方法和属性。该类包括了机体的速度,位置,模型号,子弹号,生命等属性。
5.2.5敌机对象类(ObjBaseData.h、ObjBaseData.cpp)
该类继承了机体对象基本类,并有自己特有的方法。敌机会自行随机出一个结束点,并不断的向该结束点前进。在一个随机的时间内发射子弹。
通过敌机对象控制器接收到的信息,敌机对象的信息进行修改。
敌机对象每次被检测时,自行检测是否结束生命,若结束生命则返回相应信息,不再进行然和判定。
敌机对象自行检测是否到达结束点,若没有到达结束点测继续前进。若到达结束点则判断是否超出视觉界限,若超出,则返回销毁信息。若没有超出,则随机产生一个结束点。
5.2.6敌机对象控制器(AiObj.h、AiObj.cpp)
该类包含了对敌机的基本控制。其中有根据任务升级数控制敌机出现的数量,对已被击毁的敌机的销毁。并将敌机产生出来的子弹插入到子弹列表中。
每次执行,都判断对象列表中的对象是否该结束生命。若结束生命,则将该敌机对象从对象列表中删除。
否则判定敌机是否开火,若开火则将子弹对象加入到子弹列表中。
进行相应的判定后,调用敌机对象继续向结束点前进。
5.2.7战机对象控制器(SelfObj.h、SelfObj.cpp)
该类包含了用户对战机操作的各种响应。监听用户对战机的操作,如方向,开火,更改战机参数等。并将战机产生出来的子弹插入到子弹列表中。
每次执行,都判断对象列表中的对象是否该结束生命。若结束生命,则返回销毁信息给游戏控制器。
接收游戏控制器传送过来的用户的操作,对位置、方向、子弹号等信息进行修改。
5.2.8子弹对象类(BulletObj.h、BulletObj.cpp)
包含了子弹的基本属性和方法。如位置,方向向量,威力等属性。自我判定销毁,向方向向量前进等方法。
每次执行,都判断对象列表中的对象是否该结束生命。若结束生命,则返回销毁信息。
5.2.9子弹对象控制器(BulletMenager.h、BulletMenager.cpp)
对子弹进行控制。包括子弹列表,将传入的子弹插入子弹列表,清楚已结束生命的子弹,对子弹列表进行排序等属性和方法。
每次执行,都判断对象列表中的对象是否该结束生命。若结束生命,则将该对象从对象列表中删除。
5.2.10文件读取控制器(FioMenager.h、FioMenager.cpp)
用于读取用户定义的模型读取、游戏中所要使用的纹理读取。
根据自定义数据结构,从模型文件中读取模型的信息。
5.2.11文字显示类(CGLFont.h、CGLFont.cpp)
用于显示所输入的字符或文字。包括平面文字,3D文字、图片文字等多种文字显示方法。
类开始时先初始化基本文字,然后获取游戏控制器的信息,从文件读取控制器中获取相应纹理的信息,根据游戏控制器的信息对字进行定位和大小设置,然后显示文字。
5.2.12火花对象类(Grain.h、Grain.cpp)
用与对火花的控制。自动产生环境变量和每个火花点的生命、方向、方向加速度、颜色等。每个火花都有自己的生命周期,每次产生的火花都不相同。
若所有火花的生命周期都结束的,则返回销毁信息。
5.2.13火花对象控制器(GrainMenager.h、GrainMenager.cpp)
对子火花行控制。包括火花列表,将传入的火花插入火花列表,清除已结束生命的火花。
控制器先检测火花是否结束生命,若结束生命则将该火花对象从对象列表中删除。
对于没有结束生命周期的火花,进行火花的循环,每次都调用火花的更新函数对火花的信息进行更新。然后显示火花。
5.2.14碰撞检测(Hitexamina.h、Hitexamina.cpp)
对输入的对象和子弹列表进行碰撞检测。根据子弹的方向向量判定子弹时候穿过对象、击中对象。若击中对象,则产生一个火花,传入到火花对象控制器中,若没有击中,则继续循环。
5.2.15模型控制器(modeMenager.h、modeMenager.cpp)
对文件中传入的模型数据进行模型生成,并产生一个模型列表。显示时根据所传入的模型号在列表中找出该模型并进行显示。控制器中还包括对环境的显示,对视角变换的控制等。
图5-6 游戏类图
图5-7 模型编辑器界面
5.3.1MFC窗口(CMakeFlyModeDlg.h、CMakeFlyModeDlg.cpp)
包含了面向用户的所有界面显示,监听用户对窗口的操作。
5.3.2OpenGL窗口创建(OpenGL.h、OpenGL.cpp)
编辑器需要一个特殊的窗口(OpenGL窗口)来显示通过OpenGL库函数创造出来的模型图形。该窗口包括函数SetupPixelFormat(HDC hDC0)检测安装OpenGL。函数init(int Width, int Height)根据传入的高度和宽度来初始化OpenGL窗口。Render()图形处理函数,在该函数中可编写需要显示的图形或界面。:CleanUp()清除OpenGL,当游戏结束时释放所有空间。
5.3.3子模型管理(BaseGraphics.h、BaseGraphics.cpp)
对用户选择的模型插入子模型列表,并获取用户的操作,对子模型进行更改、删除等工作。提供一个对角度的摄像漫游。
根据MFC窗口传入改变子模型的信息,调用激活的子模型的大小、长宽、旋转等函数,对子模型的信息进行修改。
5.3.4子模型类(GraphicsObj.h、GraphicsObj.cpp)
存储子模型的相关信息,并提供更改子模型的方法。
其中包含自定数据结构。
5.3.5文件存取控制器(FioMenager.h、FioMenager.cpp)
将子模型列表中的所有子模型的相关信息写入到文件中。
根据自定义数据结构,将数据结构的数据和信息写入文件中。
图5-8 模型编辑器类图
为了让游戏能绘制出用户定义的模型,所以要采用一个自定义的数据结构。
为了更好的记录模型数据,所以将一个大模型划分未一个或几个子模型,子模型是基本形状,包括立方体、球体、圆锥体等,每个子模型都有其独有的名字。
结构包括子模型的个数。然后是一个子模型列表,其中包含了子模型个数的子模型信息。信息中包括子模型的名字、长、宽、高、半径、外半径、X轴旋转角度、Y轴旋转角度和Z轴旋转角度。
模型编辑器将这个数据结构写入到文件,游戏则按照数据结构的格式从文件中读取模型信息。
这样就能实现游戏可绘制编辑器编辑出来的模型。
6 测试与维护
表6-1 测试安排表
测试项目 | 测试人 | 测试时间 | 预期结果 | 实际结果 |
游戏开始菜单 | 陈鹏 | 2009-4-5 | 正确显示开始菜单 | 与预期结果一致 |
游戏游戏说明 | 陈鹏 | 2009-4-7 | 正确显示游戏说明 | 与预期结果一致 |
游戏退出游戏 | 陈鹏 | 2009-4-7 | 成功退出游戏 | 与预期结果一致 |
游戏模型导入 | 陈鹏 | 2009-4-10 | 正确导入文件,并显示正确的模型 | 与预期结果一致 |
游戏模型选择 | 陈鹏 | 2009-4-11 | 正确记录和显示用户选择的模型 | 与预期结果一致 |
游戏视觉控制 | 陈鹏 | 2009-4-13 | 能多角度观察世界 | 与预期结果一致 |
游戏界面显示 | 陈鹏 | 2009-4-13 | 正确显示用户界面 | 与预期结果一致 |
游戏碰撞检测 | 陈鹏 | 2009-4-15 | 正确判定子弹碰撞,并减少被碰撞的机体的生命 | 与预期结果一致 |
游戏数据统计 | 陈鹏 | 2009-4-18 | 正确统计所有数据 | 与预期结果一致 |
游戏机体升级 | 陈鹏 | 2009-4-20 | 根据玩家的升级数据,升级机体 | 与预期结果一致 |
编辑器添加模型 | 陈鹏 | 2009-4-25 | 按照用户选择添加子模型 | 与预期结果一致 |
编辑器修改模型 | 陈鹏 | 2009-4-28 | 按照用户选择修改子模型 | 与预期结果一致 |
编辑器删除模型 | 陈鹏 | 2009-5-1 | 按照用户选择删除子模型 | 与预期结果一致 |
编辑器导出模型 | 陈鹏 | 2009-5-2 | 将模型正确写入文件中并能被游戏识别 | 与预期结果一致 |
编辑器视觉变换 | 陈鹏 | 2009-5-2 | 按照用户要求变换观察角度 | 与预期结果一致 |
1.测试的目的是为了发现程序中的错误而执行程序的过程。
2.好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
3.成功的测试是发现了到今为止尚未发现的错误的测试。
设计测试方案是测试阶段的关键技术问题。所谓测试方案包括预定要测试的功能。应该输入的测试数据和预期的结果,目标是设计一组可能发现错误的数据。测试有两种方法:黑盒测试和白盒测试。
黑盒测试又称为功能测试,在程序接口进行,只检查程序功能是否能够按照规格说明书的规定正确使用,程序是否能适当地接收输入数据并发生正确的输出信息,而且要能够保持外部信息的完整性。
白盒测试又叫结构测试,完全了解程序的结构和处理过程,这种方法按照程序内部的逻辑测试程序,检验程序中每条通路是否都能按照预定要求正确工作。
本系统开发过程进行的测试步骤如下:
也叫单元测试,目的是保证每一个模块作为一个单元能正确运行,本测试所发现的往往是编码和详细设计的错误,主要评价模块的下述五个特点:
1.模块接口; 2.局部数据结构;
3.重要的执行路径; 4.出错处理通路;
5.影响上述各方面特性的边界条件。
模块测试主要由代码审查和软件测试两部分组成。
包括系统测试和子系统测试。集成测试是组装软件的系统技术,主要目标是发现与接口有关的问题。集成测试有两种方法:非渐增式和渐增式,但比较而言,渐增式方法比较好,因为:
编写的测试软件较少,开销较小。
较早地发现模块间的接口错误。
错误位置容易判断。
测试更彻底。
因此,本系统集成测试采用渐增式测试中的混合法,即对软件结构中较上层使用自顶而下的测试方法,而对软件结构中较下层,使用的是自底向上方法,两者结合,这是对模块较多时测试的一种折衷方法。
这一步是验证软件的有效性。目的是向未来的用户表明系统能够象预定的那样工作,验收测试一般使用黑盒测试法,验收测试有两种可能的结果。
1.功能和特性与用户的要求有差距。
2.功能和性能与用户要求一致,软件是可以接受的。
这个阶段发现的问题往往和需求分析阶段的差距有关。
所谓平行运行就是同时运行。新开发出来的系统和将被它取代的旧系统,以便比较新旧两个系统的处理结果。目的有:
1.可以在准生产环境中运行新系统而有不冒风险;
2.用户能有一段熟悉新系统的时间;
3.可以验证用户指南和使用手册之类的文档;
4.能够以准生产模式对新系统进行全负荷测试,可以用测试结果验证性能指标。
6.3系统维护
软件维护是软件生命周期的最后一个阶段,处于系统投入生产性运行以后的时期中,所谓软件维护就是在软件已经交付使用之后,为了改正错误或满足新的需要而修改软件的过程。软件的维护有适应性维护;完善性维护;改正性维护;预防性维护。
本系统为适应维护的需要,采用如下措施:
1.软件配置程序源代码;
2.开发过程文档齐全;
3.设计过程中各模块均考虑或预留完整性和可维护性接口等部分。
4.本软件的模块化,详细设计的文档、源代码内部的文档有详细说明、注释均可提高可维护性;
5.尽量松散〈低偶合〉,高内聚。
一般的游戏,只提供了一个游戏平台,不管游戏做得如何,模型做得如何,用户都无法改动。以至于不能很好的吸引用户。
本游戏针对这一方面的问题,自行开发了一个模型编辑器,这个编辑器制作出来的模型,能正确的被游戏所识别。因此,用户可以通过使用编辑器来编辑自己喜欢的模型,然后加载到游戏当中去。而且使用简单、方便、快捷。
游戏还有一个机体升级功能。用户可以通过击毁敌机来获得分数,然后在机体升级里对自己制作的模型飞机进行速度、生命、子弹威力等机体性能进行维修升级。完全满足用户的需求。
真正好的游戏,不单单是画面和游戏性能的好,更多的是让用户通过游戏,拥有自己的东西,那才能更大的满足用户。本游戏提供了一个模型编辑器,让用户拥有自己的模型,使游戏更有乐趣。
游戏编写采用面向对象思想,将相同性质的对象抽象出来。大大降低耦合度。
在模型制造与导入导出的代码编写中,重载了多个函数,提高了代码的重用性。
游戏的一大亮点是碰撞检测与火花制作。
碰撞检测:传入攻击对象列表和被攻击对象列表,根据攻击对象的方向向量来判定攻击方向,然后判定攻击对象是否撞击到被攻击对象或穿过被攻击对象。为提高效率,使游戏获得更好的性能,并降低时间复杂度,在碰撞检测前,先对攻击对象进行线性路程排序,即同一方向的攻击对象进行路程降序排序,若路程远的攻击对象未攻击到被攻击对象或未穿过被攻击对象,则路程近的攻击对象不必再进行碰撞检测,直接结束检测。
火花制作:一个大火花是由很多个小火花组成,每个小火花初始化时都有自己的生命周期,加速度方向,和该方向的加速度力量、颜色、纹理。每个火花都会因为环境变量的不同产生不同的效果。根据环境的各个方向的阻力、重力情况发生改变。因此,该火花系统还可以做成云、喷泉、雨等不同的粒子效果。通用性很强
[1]谭浩强:《C++程序设计》[M].第1版. 清华大学出版社,2004.6
[2]朱少民:《软件测试方法和技术》[M].第1版. 清华大学出版社,2005.7
[3]施瑞奈尔:《Open GL编程指南》[M].第7版. 机械工业出版社,2010.3
[4]安吉尔:《OpenGL编程基础》[M].第3版. 清华大学出版社,2008.7
[5]安杰尔:《OpenGL程序设计指南》[M].第2版. 清华大学出版社,2005.5
[6]李普曼:《C++ Primer中文版》[M].第4版. 人民邮电出版社,2008.7
[7]侯俊杰:《深入浅出MFC》[M].第1版. 华中科技大学出版社,2001.1
[8]董建明:《人机交互:以用户为中心的设计和评估》.第1版. 清华大学出版社,2003.9
[9]张海藩:《软件工程导论》[M].第4版.北京:清华大学出版社,2005.7
[10]韩万江:《软件项目管理案例教程》[M].第1版. 机械工业出版社,2008.4
[11]汤庸:《软件工程方法与管理》[M].北京:冶金工业出版社,2006.1
[12]黄敬仁编著:《系统分析》[M],清华大学出版社,2005.8
OpenGL类代码:
BOOL OpenGL::SetupPixelFormat(HDC hDC0)//检测安装OpenGL
{ int nPixelFormat; // 象素点格式
hDC=hDC0;
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
16, // 24 位颜色深度
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累加缓存
0, 0, 0, 0, // 忽略累加位
16, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
{ MessageBox(NULL,"没找到合适的显示模式","Error",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
SetPixelFormat(hDC,nPixelFormat,&pfd);//设置当前设备的像素点格式
hRC = wglCreateContext(hDC); //获取渲染描述句柄
wglMakeCurrent(hDC, hRC); //激活渲染描述句柄
m_Contral = new CContral();
return TRUE;
}
void OpenGL::init(int Width, int Height)
{
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glViewport(0,0,Width,Height); // 设置OpenGL视口大小。
glMatrixMode(GL_PROJECTION); // 设置当前矩阵为投影矩阵。
glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵
gluPerspective // 设置透视图
( 54.0f, // 透视角设置为 45 度
(GLfloat)Width/(GLfloat)Height, // 窗口的宽与高比
0.1f, // 视野透视深度:近点1.0f
3000.0f // 视野透视深度:始点0.1f远点1000.0f
);
// 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。
/*
glShadeModel(GL_SMOOTH);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glMatrixMode(GL_MODELVIEW); // 设置当前矩阵为模型视图矩阵
glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵*/
//====================================================
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND); // Enable Blending
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Type Of Blending To Perform
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // Really Nice Perspective Calculations
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); // Really Nice Point Smoothing
glMatrixMode(GL_MODELVIEW); // 设置当前矩阵为模型视图矩阵
glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵
}
void OpenGL::Render()//OpenGL图形处理
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 设置刷新背景色
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景
glLoadIdentity(); // 重置当前的模型观察矩阵
if (m_Contral->EndMark)
{
CleanUp(); // 结束处理
PostQuitMessage(0);
}
else
{
if (m_Contral->IlluminateMark)
m_Contral->IlluminateGame();
else
{
if (m_Contral->BeginMark)
{
if (m_Contral->SelectModeMark)
{
if (m_Contral->checkChance())
{
if (m_Contral->GameOver())
{
m_Contral->renewAll();
}
}
else
{
if (m_Contral->IsGameMenu())
{
if (m_Contral->IsUpDate())
{
m_Contral->UpDateSelf();
}
else
m_Contral->GameMenuList();
}
else
{
m_Contral->CheckGameMenu();
m_Contral->GameGo();
}
}
}
else
{
m_Contral->selectMode();
}
}
else
{
m_Contral->Menu();
}
}
}
//m_Contral->GameGo();
//bm->Show();
glFlush(); // 更新窗口
// glutSwapBuffers();
SwapBuffers(hDC); // 切换缓冲区
}
void OpenGL::CleanUp()//清除OpenGL
{
wglMakeCurrent(hDC, NULL); //清除OpenGL
wglDeleteContext(hRC); //清除OpenGL
}
碰撞检测代码:
bool Hitexamina::HitTest(BulletObj *BulletObj , vector<ObjBaseData> *ObjList)
{
if (ObjList->empty())
{
return false;
}
try
{
IsOver = false;
bool IsHit = false;
vector<ObjBaseData>::iterator it;
Point op , bp , bp2;
float w , l , h , vz;
for (it = ObjList->begin(); it != ObjList->end() ;it ++)
{
IsHit = false;
///计算射击子弹点坐标
vz = BulletObj->v[2];
op.x = it->ob.x;
op.y = it->ob.y;
op.z = it->ob.z;
bp.x = BulletObj->x;
bp.y = BulletObj->y;
bp.z = BulletObj->z;
bp2.x = BulletObj->v[0] * BulletObj->speed - BulletObj->x;
bp2.y = BulletObj->v[0] * BulletObj->speed - BulletObj->y;
bp2.z = BulletObj->v[0] * BulletObj->speed - BulletObj->z;
w = CoreData[it->ob.ListNum].Wid;
l = CoreData[it->ob.ListNum].Long;
h = CoreData[it->ob.ListNum].Hight;
///判断子弹是否到达
if (vz > 0 )
{
if (bp.z >= (op.z - l / 2.0f))
{
IsOver = true;
IsHit = true;
}
}
else
{
if (bp.z <= (op.z + l / 2.0f))
{
IsOver = true;
IsHit = true;
}
}
if (bp.x >= (op.x - w / 2.0f) &&
bp.x <= (op.x + w / 2.0f) &&
bp.y >= (op.y - h / 2.0f) &&
bp.y <= (op.y + h / 2.0f))
{
if (bp.z >= (op.z - l / 2.0f) && bp.z <= (op.z + l / 2.0f) ///在核心内
||
bp.z > op.z && bp2.z < op.z ///穿过
||
bp.z < op.z && bp2.z > op.z ///穿过
)
{
撞击后
fd = new fireData();
fd->x = bp.x;
fd->y = bp.y;
fd->z = it->ob.z;
fd->size = 1;
it->ob.life -= BulletObj->power;
BulletObj->life = 0;
return true;
}
}
}
return false;
}
catch(...)
{
MessageBox(NULL ,"碰撞检测" , NULL , MB_OK);
}
return false;
}
值此毕业论文完成之际,不管毕业设计的最终成果如何,我都要感谢在这一路走来,给予我无私帮助的老师和同学们:
我要感谢我的指导老师章远老师,因为在我做毕业设计的过程当中,他负责任的指导和建议使我受益非浅,无论在学习上还是在精神上都给予了帮助,这些帮助和鼓舞对我而言是一笔财富,它一直鞭策着我认真的完成毕业设计,而且也让我在面对人生的设计舞台时同样充满了信心。在老师的帮助下,不仅学到了许多宝贵的理论知识和实践经验,还受到了勇于探索、严谨治学高贵品质的熏陶。这些对我今后的工作和生活都将起到重要的作用。
最后,我再次深深的感谢帮助我的人。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。