经典***方块游戏

源码百度云链接

链接:https://pan.baidu.com/s/14frk2EuFoiRCzudol2Xgvg
提取码:syzk

GitHub

https://github.com/yocichenyx/Tetris-Game

开发者:yocichen

 0引言

0.1背景和意义

一直以来,就有自己实现一个经典小游戏(比如贪吃蛇、***方块等)的想法,但是从未实现过,这次课设正好有此机会并且本学期开设的图形学课程也可以派上用场。要求由自己独立设计(用面向对象方法)、完成一个游戏,就想到了***方块这个经典又不失难度的小游戏。

用面向对象的方法来设计,可以培养自己的设计的能力,设计模式的运用又可以让自己熟悉常用的设计模式、体会其深邃的思想,独立开发也锻炼了自己的编码能力,这是一个较为全面的课程设计,对于我来说是一个不小的挑战。

0.2小组分工

任务分工

组员姓名

需求分析

yocichen

概要设计

yocichen

详细设计

yocichen

编码

yocichen

测试

yocichen

后期维护

NULL

1 工作计划

1.1主要工作阶段划分

阶段名称

时间安排

需求分析

12.21

概要设计

12.22

详细设计

12.22

编码

12.23-12.26

测试

12.21-12.26

 

1.2各阶段工作任务分解

阶段名称

任务名称

任务描述

负责人

需求分析

需求收集

收集需求,要求给出简要的需求说明

yocichen

用例图绘制

绘制用例图

概要设计

设计类图

根据需求说明和用例图,设计类图

yocichen

详细设计

Panel类设计

设计类属性和方法,给出实现思路

yocichen

Assembly类设计

Square类设计

编码

Panel类实现

按照详细设计,具体实现各个类,完成参数传递的协调,能达到游戏的基本要求

yocichen

Assembly类实现

Square类实现

测试

黑盒测试

测试游戏是否正常运行,各个功能是否实现

yocichen

白盒测试

进入代码内部,对逻辑进行推导和测试

 

2需求分析

2.1概述

收集需求,给出简要的需求说明,绘制用例图。

2.2用户分析

我是一个游戏玩家,我希望这个***方块游戏是这样的:首先它的界面应该和经典的游戏界面风格保持一致,他的音效一定要好,有动感,让人在玩游戏时感受到***。它还要能显示当前玩的累计时间,显示我已经消除的行数以及我的等级。在控制方面,我希望可以通过方向键控制同时WASD键也可以控制,这样会方便***作。然后我希望我可以通过鼠标点击来控制开始和暂停游戏。

2.3 约束条件

       成员和工作时间约束:小组只有一人,工作时间可从早上8:00持续到晚上11:30,其中要去掉休息时间。

用户约束:用户要求用最少的人员、最低的成本、最快的速度、最高的质量交付所需的软件,并且要求工作人员可以持续工作。

2.4功能需求

2.4.1 用例图

    用例图

2.5用户界面需求

2.5.1 方块显示界面应该简约、像经典***方块的界面,并且要有方格(辅助对齐)

 

方块界面

 

2.5.2 要能显示当前的分数、所消行数、累计时间、玩家等级

 

分数面板

 

2.5.3 开始和暂停按钮要做的醒目一些,容易点击

 

按钮图片

 

3设计与实现

3.1概述

经典***方块游戏主要涉及游戏面板、组合块以及小方块三种显示元素,分别设计为三个类。其中,组合块由个数不同的小方块组成,所以组合块类与方块类相关联,面板类需要显示每一个组合块,因此面板类与组合块类相关联。

特别的,由于面板类对象只需要一个,它需要掌握大量对象的引用、占用较多资源并且要求能够公共访问,故将其设计为Singleton

3.2体系结构

3.2.1 类图

类图说明:主要包含四个类CTetrisView、Panel、Assembly、Square,其中CTetrisView由软件生成,Assembly类与Square类关联,Panel类与Assembly类关联,CTetrisView类与Panel关联。这样,Panel类对象就可以掌握所有Assembly对象,进而掌握所有Square类对象,这样在不断绘制、擦除、移动、重绘时就会非常方便。

 

类图

 

3.2.2 对象图:

对象图

说明:单件模式Panel类只有一个对象panel,它掌握多个Assembly对象,每个Assembly又掌握多个Square对象的引用,均属二元关联。

 

3.2.3 序列图

 

 

序列图

说明:在定时器中需要对当前的Assembly对象进行移动刷新,步骤是代码调用段发消息给焦点组合块对象p让其移动,p向自己掌握引用的方块对象发消息让其分别启动,下面是移动的序列图。(擦除和绘制机制与移动一致)

 

3.2.4 状态图

 

状态图

说明:运行程序时状态转入开始,鼠标点击开始按钮,进入组合块下落状态,每次到达底部进行判断,如果!isTop(),即未达到顶部,继续下落,如果接收到键盘方向键按下消息,进入移动/旋转状态,接收到释放键盘消息,则回到下落状态;如果此时点击暂停按钮,则静茹暂停状态,再点击开始按钮则继续下落。如果isTop()判断为真,则结束。

3.3 主要程序文件

主要文件

对应类

Panel.h

Panel

Assembly.h

Assembly

Square.h

Square

TetrisView.h

TetrisView

主要函数

功能

void drawSelf(CDC *pDC)

绘制(用于Panel/Assembly/Square

void addAssembly(Assembly a)

Panel添加Assembly对象引用

void moveSelf(CDC *pDC,int x, int y)

移动对象

void wipeSelf(CDC *pDC)

擦出自己

void addSquare(Square s)

Assembly类对象添加Square类对象的引用

void delSquare(int y1, int y2)

Assembly类对象删除Square类对象的引用

void changeColor(CDC *pDC, COLORREF color)

改变对象颜色

void OnTimer(UINT_PTR nIDEvent)

定时器

int UpdateTopp(CDC *pDC)

更新panel的顶部值

BOOL PreTranslateMessage(MSG* pMsg)

键盘响应

bool isRightBoundary()

判断是否到达右边界

bool isLeftBoundary()

判断是否到达左边界

bool isUnderBoundary()

判断下方是否碰撞

void filledLineClear(CDC *pDC)

判断是否满行

int dropTopPart(int baseLine)

满行消除后,下移上方的部分

int rotatAssembly(CDC *pDC)

直接旋转对象

int playMusic(CString musicName)

用于播放背景音乐

int funcTop()

处理 上键/w键

int funcBottom()

处理下键/s键

int funcRight()

处理右键/d键

int funcLeft()

处理左键/a键

int updateMarkBoard(CDC *pDC)

更新得分板

static UINT gameOver(LPVOID pParam)

线程函数

int CreateAssembly(CDC *pDC)

产生新的组合对象,加入panel中

3.4开发环境以及部署环境要求

开发环境:Windows 10操作系统 & VS2017

部署环境:Windows 10操作系统

4 测试环境

4.1概述

对于本软件,主要采用黑盒测试方法。主要测试项目为,按钮工作状态、音效播放状态、方块下落状态、能否正常消行、方块是否会出界,是否会重叠、游戏结束判断状态、能否正常结束。 白盒测试,主要测试工作线程逻辑、定时器逻辑、消息响应逻辑等。

4.2 测试环境

机型:荣耀Magic Book

处理器:AMD Ryzen 5 2500U 2.00 GHz

内存(RAM):8.00 GB

系统类型:64位 基于x64处理器

操作系统:Windows 10 家庭中文版

4.3测试计划

测试项目编号

测试项目

负责人

1

按钮工作状态

yocichen

2

音效播放状态

yocichen

3

方块下落状态

yocichen

4

能否正常消行、

yocichen

5

游戏结束判断状态

yocichen

6

能否正常结束

yocichen

7

工作线程逻辑

yocichen

8

定时器逻辑

yocichen

9

消息响应逻辑

yocichen

 

4.4测试项目

测试项目

主要测试内容

按钮工作状态

游戏开始后,点击按钮是否会响应,响应有无异常

音效播放状态

游戏开始,音乐是否会响起

游戏暂停,音乐是否会停止

方块下落状态

方块是否会下落、下落频率,是否会出界,碰撞检测是否异常

能否正常消行、

当有满行时,是否会消除;

当连续有多行满时,消除是否异常

游戏结束判断状态

当组合块触及顶端时,是否会判断结束,就结束音效是否异常,提示信息是否正常

工作线程逻辑

逻辑是否会与用户线程冲突,主要测试音效的状态

定时器逻辑

定时器刷新频率是否合适,内部处理函数间是否会有冲突,是否会导致程序异常

消息响应逻辑

键盘响应函数逻辑

 

5、工作总结

5.1工作成果

成果

完成时间

用例图

12.21晚

类图

12.22整天

初步实现***方块(方块能下落)

12.24早

初步实现碰撞检测、满行消除

12.24晚

添加分数面板,满行消除改善,加入键盘响应

12.25晚

音效调试

12.26

 

5.2过程分析

       本次经典小游戏算是比较成功,这是我在课设中首次采用面向对象方法来设计,在开始时就采用了类关联的设计以及panel的单件设计。在具体的编码过程中采用“设计先行,及早测试”的思想,不断简化算法,以达到更强的鲁棒性。在具体算法的实现过程中,也遇到很多困难,比如结束判断异常,最终采用多线程方式(开一个工作线程不断测试)解决;在线程同步实现中,音效出现异常,最终采用更换设备(设备句柄)解决。另外,图形学的先导课程也对本游戏的开发起了很大的促进作用。

5.3经验教训及其分析

本次课设作品“经典***方块游戏”确实存在一些不足,现罗列如下:

(1)      重新开始按钮未添加。在添加该按钮时,出现了程序逻辑很乱,无法顺利运行的情况,所以最终版本中取消了重新开始按钮。分析原因是,没有理清其中的逻辑顺序。

(2)      背景音乐无法循环播放。播放音乐采用的是Microsoft MCI接口,其中设置循环播放的参数,在VS2017中无法使用,经查找需要加入头文件,再加入头文件后程序出现崩溃,故最后放弃使用。

本次课设确实付出了很多,程序的主体是自己独立设计和实现的,只参考了多线程和MCI接口的资料。同时,在实现过程中,锻炼了我的面向对象思想和设计能力,提高了我的算法的实现和优化能力。最后,感谢教授概要设计课程的袁老师。


 [MS1]人人有事做,事事有人做