2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文

上传人:1888****888 文档编号:38215642 上传时间:2021-11-06 格式:DOC 页数:35 大小:1.19MB
收藏 版权申诉 举报 下载
2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文_第1页
第1页 / 共35页
2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文_第2页
第2页 / 共35页
2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文_第3页
第3页 / 共35页
资源描述:

《2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文》由会员分享,可在线阅读,更多相关《2111.基于Visual C++实现的单机版俄罗斯方块游戏的设计毕业论文(35页珍藏版)》请在装配图网上搜索。

1、本科生毕业设计 基于 Visual C+实现的单机版俄罗斯方块游戏的设计I摘摘 要要俄罗斯方块是非常传统的游戏,操作简单,难度却不低,广受娱乐界欢迎。给人们的生活带来了健康愉快的补充,唯美的艺术享受。本文在基于 Visual C+实现的单机版俄罗斯方块游戏的基础上,深入的研究 MFC 框架中的各个类的关系和它们内部之间的联系。主要工作和结论:1. 分析了俄罗斯游戏规则。2.系统的介绍了实现俄罗斯方块游戏的算法设计过程。3. 将研究的思路运用于实际,在 VC+6.0 平台下实现了俄罗斯方块游戏。 关键词关键词 :俄罗斯方块游戏;VC+;MFC 框架AbstractRussia is a very

2、 traditional box of the game, simple operation, the difficulty is not low, widely welcomed by the entertainment industry. To the peoples life a happy and healthy complement to the flavor of the enjoyment of the arts. In this paper, based on the Visual C + + to achieve the single version of the Russi

3、an box on the basis of the game, MFC-depth study in the framework of various types and their internal relations between the links. And the main conclusions : 1. Analysis of the Russian rules of the game. 2. The system introduces a game of Russian box algorithm design process. 3. Will examine the pra

4、ctical application of ideas, in VC + +6.0 platform under the Russian box game. Key words : Russian box game; VC + +; MFC framework 本科生毕业设计 基于 Visual C+实现的单机版俄罗斯方块游戏的设计II目目 录录摘摘 要要.IABSTRACT.I1 引言引言 .31.1 选题及研究意义选题及研究意义 .31.2 论文研究的主要内容论文研究的主要内容 .32.1 APPAPP 应用程序类物件应用程序类物件 .42.2 文档文档视图机制视图机制 .52.3 DOC

5、UMENTDOCUMENT 文挡操作文挡操作 .62.4 文档文档- -视图的关联视图的关联 .63 俄罗斯游戏分析和总体设计俄罗斯游戏分析和总体设计 .73.1 俄罗斯方块俄罗斯方块游戏游戏功能描述功能描述 .83.2 游戏游戏规则规则分析分析 .84 俄罗斯方块游戏的实现俄罗斯方块游戏的实现 .94.1 游戏游戏核心数据的抽象与设计核心数据的抽象与设计 .104.2 操作方法的抽象与设计操作方法的抽象与设计 .134.3 流程的设计流程的设计与实现与实现 .154.3.1 正常流程的设计正常流程的设计 .154.3.2 正常流程的实现正常流程的实现( (定时处理定时处理) ) .164.3

6、.3 中断操作流程的设计中断操作流程的设计 .194.3.3 中断操作流程的实现中断操作流程的实现 .204.4 游戏区域绘图的实现游戏区域绘图的实现 .214.4.1 位图资源的准备位图资源的准备 .214.4.2 绘图机制设计绘图机制设计 .224.4.3 绘图环境资源的初始化和释放绘图环境资源的初始化和释放 .224.4.4 游戏区域的绘制游戏区域的绘制 .245. .功能的完善功能的完善 .275.1 游戏背景音乐的实现游戏背景音乐的实现 .295.2 工具栏快捷键的实现工具栏快捷键的实现 .30结束语结束语 .33参考文献参考文献 .33致致 谢谢 .34本科生毕业论文2俄罗斯方块游

7、戏的实现1 引言我们国家正处于全球文化产业日新月异大格局中,电子游戏、网络游戏的发展速度之快,更是令人眼花缭乱,目不暇接。未来的电子和游戏发展趋势必将是更智能化、更艺术性、更人性味。在高性能的硬件设备的支持下,游戏的驱动引擎更具威力,控制功能更加完备,在一个错综复杂的极度扩张的游戏大世界中,带着超乎常人智慧的人工智能的应对力,使得所有要素包括艺术的风格、情感的互动、故事的铺展、视觉的表现、用户的界面,融合为有机的一体,给人们带来更丰富的娱乐和体验。好的游戏给人们的生活带来了健康愉快的补充,唯美的艺术享受,潜默的教育功效。本系统采用VC+为主要开发工具设计实现了一个单机板的俄罗斯方块游戏。与其他

8、程序相比,笔者的作品有三个特色:一是精心设计的人机界面,不仅友好而且易于操作。二是笔者的游戏采用的是单机板。三是采用MFC应用程序开发模型进行编制,使开发人员减轻创建Windows应用程序的负担。网络版的俄罗斯方块游戏是两个玩家通过网络进行较量,但在游戏过程中数据要通过服务器进行传送,网络版游戏经常会出现断线、超时等情况这些都是因为网络的速度比较慢造成的。而笔者设计的俄罗斯游戏虽然是单机版的,但速度快,提高了效率。1.1 选题及研究意义选题及研究意义俄罗斯方块游戏是一个比较经典的游戏,根据软件工程有关的规范,以合理的开发原则,设计出单机的俄罗斯方块游戏,并给人们的生活带来唯美的艺术享受和健康愉

9、快的补充。游戏软件是一种与文化背景密切联系的产品,具有很强的民族性和丰富的文化内涵。伴随着游戏软件在市场上的销售,与其相关的文化也随之传播。因此发展我国自主的益智、健康的游戏软件已是当务之急。游戏是一种基于计算机的应用软件,是新型的休闲娱乐方式。当前开发的游戏软件应该做到知识性、娱乐性、趣味性、教育性相统一。1.2 论文研究的主要内容论文研究的主要内容在论文完成过程中,认真学习了游戏开发的基本技术,OOD 方法软件设计的基础知识,VC+程序设计语言等。结合游戏开发的过程、算法的设计与分析(如下坠物的生成、下坠物随机选择、游戏区画板实现的方法等)、软件工程等角度重点研究了实现游戏的算法和采用 V

10、C+平台设计游戏的优点和现存结构的不足之处。以下是论文的组织结构:第 1 部分是引言,主要介绍论文选题的意义、选题背景等相关情况。第 2 部分概述 MFC 应用程序框架。第 3 部分是游戏规则的分析。第 4 部分是游戏算法的实现、游戏功能模块、操作界面以及系统分析及设计。本科生毕业论文3第 5 部分是对整个论文的结束语。对论文的主要工作作了归纳总结,分析了进一步需要做的工作。2 MFCMFC 应用程序架构应用程序架构传统的 Windows 应用程序的开发使用 API(Application Programming Interface)函数。API 函数的功能主要是为 Windows 应用程序开

11、发提供统一的编程接口。在使用 API 编程的过程中,窗口的创建和消息的处理都需要手工编码。一个简单的 Windows 应用程序的代码需要上百行,这使 Windows 应用程序开发变成了一件繁重的工作。现在编程,都是在 Visual C+ 环境下采用基本 MFC(Microsoft Foundation Class)的 Windows 编程方法。Microsoft 基本类库 MFC 是一个 Windows 应用程序框架,它是 C+类结构的扩展。利用 MFC 提供的面向对象程序行色机的框架,可大大减轻程序开发人员创建 Windows 应用程序的负担。MFC 提供了管理窗口、菜单、对话诓的代码,可实

12、现基本的输入输出和数据的存储。此外,MFC 还提供一个应用程序来发模型,此模型被称为文档视图模型。文档视图模型视将应用程序数据与用户界面元素分离的一种应用编程方法,它允许这两部分程序独立存在。这样,程序员在更改其中部分代码的时候,不会大幅度地更改另一部分。该游戏的实现采用 MFC 框架。在构架类视图中有 MFC 基本架构组合 : App(应用程序)类、Document(文档)类、View(视图)类、Frame(框架)类和用于提示关于作者的对话框 CAboutDlg 类。下面对这几个类做一个简单的列表,如表 2.1 所示。表 2.1 MFC 应用程序架构表类别基类 描述ApplicationCw

13、inApp代表应用程序的核心DocumentCdocument包含应用程序的数据集Windows Cwind主要用于图形用户界面(GUI)的对象,可以处理常见的 Windows 消息FrameCframeWnd用于应用程序的主要 Windows 框架ViewVciew用于显示数据并与文档 Document 对象交互2.1 APPAPP 应用程序类物件应用程序类物件每种语言都有一个程序入口(主函数),如 C/C+语言的 main()函数。总地来说, main()函数的调用与终止代表着程序执行的开始与结束,在程序运行的过程中,无非是对一些业务性的功能流程进行不断的处理,当完成后才退出程序。其实,所

14、有的程序也是采用同样的方法去实现, MFC 机制巧妙地利用了 Application 类去封装实现了这样的效果功能,每个 CWinApp 类对象实体都代表应用程序本身,它是基本的 Application Class(应用程序类),其封装了 Windows-based 应用程序的初始化、运行、 Message 映射和终止等功能。假如创建了这样的一个对象实体,在运行期间处理初始化、消息映射、或者其他本科生毕业论文4动作时就可以通过属性操作的调用去实现,而不像拥有结构化设计思想的 mainO 函数那样的顺序去实现。那么,现在就来看看这个 CWinApp 类对象的性质。在 MFC 框架中,应用程序必须

15、有且仅有一个从 CWinApp 派生的 Class Object(类物件),这个 Object 在 Windows 创建之前就会被创建,也就是说这个 Object 会和其他 C+ 全局 Object 同时创建。当 Windows 调用 WinMainO 时(在 MFC 应用程序中,不必亲自调用 WinMainO,因为机制已经对它封装好,当应用程序启动时会由框架自动调用),这个 Object 已经可用了,并且该 Object 是全局的。 当用 AppWizard 创建 DocumentNiew 模式应用程序时,AppWizard 会声明一个从CWinApp 派生的 Application Cla

16、ss, 因此,由 AppWizard 所产生的.cpp 文件中还包括 Message 映射、空的构造函数、一个应用程序 Object(即一个变量)和 InitInstanceO 函数。AppWizard提供的源代码和 Message 映射可以满足一些基本的任务,但在通常情况下,还是需要手工修改那些源程序,特别是要修改 Initinstance()函数。在 CWinApp 中,有以下几个关键的可重写的成员数。 InitInstance(): 此函数对文档模板(Document Template)进行创建和初始化,即在这过程中伴随着 Document、View 和 Frame 的创建。 Run()

17、: 初始化后,WinMain 就会调用这个成员函数去处理 Message 循环。 ExitInstance(): 每当一个应用程序的 Copy (拷贝)终止时,就会调用这个函数,即发生在应用程序退出时。 OnIdle(): 当没有 Windows Message 处理时,就会由 Framework 调用这个函数,并重写这个函数去执行后台任务。当用户从 CWinApp 派生一个 Application Class 时,必须重写成员函数InitInstance() 去创建应用程序的 Main Window Objecto Windows 允许同时运行同一个应用程序的多个“Copy”, 而且该应用程

18、序的每个 Instance(包括第一个的)都会被初始化,而初始化时都会用到被 Override 了的 InitInstance() 函数所提供的信息。通常情况下,每个 Windows-based 应用程序都有一个 Main Window 。因此,在初始化完成后, Framework 就会检查是否存在一个指向有效 Main Windows( CWinApp:m_pMain Wnd) 的指针,如果不存在的话,应用程序就会终止。当利用 AppWizard 创建应用工程项目时,AppWizard 会重写缺省的 InitInstance()来创建 Main Window Object,还会使 CWinA

19、pp 的数据成员 m_pMainWnd 指向那个 Window 。2.2 文档文档视图机制视图机制文档对视图的管理。若用非文档,视图机制的时候,交互界面显示的只有一种视图,在这种情况下,可以将内部数据以一种对应规则用图像显示出来。将一份数据用不同的方式去展示,并且将它们放在不同的窗口视图中,MFC 机制给出了这样的实现方法:先用一个 CDocument 这样的物件去处理数据的管理,然后用一个 CView 这样的物件去管理视图的显示,这样一来,所有不同的显示图像若要以某种方式反映出数据的特性,必须在数据源和众多不同方式的图像显示之间有一定的关联。对于它们的关联,MFC 机制用了一个很好的方本科生

20、毕业论文5法,就是将所有与这个数据源相关的图像显示都独立用 CView 物件去表示,而当数据源就抽象成 CDocument 物件, 而在 Document 中有这样的一个指针列表 CPtrList 类型的日 员变量 m_viewList, 将所有这些与之关联的视图用链表串起来。而这些用于显示不同性质的图像视图类也可以通过 GetDocument()来获取其所对应的 Document 文档数据。2.3 DocumentDocument 文挡操作文挡操作由于 MFC 机制设计出文档类对象专门负责数据的 I/O 存取和数据的运算和操作等。一般来说,数据运算是通过 Document 类里面的扩展功能来

21、实现的,这样做可以形成一种密集数据处理,达到方便易用和管理的好处。对于一个文件而言,如果文件内对象的排列顺序是固定的,那么对于文件读和写从形式上只有使用的运算符的不同。在 MFC 的文档-视图-框架结构中,一个文档的内部对象的构成往往是固定的,在这种情况下,写到文件中的对象在文件中的布局也是固定的。因此 CDocument 是利用其基类 CObject 提供的 Serilize()虚函数实现自动文档的读写操作的。 当用户在界面上选择文件菜单或打开文件 (ID_FILE_OPEN)时,CWinApp 派生类的 OnFileOpenO 函数将被自动调用,它通过文档模板创建或重用框架、文档和视图对象

22、,并最 终调用 CDocument: :OnOpenDocument()来读文件。 当用户选择菜单文件或文件保存(ID_FILE_SAVE) ,选择文件或另存(ID_FILE_SAVEAS) 时,是通过呼叫函数 CWinApp: :OnFileSave() 和 CWinApp: :OnFileSaveAs()并最终调用 CDocument: :OnSaveDocument() 实现的。2.4 文档文档- -视图的关联视图的关联视图与文档和窗口的关联和协调工作可以从视图类对象的 OnDraw() 函数开始,找出关联的物件与关系。在 MFC 机制中,关于 DocumentNiew 架构的项目工程和

23、 OnDrawO 函数的驱动绘图触发的流程 :CDocument:UpdateAIIViews()-CView:OnUpdate()- CWnd: :Invalidate()-OnPaint()-OnDraw()从流程可知当用于装载重要数据的 Document 类对象中的数据发生变化时,为了能让与其关联的各个视图实时表现出数据的特征性质,需要通知所有这些关联的视图进行更新重绘 , 而 Document 类对象就拥有通知所有视图重绘的这样的一个功能函数。对于UpdateAIIViews() 函数实现对各个视图类对象对数据显示的更新是通过文档类内部CPtrlist 类型的成员变量 m_viewLi

24、st 来维护和管理所有相关联的视图对象 , 如图 1.1所示。 本科生毕业论文6 Document 图 1.1 变量 m_viewList 视图对象而对于该文档关联视图的增添,与将 DocumentTemplte 文档模板添加到模板类表一样, 也是有相应的处理函数,对于文档模板在模板管理列表的添加是在 App 类的 Initlnstance()里面使用 AddDocTemplate() 函数去实现,而对于视图在视图列表的添加, 可以使用 Document 类对象的成员函数 AddView() 去实现。当与文档类关联的视图类收到文档类通过 UpdateAIIViews() 函数发出的更新重绘通知

25、后 , 会触发视图类的 OnUpdate() 函数的实现。m_viewListpView_1pView_2pView_3pView_4View_4View_3View_2View_1本科生毕业论文73 俄罗斯游戏分析和总体设计俄罗斯游戏分析和总体设计3.1 俄罗斯方块俄罗斯方块游戏游戏功能描述功能描述对于俄罗斯方块游戏,其功能描述如下:游戏开始,游戏区域上方不断地出现预定义形状的下坠物件。下坠物件可以通过旋转改变其显示形态,并且不断地往下坠, 直到它接触到游戏区域底部或其他之前已经累叠起的下坠物件。当一个下坠物件到达底部后,其位置则确定下来并占有该空间的位置区域。当游戏区域的某一行被下坠物件完

26、全填充,则消除该行的所有下坠物,垒在其上的物件将掉下代替该行空间。游戏的结束是以下坠物件的顶部到达游戏区域顶部作为判断依据,表示装满溢出。并且在某一瞬间,下一个下坠物件的形态在游戏区域的右上方有预先提示,同时每抵消一行空间积分自增 100。3.2 游戏游戏规则规则分析分析首先,在游戏开始后检查当前的下坠物是否已经到了底部,如果不是的话就将下坠物到了该定时器间隔的时间后整体往下移动一个单位,否则,进行到达底部后的操作。对于到达底部后的操作,可以分成以下几个步骤来处理。(1)先对进行到底部后的所有可以抵消的行进行销行处理。(2)生成一个新的“下一个下坠物”,这个下坠物的形态需要随机地生成。(3)在

27、将旧的“下一个下坠物”置换成新的下一个下坠物,并在屏幕右上方显示。(4)将当前的“下坠物”换成以前产生的旧的“下一个下坠物”,并且马上使用。由于在这个过程中已经重新使用了一个新的下坠物件,在刚使用时并且还没有下降前,应该判断它是否已经不可以下降到底部(也就是说,在方块己经堆砌到接近游戏区域顶部的时候,下坠物件一旦被使用,就已经到达了底部),如果是刚好到达底部则实行销行检测和操作, 并且判断顶部(第一行)的某些区域是否已经被占用了,是则表示游戏已经触发结束的标志时间,应该进入游戏结束状态。(5)在前面判断为到达底部后,进行销行检测与操作。(6)在下坠物到达底部的同时,判断是否已经到达了游戏的顶部

28、,是则表示游戏结束,进行游戏结束的资源释放与数据环境清理工作整个流程如图 1.2 所示。本科生毕业论文8开始到达低部1.销行操作2.生成新的“下一个下坠物”3.将新生的下坠物代替旧的“下一个下坠物”4.将旧的“下一个下坠物”用作当前下坠物5.销行操作6.游戏结束处理到达顶部,游戏结束结束到达低部7.下降一个单位本科生毕业论文9 图 1.2 流程图4 俄罗斯方块游戏的实现俄罗斯方块游戏的实现俄罗斯方块游戏设计的实现,主要包括游戏核心数据的抽象与设计、操作方法的抽象与设计、及流程的设计与实现等。下面将对这几个部分作具体的设计。4.1 游戏游戏核心数据的抽象与设计核心数据的抽象与设计在抽象出方法和属

29、性前,先来分析一下整个游戏的具体实现。首先 , 游戏有开始、暂停、结束等操作接口,而在游戏过程中,随着用户的按键交互,会出现方块的形态变化、方块快速下坠、安放该下坠物件、销毁填满的行、产生下一将要出现的方块等功能。这里,先分析游戏的特点,把整个游戏的核心数据结构提取出来,再根据数据结构的特点提取出核心功能模块的关联,然后对这些功能一一进行细化,从而完成整个游戏的设计。下面就来分析整个游戏的整体状况,如图 1.3 所示。 图 1.3 游戏内部方块从如图 1.3 所示可以看到,游戏区域可以看作是由许多个等面积的小方块构成的大面积区域。而这些区域的状态只有 2 种,被下坠物占据和空闲(没有被下坠物占

30、据),因此,对于整个游戏区域的数据,用一块空间来标识即可。其状态只有两种:被占据 1 和空闲 0。这块空间的分配,可以采用动态分配的方式或者静态分配的方式去实现,至于数据结构的选择,可以是链表、队列或者数组等,我这里选择静态分配并划分一个足够大的二维数组的方式来实现,如下所示。/in file:skyblue_RectView.h#define MAX_ROW 100 /地图的最大行数#define MAX_COL 100 /地图的最大列数/in file:skyblue_RectView.h class:Cskyblue_RectView/内部存取数据结构int m_stateMapMAX_

31、ROWMAX_COL本科生毕业论文10从上述代码可以看到,在视图类对象里面分配了一个存储游戏区域地图状态的二维数组 ID_stateMap 成员变量,并定义其最大行数和列数都为 100(当然,实际可能并不需要那么大,只是先分配好足够的地图空间以供使用而已)。同时,还应该预先定义该区域的两种状态值:#define MAP_state_empty 0 /空(未被占据)#define MAP_state_not_empty 1 /被占据整个游戏区域的地图设计好后,再来看看具体的下坠物,通过分析它们的特性,还可以抽象出一些物件来。在每个下坠物在下坠的过程中,总是占有地图中的某一块区域,那么怎样表达这些

32、下坠物的形态和它们占有的位置关系呢?在此,先来看看它们的基本类型,然后进行归纳分析,其基本类型如图 1.4 所示。 图 1.4 方块基本类型从图 1.4 可以看到,这些下坠物的形状一共有 7 种,对于这些形态各异的下坠物间存在一个最基本的共性,就是它们占有的位置空间是一样的,都是 4 个小方块区域。对于它们在某一瞬间的位置标识,我们可以采用一个 4x2 的小数组标识出来,如图 1.5 所示。 图 1.5 方块位置标识 也就是说,用 4 个存储单位空间存储当前下坠物的每一子块的位置来对整 个下坠物件的位置进行标识,而每个存储空间的大小就是一个点的坐标值(x,y),于是就有如下定义。 /in fi

33、le : skyblue_Rectciew.h /用于保存当前方块的动态位置,4 个小方块分别在大数组中的存放位置为先左后右, /每一列又遵循先上后下的原则 Int ActiveStatus42; /存入下一个要出现的方块形状的数组 Int NextStatus42; 本科生毕业论文11在上述代码中,分配了一个整型的二维数组 ActiceStatus来存储每个下坠物的 4 个子方块的坐标位置,其实在游戏过程中,变动的下坠物件除了当前用户正在操控的下坠物件外,项目程序的右上方还需要显示出下一个下坠物件的形状。也就是说,在游戏过程中的某一瞬间,除了需要记录当前用户正在控制的下坠物状态外,还需要记录

34、预先随机生产出来的下坠物件状态,于是代码中多了一个 NextStatus数组成员变量,用以存储下坠物的形态。还有一个问题没有解决,这些形状各异的下坠物件,虽然都是由 4 个小方块构成,但是对于它们的编号还没有一定的规律,因此需要人为地定下一些规则,而这个规则就是:编号从下坠物的左边起往右编排,而在同一列的方块中,则从上往下的顺序开始编号它们的对应关系如图 1.6 所示。图 1.6 方块类型对应位置标识如图 1.6 所示的两个不同的下坠物,每个方块按照从左到右的方式进行编号,并且在编号过程中对于同一列的方块实行从上到下进行编号,而该方块所在游戏区域的位置坐标 则 存储在下标与编号所对应的 Act

35、iceStatus二维数组的每个单位里面,如: ActiceStatus00 和 ActiceStatus01则是第 0 号方块的横坐标 X 和纵坐标Y。 ActiceStatus20 和 ActiceStatus21则是第 2 号方块的横坐标 X 和纵坐标 Y。至此,可以实现下坠物件的位置标识了,那么对于某一下坠物的形态特性又怎么标识呢?可以使用这样的方法:用一个宏去标识 ,第 1 位的数值变化范围为 17,用于标识下坠物的种类(7 种),第 2 位标识该种类下坠物的不同形态,不同的下坠物,如“田”字形的下坠物只有 1 种形态,所以没有第 2 位,其他的不同形态则从 14(最多有 4 种形态

36、)按顺序标识即可,如第 2 种下坠物的第 3 种形态,其宏标识为 23,如图 1.7 所示。01232031本科生毕业论文12下坠物编号:4状态编号: 1 2 3 4 形状宏标识 41 42 43 44图 1.7 方块变形表示4.2 操作方法的抽象与设计操作方法的抽象与设计 当完成整个游戏的基本核心数据的表达并进行抽象与设计后,接下来,就可以根据游戏的特性对核心的基本操作方法进行抽象,进而实现这些功能。下面将着重分析游戏过程中的实现细节,以便抽象出基本的操作功能。首先是游戏开始,应该有个事件触发游戏的开始,譬如菜单栏选项等,相应地,也可以 类推出游戏暂停与游戏结束等操作功能。游戏开始后,产生一

37、个下坠物件,并且在右上角生成下坠物件的基本形态,因此有随机物件产生这个操作。在游戏过程中,方块会自动随着时间的推移而向下移动,因此有向下移动的操作。在游戏过程中,用户可以通过按键对下坠物的功能进行操作,如变形操作、加速下降操作、向左移动操作、向右移动操作等。上面说到的几点大多是从与用户交互的角度去观察分析的,而从游戏的规则方面,也可以作一下分析,当下坠物响应用户的指示向左或向右移动的时候,需要判断该不坠物件是否已经到这了游戏区域的边界而无法向左或着向右移动:当下坠物的形态改变的时候,需要计算出应该改变成何种形态: 当下坠物向下移动的时候,需要判断是否已经到达了底部等。先虚拟出该俄罗斯方块游戏的

38、类对象,并抽象出核心的数据属性和操作方法等,然后再作细,最后将整个虚拟类的外壳脱掉,再移植到视图类中去,其实现如下所示。CRectGameView: public cview /内部存取数据结构 Int m_stateMapMAX_ROWMAX_COL; /用于保存当前方块的动态位置,4 个小方块分别在大数组中的存取位置为先左后/右,每一列又遵循先上后下的原则Int Activestatus42; 本科生毕业论文13/存入下一个要出现的方块形状的数组Int Nextstatus42; /初始化操作GameInitnal(); /游戏的初始化/用于判断数据相关状态的操作IsLeftLimit()

39、; /下坠物体是否可向左移动IsRightLitmit(); /下坠物体是否可向右移动IsBottom(); /是否已经到达底部IsGameEnd(); /是否游戏已经结束/方块物体下坠过程中的操作RectChange(); /下坠物体变形RectDown(); /下坠物体正常下落RectArrow(); /下坠物体方向移动(左,右,下加速)/状态控制操作GameStart(); /游戏开始GamePause(); /游戏暂停GameEnd(); /游戏结束通过上面的代码可以看出,在虚拟类中抽象出了核心的内部数据和一些基本的操作函数。对于操作函数,可以把它们分成内部实现的基本核心操(如判断操作

40、)以及明显提供给外部使用的整体模块外部操作(如状态控制操作)。而内部的基本操作又可以分成判断操作和执行操作这样两种类型。这里将上面涉及到的操作整理成表,如表 4-1 所示。表 4-1 操作函数及功能描述 属性和操作 功能描述外部操作外部操作状态控制操作组GameStart()游戏进入开始状态,进行相关数据的初始化以及关联操作GamePause()游戏进入暂停状态,进行数据的保持与其他关联的操作GameEnd()游戏进入结束状态,进行数据的清除以及资源的销毁和释放操作内部基本核心操作内部基本核心操作判断操作组IsLeftLimit()向左偏移前,判断该下坠物件是否已经到达了游戏区域的最左边界(不

41、可以再左移IsRightLitmit()向右偏移前,判断该下坠物件是否已经到达了游戏区域的最右边界(不可以再右移)IsBottom()向下偏移加速或者下坠物件自动向下偏移前,判断是否已经到达了底部(这里对底部定义是游戏区域底部或下面有其他下坠物)IsGameEnd()判断下坠物是否到达了游戏区域顶部而应该结束游戏本科生毕业论文14执行操作组RectChange()下坠物件的状态变形,方法为在原来的状态下逆时针旋转 90 度RectDown()该下坠物件的 4 个小方块所有坐标位置向下偏移一个单位RectArrow()直接响应用户按键,向左或者向右或者向下偏移一个单位其他操作其他操作Gameln

42、itnal()游戏的初始化操作 4.3 流程的设计流程的设计与实现与实现流程的设计分正常流程设计和中断流程设计。下面对这两部分做具体的设计和实现。4.3.1 正常流程的设计正常流程的设计对于正常流程的实现是由定时器驱动的,也就是说,当预定的时间间隔到达后就执行这样的一个工作流程,所以必须先设置一个定时器机制,下面来对增加一个定时器进行实现。从分析游戏的特性可以知道,定时器的产生与生效应该在游戏开始的时候,而在游戏暂 停或者游戏结束时则将已经设定的定时器失效/销亡(对于暂停的情况,使它销亡,当游戏从 暂停状态又进入游戏状态的时候,则重新创建一个定时器并激活它的运作),所以分别在游戏的开始函数、暂

43、停函数以及结束函数中实现定时器的激活与去激活工作。这里,先在资源编辑器菜单资源里面添加 3 个菜单选项,分别是游戏的“开始”、“暂停”和“结束”(由于这 3 个功能是外部给用户操作的功能,所以可以预先在菜单栏中添加相应的功能选项,然后在视图类中实现它们即可,当它们找到直接关联的物件后对虚拟类的功能操作预先脱壳), 然后利用 ClassWizard 直接在视图类对象 Cskyblue_RectView 中为它们添加空白的处理函数 , 具体如表 4-2 所示。表 4-2 菜单选项功能对应表菜单选项名称快捷键资源 ID晌应处理函数开始游戏&S.ID GAME_STARTOnGameStart()暂停

44、游戏&P.ID GAME_PAUSHOnGamePaush()结束游戏&E.ID GAME_ENDOnGameEnd()现在,就可以在上面的 3 个空白的函数中添加定时器了,其具体实现如下所示。/in file:skyblue_Rectview.cpp/游戏开始void Cskyblue_Rectview:ongamestart() m_bGamepaush=FALSE;SetTimer(1、1500-250*m_iLevel、Nulll);/游戏暂停void Cskyblue_RectView:onGamePaush()本科生毕业论文15 m_bGamepaush=TRUE; killTim

45、er(1);/游戏结束void Cskyblue_RectView:onGameEnd() m_bGameEnd=TRUE; m_bGamepaush= FALSE; /清除游戏暂停状态 killTimer(1);从上面的 3 个函数代码中可以看到,在添加这 3 个函数时,视图类还添加了涉及到游戏状态的 3 个成员变量,它们分别是用作判定当前游戏等级的 m_iLevel、记录游戏状态的m_bGamePaush(是否暂停)和 m_bGameEnd(是否结束游戏),它们在视图类中的定义如下所示。/in file:skyblue_Rectview.h class: CSskyblue_Rectvie

46、w/当前的级别,换算成速度的算法为:1500-m_iLevel*200int m_iLevel;/游戏是否已经结束或者暂停BooL m_bGameEnd;BooL m_bGamePaush;其中 m_iLevel 变量是标识当前游戏的等级,随着游戏等级的升高,定时器的固定时间间隔会逐渐变短,从而达到加快下降速度的效果。4.3.2 正常流程的实现正常流程的实现( (定时处理定时处理) )经过定时器的设置后,就可以在定时器预定时间到达后对正常流程进行实现了。这里通 过利用 ClassWizard 跳到定时器到时后的处理函数 OnTimerO 去实现,其清单如下所示。/int file:skyblu

47、e_Rectview.cpp void CSkyblue_RectView:OnTimer(UINT nIDEvent) /如果原来的方块已到底或游戏刚开始,则掉下一个新的方块int i,j,k;if (m_isBottom)/1.产生下一个随机下坠物m_icurrentStatus = m_inextStatus;m_inextStatus = Random(7); /得到下一次的方块样式本科生毕业论文16/ if (m_inextStatus=0) m_inextStatus+;/2.修改新的“下一下坠物”RectStatusToNextStatus( m_inextStatus );/

48、CRect rect(m_iStartY+320, m_iStartX, m_iStartY+440, m_iStartX+160);/ InvalidateRect(&rect);/ Invalidate(FALSE);/3.将旧的“下一下坠物”用作当前使用m_currentRect = m_icurrentStatus; /根据当前下坠物的形状去初始化激活状态下的下坠物坐标RectStatusToActiveStatus( m_icurrentStatus );/将当前动态数组中的数据反映到大数组中ActiveStatusToGameStatus();m_isBottom = FALSE;

49、/4.判断当前方块是否已到底IsBottom(); /5.判断游戏是否已结束: 碰了底,且第 1 行有小方块if (m_isBottom)for (i=0;im_iCol;i+)if (GameStatus0i)KillTimer(1);AfxMessageBox(游戏已结束!);for (j=0;jm_iRow;j+)for (k=0;k SelectObject(m_pBlackBrush);CRect rect;GetClientRect(&rect);pDC - Rectangle(rect);/选用灰色画刷,绘制游戏区域的背景pDC - SelectObject(m_pGrayBru

50、sh);pDC - Rectangle(m_iStartY ,m_iStartX, m_iStartY + 301, m_iStartX + 360);pDC-SelectObject(m_pBlackPen);/画网格线if (m_bDrawGrid)/画横线for (i=0;iMoveTo(m_iStartY, m_iStartX + i*m_iLarge);pDC-LineTo(m_iStartY+300, m_iStartX +i*m_iLarge);/画竖线for (i=0;iMoveTo(m_iStartY+i*m_iLarge, m_iStartX);pDC-LineTo(m_i

51、StartY+i*m_iLarge, m_iStartX+360);int x,y,nW,nH;/小方块的绘制for (i=0;im_iRow;i+)for (j=0;jBitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockSytle*30,0,SRCCOPY);本科生毕业论文25/显示游戏区域及游戏级别的汉字描述if (!m_bGameEnd)pDC - SetBkColor(BLACK);pDC - SetTextColor(WHITE);pDC - TextOut(m_iStartY+320, m_iStartX+220, 游戏区域大小:);pDC - TextOu

52、t(m_iStartY+320, m_iStartX+240,m_strArea);pDC - TextOut(m_iStartY+320, m_iStartX+280, 游戏级别:);pDC - TextOut(m_iStartY+320, m_iStartX+300,m_strLevel);/显示总分if (!m_bGameEnd)CString lsStr;lsStr.Format(总分为:%d 分,m_iPerformance);pDC - SetBkColor(BLACK);pDC - SetTextColor(WHITE);pDC - TextOut(m_iStartY+320,

53、m_iStartX+180,lsStr);/画下一次将要出现的方块,用于提示用户if (!m_bGameEnd)pDC - SetBkColor(BLACK);pDC - SetTextColor(WHITE);pDC - TextOut(m_iStartY+320, m_iStartX,下一个方块:);int x,y,nW,nH;for (UINT k=0;kBitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockSytle*30,0,SRCCOPY);本科生毕业论文26从上述代码可以看到,这里并不是先将各个部分的图像所在的位置先计算出来, 然后在相应的位置绘制适当的图像

54、,而是采用类似于平常的手工作画方式,首先是将整个画布画上背景色,接着绘制游戏区域的背景色(将原来整个画布的背景覆盖掉),然后在游戏区域中将位置为被占用状态的区域绘制成小方块图样,并将原先绘制好的游戏区域背景色覆盖掉。一般来说,使用这种方式去实现绘制, 效率比先逐个计算出每个位置区域应当显示的图样,然后再一次性地绘制的方式要高,因为这样做不必花费太多的时 间在计算方面。在绘制之前,分别通过黑色画刷 m_pBlackBrush 以及灰色画刷 m_pGrayBrush, 对窗口区域背景以及游戏区域背景进行绘制,并且选择黑色画笔 m_pBlackPen 对网格进行绘制。对于这些画刷和画笔的使用,也要预

55、先准备好,所以在绘图资源初始化和释放函数中,也要添加它们的创建和释放。至此,就完成了俄罗斯游戏的全部基本功能,效果如图 1.11 所示。 图 1.11 游戏界面本科生毕业论文275. .功能的完善功能的完善完成游戏的功能后,为了使得游戏功能更加健全,还需要对它进行一些完善,下面是附加功能描述的列表,如表 5-1 所示。表 5-1 附加功能描述列表功能名称选项其他描述游戏等级选择初级顶级对游戏快慢难度的设定方块图案样式选择深蓝条纹对下坠物的小方块图案样式选择游戏区域大小选择小、中、大对游戏区域的行列数选择网格的选用有、无是否需要在游戏区域绘制网格背景音乐的选用有、无在游戏过程中是否播放背景音乐有

56、了上面的目标功能定义后,这里先将这些目标功能通过资源编辑器在主菜单条进行添加,将前面已有的菜单选项补全,再通过 Class Wizard 添加对应的响应处理函数,其详细信息如表 5-2 所示。表 5-2 菜单选项功能对应表菜单选项名称快捷键资源 ID晌应处理函数基本选项组(&G)开始游戏&S.ID GAME STARTOnGameStart 0暂停游戏&P.ID GAME PAUSHOnGarnePaush 0结束游戏&E.ID GAME ENDOnGarneEnd 0游戏等级选择(&L)本科生毕业论文28第一级:入门级&1.ID OPTION LEVEL 1OnOptionLeve110第二

57、级:初级&2.ID OPTION LEVEL 2OnOptionLeve120第=级:中级&3.ID OPTION LEVEL 3OnOptionLeve130第四级:中高级&4.ID OPTION LEVEL 4OnOptionLeve140第五级:高级&5.ID OPTION LEVEL 5OnOptionLeve150第六级:顶级&6.ID OPTION LEVEL 6OnOptionLeve160区域大小选择(&A)小: 12 行10 列&1.ID OPTION AREAlOnOptionArea 10中: 18 行15 列&2.ID OPTION AREA2OnOptionArea

58、10大: 24 行20 列&3.ID OPTION AREA3OnOptionArea 10其他网格&G.ID OPTION GRlDOnOptionGridO音乐&M.ID OPTION MUSICOnOption 如1usicO对于上面众多参数选项的实现,只需要在它们的处理函数中对相应的参数进行适当地修改即可, 通常对于功能的完善,多是将原来设定的固定值拓展成可修改的成员变量,而对这些成员变量的修改则通过函数接口去实现。关于背景音乐的播放,这里将选用一种比较高级的音频播放控制机制 MCI(媒体控制接口)去实现. MCI 具有更强大的功能。正因为它有强大的功能,故 MCI 的操作和使用也会相

59、应地复杂些,MCI 向 Windows 程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备,就可以对 CD 机、视盘机、波形音频设备、视频播放设备和 MIDI 设备等媒体设备进行控沤制。现在常见的 au、mp3、Mpeg4 格式的文件,都可以通过 MCI 去控制并实现播放或录制。可以把 MCI 理解为设备面板上的一排按键,通过选择不同的按键(发送不同的 MCI 命令)让设备完成各种功能, 而不必关心设备内部的实现。5.1 游戏背景音乐的实现游戏背景音乐的实现本科生毕业论文29游戏背景音乐采用 MCI 机制方式实现音乐的播放。在 CSkyblue_RectView 视图类添加两个成

60、员函数 playmid()和 stopmid(),分别实现对指定的背景音乐的播放以及停止播放功能,其具体实现如下所示。/in file:skyblue_rectview.cpp/播放背景音乐,所有错误忽略/void CSkyblue_RectView:PlayMid()HWND hWnd;hWnd = GetSafeHwnd();/分配命令字符串缓冲,错误信息储存缓冲,播放的文件名char szCmdBuf300,errBuf60,szfileName255;/错误码MCIERROR mciError;/初始化设备元素strcpy(szfileName,skyblue_rect.mid); /

61、初始化命令字符串wsprintf( szCmdBuf,open %s type sequencer alias bkMusic,szfileName);/打开设备mciError = mciSendString( szCmdBuf, errBuf, sizeof(errBuf), NULL);if (mciError = 0)/如果打开成功则播放mciError = mciSendString(play bkMusic notify,NULL,0, hWnd);/根据播放操作是否成功决定是否关闭设备if (mciError != 0)mciSendString(close bkMusic,NU

62、LL,0,NULL);/终止插放背景音乐/void CSkyblue_RectView:StopMid()/关闭设备mciSendString(close bkMusic,NULL,0,NULL);本科生毕业论文30完成播放 playmid()以及停止播放 stopmid()的功能封装后,现在只需在相应的菜单选项以及适当的代码位置中加上它们就可以了。5.2 工具栏快捷键的实现工具栏快捷键的实现在完成上面补充功能的拓展和完善后,接下来为俄罗斯方块游戏增加一个放置常用功能选项的工具栏,以便用户可以通过鼠标点击而直接对相应的选项功能进行实现。这些常用功能选项分别是游戏的“开始”、“暂停”、“结束”、

63、“配置”。(1)工具栏的定义/in file:mainfrm.h class:cmainframeCtoolbar m_wndtoolbar(2)工具栏的创建/jin file:mainfrm.cppint CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;/工具栏的实现CImageList img;CString str;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |

64、WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)return -1;/设置按钮的宽度和长度m_wndToolBar.GetToolBarCtrl().SetButtonWidth(40, 100);/改变属性m_wndToolBar.ModifyStyle(0, TBSTYLE_FLAT |CBRS_TOOLTIPS | TBSTYLE_TRANSPARENT|TBBS_CHECKBOX );/设置按钮数为 6m_wndToolBar.SetButtons(NULL,4);

65、/ 2. 添加图像/设置热/hot状态的的位图本科生毕业论文31img.Create(28, 28, ILC_COLOR8|ILC_MASK,2,2);img.SetBkColor(RGB(0, 0, 102);/顺序增添按键的图标img.Add(AfxGetApp()-LoadIcon(IDI_ICON_START); img.Add(AfxGetApp()-LoadIcon(IDI_ICON_PAUSE);img.Add(AfxGetApp()-LoadIcon(IDI_ICON_END); img.Add(AfxGetApp()-LoadIcon(IDI_ICON_SET);m_wndT

66、oolBar.GetToolBarCtrl().SetHotImageList(&img);img.Detach();/设置冷/cold状态的位图img.Create(32, 32, ILC_COLOR8|ILC_MASK, 2,2);img.SetBkColor(:GetSysColor(COLOR_BTNFACE);/顺序增添按键的图标img.Add(AfxGetApp()-LoadIcon(IDI_ICON_START); img.Add(AfxGetApp()-LoadIcon(IDI_ICON_PAUSE);img.Add(AfxGetApp()-LoadIcon(IDI_ICON_END); img.Add(AfxGetApp()-LoadIcon(IDI_ICON_SET);m_wndToolBar.GetToolBarCtrl().SetImageList(&img);img.Detach();/3. 设置文字 m_wndToolBar.SetButtonInfo(0, ID_GAME_START, TBSTYLE_BUTTON, 0);m_wndToolBar.Set

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!