摘要:随着现今经济及计算机多媒体技术的飞速发展,计算机游戏日益受到人们的亲睐,成为人们生活中重要的组成部分。目前纷繁复杂的计算机游戏,多由单机版游戏发展而来,学习简单的单机版游戏制作,有益于加深对计算机游戏的制作理念的理解,也将有益于今后参加更加复杂的项目。
本游戏采用软件工程的方法,以Visual C++ 6.0作为系统应用程序开发工具,以MFC中对话框为程序基础,使用文本文件贮存相关数据,并使用C语言中的文本操作语句对文本文件进行相关操作。游戏程序采用多对话框结构,其中包括游戏界面对话框,登录对话框,充值对话框,以及提示对话框。
关键词:游戏; Visual C++
Abstract:Today as the rapid development of economic and computer multimedia technology, computer game is more than popular and become an important element of our life. Although there are varied kinds computer games, most of them are devolved from Standalone Games. So Standalone Games is a good starting point for beginner to get a better understanding of computer game technology, which will build a good foundation for more complex project development.
Using software engineering methodology, this game is developed with MFC frame work under Visual C++ 6.0. All the data maintenances are based on file operations. This game are based on multi-dialog, the dialogs include main window dialog, login dialog, paying dialog, etc.
Keywords: Games; Visual C++
前 言
随着经济及计算机多媒体技术的飞速发展,计算机游戏日益受到人们的亲睐,成为人们生活中重要的休闲娱乐方式。目前纷繁复杂的游戏软件,多由单机版游戏发展而来,学习简单的单机版游戏制作,有益于加深对游戏软件制作理念的理解,也将有益于今后参加更加复杂的项目。
目前不论是在我国,还是在世界范围内,游戏产业都在蓬勃发展,越来越多更具娱乐性的游戏被开发出来,这其中游戏开发工具的发展进步功不可没。在众多的游戏开发工具中,Microsoft的Visual C++ 系列被认为是当今世界最强大的游戏开发软件,其代表作: “Diablo 暗黑破坏神 系列”、“魔兽争霸系列”、“星际争霸系列”、“模拟人生系列”、“帝国时代系列”等等等等,几乎所有的大作都有VC的功劳。因此掌握了VC的应用,不但是掌握了一种优秀的开发工具,对于今后参加大型团队的游戏项目开发也具有一定的帮助。
本设计通过开发一个单机版的基于Visual C++的点歌游戏,使其拥有一定的多媒体功能,有一定的市场适应能力,及一定的娱乐性很值得一试。通过制作这样一个软件,可以加深对游戏设计思想的了解,也可以进一步熟悉编程工具的应用,更可以给我们的生活带来更多的趣味。在设计过程中,通过Visual C++开发一个基于对话框的程序,不同对话框实现不同功能,通过在对话框之间的切换来完成用户的身份认证,选择继续,以及退出游戏等功能。
通过该设计,我将更好的了解windows消息机制,更深的体会到利用Visual C++/MFC开发windows程序的优越性。
第一章 前言
1 VC++概述
VC++是微软公司开发的一个IDE(集成开发环境),换句话说,就是使用c++的一个开发平台.有些软件就是这个编出来的...另外还有VB,VF.只是使用不同语言...但是,VC++是Windows平台上的C++编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。 VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VC++不是门语言,虽然它和C++之间有密切的关系,如果形象点比喻的话,可以C++看作为一种”工业标准”,而VC++则是某种操作系统平台下的”厂商标准”,而”厂商标准”是在遵循”工业标准”的前提下扩展而来的。
VC++应用程序的开发主要有两种模式,一种是WIN API方式,另一种则是MFC方式,传统的WIN API开发方式比较繁琐,而MFC则是对WIN API再次封装,所以MFC相对于WIN API开发更具备效率优势,但为了对WINDOWS开发有一个较为全面细致的认识,笔者在这里还是以讲解WIN API的相关内容为主线。
1.1 C++语言的特点与发展:
为了解决在面向过程的软件设计过程中遇到的软件设计危机,上世纪80年
代提出了面向对象的程序设计(Object Oriented Programming,OOP)。AT&T Bell实验室的 Bjarne Stroustrup博士及其同事于20世纪80年代初在C语言的基础上发明了C++(C Plus Plus)语言。C++保留了C语言的所有优点,增加了面向对象的机制。C++面向对象编程语言具有如下4个基本特征:
抽象。抽象是忽略一个主题中与当前目标无关的那些方面,以便更充分地注
意与当前目标有关的方面。抽象并不打算了解问题的全部,而只是选择其中的一
部分。比如要编写一个学生成绩管理系统,考察学生这个对象时,我们只关心他所在的班级,学号,成绩等,而不用关心他的身高、体重等信息。
封装。封装把描述事物的数据和行为包裹起来,形成一个独立的抽象数据类型—类。封装并不等于完全封闭,类通过Private,Protected,Public访问限制符使自身的数据和行为有限制地对外公开。
继承。继承非常好地提供了代码地可重用性,体现了客观现实世界中一般与特殊地关系。
多态。多态性指允许不同的类的对象对同一消息自动作出不同的响应。多态性提高了代码的可重用性和可扩展性。 1.2 C++版本变迁:
带类的C(1979-1983)
从带类的C到C++(1982-1985),在原有带类的C基础上扩充了6种特征:虚
函数、函数名和运算符重载、引用机制、常量const、用户对自由存储的控制、改进了的类型检查、注释表示的多样化。
C++2.0版(1985-1989)。1989年推出的C++2.0版本增加了如下的新特征:多
重继承、抽象类、静态成员函数、const 成员函数、protected成员函数、运算符重载、成员指针、赋值和初始化的递规定义、对一些特征又做了改进、重载分辨、类型完全连接、用户自定义递内存管理设施。此时各大公司相继退出C++2.0的编译器。1990年5月Borland推出Borland C++,1992年Microsoft推出Microsoft C++,DEC,IBM也于1992年推出了自己的C++。
C++3.0(1993)。C++3.0扩充了模版。
标准化(1998)。1989年后C++开始形成热潮,同时也要求尽快标准化。1989
年,由HP公司联合AT&T,DEC,IBM等公司发起建议标准化。为此,美国国家标准局成立了C++语言标准化小组X3J16,于1989年12月召开了第一次会议。1991年6月国际标准化组织ISO也为C++成立了WGI委员会,第一次会议载瑞典召开。1995年4月,ISO发行了最初的草案,以供公众评论。1998年7月10日终于通过了编号为ISO/IEC 14882的C++程序设计语言正式标准,改ISO标准同时也是ANSI的正式标准。
1.3 MFC和VC++
MFC,微软基础类(Microsoft Foundation Classes),实际上是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个辅助软件开发包,MFC作为与VC++血肉相连的部分(注意C++和VC++的区别:C++是一种程序设计语言,是一种大家都承认的软件编制的通用规范,而VC++只是一个编译器,或者说是一种编译器+源程序编辑器的IDE,WS,PlatForm,这跟Pascal和Dephi的关系一个道理,Pascal是Dephi的语言基础,Dephi使用Pascal规范来进行Win下应用程序的开发和编译,却不同于Basic语言和VB的关系,Basic语言在VB开发出来被应用的年代已经成了Basic语言的新规范,VB新加的Basic语言要素,如面向对象程序设计的要素,是一种性质上的飞跃,使VB既是一个IDE,又成长成一个新的程序设计语言),MFC同BC++集成的VCL一样是一个非外挂式的软件包,类库,只不过MFC类是微软为VC++专配的。
MFC是Win API与C++的结合,API,即微软提供的WinOS下应用程序的编程语言接口,是一种软件编程的规范,但不是一种程序开发语言本身,可以允许用户使用各种各样的第三方(如我是一方,微软是一方,Borland就是第三方)的编程语言来进行对Win OS下应用程序的开发,使这些被开发出来的应用程序能在WinOS下运行,比如VB,VC++,Java,Dehpi编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在WinOS的消息机制和绘图里,遵守WinOS作为一个操作系统的内部实现,这其实也是一种必要,微软如果不提供API,这个世上对Win编程的工作就不会存在,微软的产品就会迅速从时尚变成垃圾,上面说到MFC是微软对API函数的专用C++封装,这种结合一方面让用户使用微软的专业C++ SDK来进行Win下应用程序的开发变得容易,因为MFC是对API的封装,微软做了大量的工作,隐藏了好多程序开发人员在Win下用C++ & MFC编制软件时的大量内节,如应用程序实现消息的处理,设备环境绘图,这种结合是以方便为目的的,必定要付出一定代价(这是微软的一向作风),因此就造成了MFC对类封装中的一定程度的的冗余和迂回,但这是可以接受的。
第二章 相关介绍和准备工作
2.1 开发环境及运行环境
2.1.1 开发环境
Intel® Pentium® 4 2.0GHz,512M内存,80G硬盘 Microsoft® Windows™ 2000 Professional Microsoft® Visual C++ 6.0
Microsoft® Developer Network for Visual Studio.NET 2008 Visual Assist X 10.1.1301.0 2.1.2 运行环境
Intel® Pentium® 2及以上处理器,32M以上内存,4G以上硬盘 Microsoft® Windows™ 9X/NT操作系统 800*600或以上的屏幕分辨率
2.2计算机图形学方面的知识
2.2.1基本的C作图方法及主循环控制模块
Turbo C提供了非常丰富的图形函数,所有的图形函数的原型均建立在graphics.h中,在使用图形函数时要确保有显示器图形驱动程序*.BGI,同时将集成开发环境Options/Linker中的Graphics lib选为on,只有这样才能保证正确使用图形函数。
这个程序调用一个EGA、VGA显示器下能独立图形运行的函数。所谓独立图形运行程序,就是在编译和连接时将相应的驱动程序(*.BGI)直接装入到执行程序,从而能在独立的计算机上运行,避免需要重新编译连接才能运行。Turbo C进行画点、画线、封闭图形填充以及图形下文本输出只需要调用graphics.h中相关的函数。主循环控制模块:控制下棋顺序,当轮到某方下子时,负责将程序转到相应的模块中去,主要担当一个调度者的角色。这个五子棋程序是用键盘控制下棋,所以要用到Turbo C中的bios.h。在一个循环块中等待键盘信息,判断键盘所输入的信息是否需要响应,调用相关的代码进行下棋。
2.2.2图形模式下的文本输出
在C语言的图形模式下,只能用标准输出函数,如printf(),puts(),putchar()函数输出文本到屏幕。除此之外,其它输出函数(如窗口输出函数)不能使用,即是可以输出的标准函数,也只以前景色为白色,按80列,25行的文本方式输出。
Turbo C2.0也提供了一些专门用于在图形显示模式下的文本输出函数。下面将分别进行介绍。 一、文本输出函数 void far outtext(char far *textstring);
该函数输出字符串指针textstring所指的文本在现行位置。 void far outtextxy(int x, int y, char far *textstring);该函数输出字符串指针textstring所指的文本在规定的(x, y)位置。其中x和y为象元坐标。说明: 这两个函数都是输出字符串,但经常会遇到输出数值或其它类型的数据,此时就必须使用格式化输出函数sprintf()。sprintf()函数的调用格式为: int sprintf(char *str, char *format, variable-list); 它与printf()函数不同之处是将按格式化规定的内容写入str 指向的字符串中,返回值等于写入的字符个数。例如: C110F1sprintf(s, \"your TOEFL score is %d\这里s应是字符串指针或数组,mark为整型变量。
第三章 游戏实现
3.1游戏规则
迷宫(maze)是一个矩形区域,它有一个人口和一个出口。在迷宫的内部包含不能穿越的墙或障碍。在图1所示的迷宫中,障碍物沿着行和列放置,它们与迷宫的矩形边界平行。迷宫的人口在左上角,出口在右下角。假定用nxm的矩阵来描述迷宫,位置(1,1)表示人口,(n,m)表示出口,n和m分别代表迷宫的行数和列数。迷宫中的每个位置都可用其行号和列号来指定。在矩阵中,当且仅当在位t(i,j)处有一个障碍时其值为1,否则其值为O。图2给出了图1中迷宫对应的矩阵描述。迷宫 (花tinamaze)要求寻找一条从人口到出口的路径。路径是由一组位置构成的,每个位置上都没有障碍,且每个位里(第一个除外)都是前一个位置的东、南、西或北的邻居(如图3所示)。
3.2编程要求
1.在窗口中画出初始时迷宫的状态,迷宫随机生成,并验证其合法性(可以通行的迷宫)。
2.在自动寻找迷宫路径的每一步,用图形标示其状态。
3.自动寻找迷宫路径可以通过定时器或多线程的方法,每一步的时间间隔可以自定,以人眼观察比较舒服为宜,每一步的过程如能实现动画最好。 4.定义迷宫的描述类。
5.在程序中,迷宫的大小及每步移动的时间间隔可以通过对话框设置(也应该有默认值)。
6.支持暂停功和继续的功能(在自动寻径过程中可以暂停,并继续)。 7.暂停后,可以将当前的状态保存。
8,可以从7中保存的文件中读出某个状态,并继续。根据要求迷宫的数据应用矩阵来存放。对于路径的寻找采用堆栈来遍历整个迷宫矩阵。只要求找到一条路径即可,从而降低了算法设计的难度。该题目要求能随时停止寻找,并将当前的状态保存,并在下次载人进度继续寻找。为了满足该要求,只能降低迷宫类的封装性,将寻找路径的代码拿到类的外部来实现。这样迷宫类的功能就成为存放迷宫矩阵的数据及相关的参数,如行数、列数等。进度的存取用到的MFC的序列化。
3.3算法的设计
该算法用到了一个堆栈CeUStack。它的是用来保存已经到过的单元。每个单元用一个Cell结构来描述。其中含有该单元所处的位置,其上、下、左、右四个位置哪些是可行的,哪些是障碍,以及该单元是否为障碍等。该结构的描述在文件“cen.h”中。设当前位于第y行,第x列的单元中(当然该单元是可行的)。先判断当前位置是否为迷宫的左下角,即第n列,第m行。若不是,则按下面的规则寻长可能的路径。由于规定了迷宫的人口在左上角,出口在右下角,所以寻找的顺序选为右、下、左、上。按照该顺序试探当前单元的四个方向的单元,当发现一个可行的单元后,将当前的单元放入堆栈中,将下一个可行的单元放入当前位置pos--now;若寻找了一圈没有可行的单元(实际上是三个方向,因为来的方向一定是可行的,否则是不会到达当前单元的。但来路已被放人堆栈中,为了防止程序进人恶性循环,在到达当前位置时,就将来时的方向设置为不可行)。则放弃该位置,从堆栈中弹出上一个位置。弹出一个元素后,应检查堆栈是否为空。若为空,则说明当前位置为人口位置。此时查看该位置的右、下两个位置是否可行,若不可行,则说明所有的可行位置已被试探过了,没有可行的通路,此时即可停止循环。此时说明该矩阵是不合法的(即没有通路的)。若当前位置不是入口,再按上面的方法寻找可行的路径。该算法的程序流程图如图l所示。在程序的实现上,我设计了迷宫类CMaze。该类的作用主要是保存迷宫矩阵的数据及相关参数。迷宫的表示为:矩阵中值为0的位置为障碍,非0的位置为可行的。该类中的矩阵为一个二维数表,但在C++中并没有针对二维数据结构的理想的数据类型。当然
二维数组是一个选择,但其动态生成和维护不是很容易。因此我选择了使用线性表来表示二维表的方式。线性表中的alk]的k同二维表中的blm,n]中的m、n的对应关系为:
k=n*Colsize+m
这样在类中的矩阵保存为线性表,之后为该类定义两个函数GetAt(intRow,intCol)和SetAt(eelldata,intRow,intCol)。这两个函数用来提取和保存第Row行,第Col列的元素。这样使用起来就同二维表一样,而数据的维护却变得轻松了。迷宫的四个边在写程序时不象中间的位置那样容易判断。因此在迷宫矩阵的四周各加上一行(列)O元素表示障碍,这样迷宫中的各位置都可以用同一方式来判断了。Cell结构中的direction[4]就是用来存放四个方向上的位置中哪些是可行的。如direction[0]=l说明当前位置的右侧的位置可行,若direction[1]=O,说明当前位置的下方的位置不可行。由于题目要求矩阵随机生成,所以其构造函数只要两个参数:矩阵的行和列。当指定了行和列数后,自动将行和列各加2(在四周各加一行/列)。
m_TotalRow=Row+2: m_TotalCofulmn=Column十2;
之后分配m_TotalRow*m_Tota1Column个单元。将第一行、第一列、最后一行、最后一列赋成O。之后将其它位置的值赋成随机数,这样就随机生成了一个迷宫矩阵。但由于当0和l为等概率时,成生的迷宫很难存在通路,因此将O(障碍)的概率降低一些,这样的迷宫矩阵比较容易有通路。所以使用以下代码:
If(rand()>12000)
pMatrix[i*Tota1Column+j].mode=1; else
pMatrix[i*Tota1Column+j].mode=0;
其中rand()产生的随机数为0一32767,当大于12000时,l和0的概率比大约为2比1。
有了迷宫描述类,下一步就是写寻找迷宫路径的代码了。题目要求可视化的效果,因此采用定时器来控制步速。定时器的时间常数由用户指定,将上述寻找路径的算法放人OnTimer()中即可。但OnTimer()中的代码除了寻找路径外,还有
一项重要的任务就是将寻找路径的过程反映到用户窗口去。该功能
的实现是调用InvalidateReet(rejow);调用该函数后,OnDraw()便根据当前的状态对窗口进行重绘。为了避免屏幕的闪烁,使用玩validateRect(),而不是
Invalidate()。此时只是重绘rcNow指定的矩形区域,而不重绘其它区域,所以以前到过的区域并没有被重绘,直到有其它窗口班盖此窗口时,才会导致整个窗口的重绘,使以前的状态消失。
程序的使用方法如下:打开程序后,程序自行生成一个6*6的迷宫。用户可设置迷宫的行数和列数,之后按“重新生成迷宫”按钮来重新随机生成一个迷宫。该迷宫只是随机生成的,没有考虑其合法性(即有可能没有通路)。选择寻找路径的步速,单位为毫秒。之后按“搜索”去搜索路径。在搜索过程中该按钮会变成“停止”,即再按下此按钮后会停止搜索。
用户可随时保存迷宫及其状态。但该程序还有一个问题就是不能在本次保存后打开保存的文件,只能在程序标题栏中显示“无标题”时才能打开。
3.4 游戏程序
用VC十十编程如下:
通过编译运行:程序自行生成一个6*6的迷宫。用户可设置迷宫的行数和列数,之后按“重新生成迷宫”按钮来重新随机生成一个迷宫。该迷宫只是随机生
成的,没有考虑其合法性(即有可能没有通路)。
选择寻找路径的步速,单位为毫秒。之后按“搜索”去搜索路径。在搜索过程中该按钮会变成“停止”,即再按下此按钮后会停止搜索。
该迷宫只是随机生成的,没有考虑其合法性(即有可能没有通路)。如果有通路,就会找到通路并以蓝色标示。
3.5 小结
游戏提示区的实现方式与主游戏区类似。该软件只包含了迷宫游戏的基本功能,但该程序采用了面向对象的设计方式,易于扩充。
总结
通过编写这个程序,我体会最为深刻的一点是系统架构和设计模式的重要性。即使是对于一个并不大的程序,代码的组织都是非常重要的,因为这关系到日后的维护以及扩展。但是对于系统的架构,却完全是自己的事情,几千上万行的代码需要通过合适的方法组织起来,使程序员编写代码更加有条理,更加符合软件工程的标准,这才是最重要的。
在刚开始编写这个程序的时候,我幼稚地认为其中最重要的是算法。但是头一个月编写程序的时候却发现程序越写越不容易维护,可见是我走错了方向。后来我向公司真正的软件设计人员及系统架构师讨教,他们告诉我:我们的先人早已为我们准备好了各种精良可用的现成算法,我们所要做的就是直接“拿来主义”罢了;但是对于代码的组织(也就是软件的架构)才是真正软件工业的核心部分,因为软件事实上是直接和经济挂钩的,因此我们必须在编写代码之前选择一种最为合适的方法来组织这些代码,否则我们将会失去更多的时间和金钱。
[15]
于是,我将以前写的代码全部删除,认真地思考了三天的时间。我也在这三天内真正从一个学生程序员走入了软件开发的大门,我开始发现其实软件开发并不是纯数学——正相反,数学只占了很小的一部分。它其实是一种哲学,一种有着数学美感的哲学。
目录
[1] MSDN for Visual Studio 6.0
[2] 设计模式——可复用面向对象软件的基础,Erich Gamma/Richard
Helm/Ralph Johnson/John Vlissides著,李英军/马晓星/蔡敏/刘建中 等译,机械工业出版社
[3] 深入浅出MFC(第2版),侯俊杰著,华中科技大学出版社 [4] A Beginner 's Guide to Pointers,Andrew Peace
http://www.codeproject.com/cpp/pointers.asp [5] 水煮多态,titilima
http://home.nuc.edu.cn/~titilima/readarticle.php?id=53
[6] Microsoft® Visual C++.NET 技术内幕(第6版),George Shepherd/David
Kruglinski著,潘爱民译,清华大学出版社
[7] Visual C++网络通信协议分析与应用实现,汪晓平/钟军 等编著,人民邮
电出版社
[8] C++编程思想,Bruce Eckel著,刘宗田/邢大红/孙慧杰 等译,机械工业出
版社
[9] 21天学通C++,Jesse Liberty著,康博创作室译,人民邮电出版社 [10] C++标准程序库,Nicolai M.Josuttis著,侯捷/孟岩 译,华中科技大学出
版社
[11] Windows程序设计,Charles Petzold著,北京博彦科技发展有限公司译,
北京大学出版社
[12] Visual C++.NET网络编程,易君 编著,中国铁道出版社 [13] 博弈树搜索
http://202.113.96.26/wlkc/rengongzhineng/rengongzhineng/kejian/AI/Ai/chapter3/33.htm [14] 五子棋的核心算法,蝈蝈俊.net
http://blog.joycode.com/ghj/articles/12727.aspx [15] 道法自然,王咏武/王咏刚 著,电子工业出版社
因篇幅问题不能全部显示,请点此查看更多更全内容