MFC俄罗斯方块
经典俄罗斯方块游戏
源码百度云链接
链接:https://pan.baidu.com/s/14frk2EuFoiRCzudol2Xgvg
提取码:syzkGitHub
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]人人有事做,事事有人做
MFC俄罗斯方块的更多相关文章
- 还是俄罗斯方块之android版
前面的,口水话 请直接跳过. 虽然现在不比以前了 也没多少人气了,放到首页 都不到几百的点击量.也许博客园整体水平也是在往水的方向发展.不谈那些了,哥也曾经辉煌过 有过一天上千的点击量 ,哥也曾经有过 ...
- 带AI的俄罗斯方块源码
好久没写俄罗斯方块的游戏了.从学习编程到现在,相继用Win32 API.MFC.C.C#.JS.iOS写过大约二十款左右的俄罗斯方块游戏.最近用Cocos2d-x写了一下,第一次完全将游戏逻辑与UI层 ...
- 【MFC三天一个游戏】之 局域网黑白棋
欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 花了三天上班时间,妈的上班写就是不能静下心来,擦,要防BOSS巡山.... 以前也写过 ...
- vs2010静态链接MFC库报链接错误
由于需要将MFC程序在其它电脑上运行,所以需要将动态链接的MFC改成静态链接,本以为很简单,没想到链接的时候出现下面的链接错误: uafxcw.lib(afxmem.obj) : error LNK2 ...
- MFC中成员变量的声明顺序与析构顺序
第一次用博客,第一篇随笔,就写今天遇到的一个问题吧. 在VS2008的MFC对话框程序,窗口成员变量的声明顺序与其析构顺序相反,即,先声明的变量后析构,后声明的变量先析构.未在其他模式下测试. cla ...
- VC中的MFC到底是什么?
1. 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API ...
- MFC&Halcon之实时视频监控
上一篇实现了在MFC的窗体内显示图片,本篇介绍如何在MFC窗体内实时显示摄像头的影像. 要实现的功能是点击一个“开始”按钮,可以显示影像,再点击“停止”按钮,可以停止显示. 因为实时显示影像需要在一个 ...
- x01.Tetris: 俄罗斯方块
最强大脑有个小孩玩俄罗斯方块游戏神乎其技,那么,就写一个吧,玩玩而已. 由于逻辑简单,又作了一些简化,所以代码并不多. using System; using System.Collections.G ...
- MFC快速入门 - 菜单
本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6231104.html 打开VS2010,依次打开File – New – Proje ...
随机推荐
- Andorid之页面布局优化
文章大纲 一.为什么要进行页面布局优化二.页面布局优化实操三.项目源码下载四.参考文章 一.为什么要进行页面布局优化 在开发Android时,会遇到某些是通用的布局,我们常将一些通用的视图提取到一 ...
- 运维DBA要不要学python
运维DBA要不要学python 我个人认为是:要 现在python在运维数据库的工作中主要用在 1.编写一些运维脚本 2.编写运维管理平台 3.研究互联网大厂的运维脚本/工具并应有 特别是运维开源数据 ...
- Agent Job代理 执行SSIS Package
摘要: 在使用Agent Job时, 运行SSIS包的Run as账号,必须有SSIS中connection manager的连接权限. 如果没有连接权限,可以用创建proxy账号,并确保proxy账 ...
- Python初识+条件语句+循环语句
一.写照: 1.第一个程序 hello world print('hello world') 后缀名可以是任意(只是现在)(lx.py lx.ps) 导入模块时不是.py 就会出错 2.解释器路径 # ...
- Linux如何管理文档多租户
例题 同一群组microsoft下的两个账号justmine001和justmine002需要共同拥有目录/microsoft/eshop的开发权,以便进行协同工作,但是其他人不允许进入和查阅该目录. ...
- 你可能需要为你的 APP 适配 iOS 11
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...
- 事务,Oracle,MySQL及Spring事务隔离级别
一.什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 二.事务特性(4种): 原子性 (atomicity):强调事务的不可分割:一致性 (consiste ...
- mysql中截取指定字符前后的字符串
使用SUBSTRING_INDEX()函数substring_index(str,delim,count) str:要处理的字符串 delim:分隔符 count:分隔符计数 例子取出上述表中数组的第 ...
- AI - TensorFlow - 分类与回归(Classification vs Regression)
分类与回归 分类(Classification)与回归(Regression)的区别在于输出变量的类型.通俗理解,定量输出称为回归,或者说是连续变量预测:定性输出称为分类,或者说是离散变量预测. 回归 ...
- 每日分享!~ vue JavaScript中为什么可以读取到字符串的长度!(包装对象)
首先需要知道什么是包装对象? 对象是JavaScript语言下最主要的数据类型,三种原始的值-----数值,字符串,布尔值,在一定条件下会自动的转为对象.也就是原始类型的包装对象: 也就是通过如下方式 ...