收藏 分享(赏)

俄罗斯方块设计步骤.doc

上传人:dzzj200808 文档编号:2532602 上传时间:2018-09-21 格式:DOC 页数:25 大小:105KB
下载 相关 举报
俄罗斯方块设计步骤.doc_第1页
第1页 / 共25页
俄罗斯方块设计步骤.doc_第2页
第2页 / 共25页
俄罗斯方块设计步骤.doc_第3页
第3页 / 共25页
俄罗斯方块设计步骤.doc_第4页
第4页 / 共25页
俄罗斯方块设计步骤.doc_第5页
第5页 / 共25页
点击查看更多>>
资源描述

1、综合实例俄罗斯方块1. 问题描述屏幕中央有一个矩形容器,程序刚开始时是空的;当鼠标单击“开始”菜单时,矩形容器内从上向下随机出现俄罗斯方块的部件。通过键盘上的左右键分别左右移动部件(一个单位),向上键顺时针旋转 90 度。当部件到达容器底部或已停止的部件上时,停止;当容器的同一行被部件填满时,该行消失。其他行依次向下移动。计分方法:一次消去一行 100 分,同时消去行、3 行或 4 行分别为 300、500 和 900 分。在适当位置显示当前累计分。当部件总行数超过矩形容器高度时,提示“游戏失败”信息并停止。设有三个级别的游戏难度供选择。难度越大、下落越快。2. 编程要求(1)屏幕中央有一个矩

2、形容器,选择“开始”菜单,俄罗斯方块的部件随机产生并在容器中从上向下下落。(2)有七种标准俄罗斯方块部件,并随着键盘上的左右键分别左右移动,随着键盘上的向上键分别顺时针旋转 90 度。(3)当部件到达容器底部或已停止的部件上时,停止;当同一行部件完整拼接上时,该行消失,其他行向下移动,在适 当位置显示当前累计分。(4)当部件总行数超过矩形容器高度时,提示“游戏失败”信息并停止。3. 要点分析本题主要涉及到的知识点有:键盘消息、菜单、随机函数、定时器和序列化。同时也需要有画笔/画刷使用,动态存储空间的分配与回收等工作,难度偏大。该题的部件以及已经停止的部件均用小方格来表示。整个游戏区域对应一个二

3、维数组,数组为 0 时,表示空白,为 1 时表示已有方格。该数组存储所有已经不能再移动的部件。部件采用一维数组来表示,这些一维数组实际是一个 nn 的矩阵。如表示一个方块使用一个22 的矩阵,实际存储为(1, 1, 1, 1);则表示一个长条使用一个44 的矩阵,实际存储为(0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0)。实际显示的时候,先画出已停止的方格,然后换算出正在下落的部件的正确坐标位置并将其画出。旋转部件时,变换存储部件的矩阵,使其对应为旋转后的形态。判断部件是否可以下落、旋转、左移或右移时,将表示部件的数组对应到游戏区域的二维数组中,再判断是否允许改操作。当

4、部件无法再动时,将部件数组中对应项填入游戏区域对应的二维数组中。使一层消失可以通过判断游戏区域的二维数组是否某一行全为1;如果该数组的第一行有一项为 1 或者已没有空白使新的部件可以加入到游戏区域中,则游戏结束。3. 解题步骤(1)首先用 AppWizard 生成一个名为 RusBlock 的 SDI 程序框架,其他选项均可用缺省设置。(2)在“Resource View”中选择 Menu 资源项中的菜单ID“IDB_MAINFRAME”,双击,增加“游戏”菜单,并在其中增加“开始”和“结束”菜单;再增加“难度”菜单,在其中添加“容易”、“普通”和“较难”菜单,如下表 1,设置了菜单的属性。利

5、用ClassWizard 自动添加菜单的 Command 消息处理函数。表 1 菜单属性ID Caption PromptID_GAME_START 开始 游戏开始ID_GAME_END 结束 游戏结束ID_LEVEL_EASY 容易 ID_LEVEL_NORMAL 普通 ID_LEVEL_HARD 较难 (3)在视图类上单击鼠标右键,打开“Add Window Message Handler”对话框,添加键盘和定时器事件。(4)完成以上工作后,即可在生成的程序框架中添加必要的代码。源程序清单:(1)在视图类的头文件中定义宏、类成员变量和自定义类成员函数。#define MAXCOM 7 /

6、部件数#define WIDE 13 / 游戏区域宽#define HIGH 26 / 高#define SIZE 12 / 组成游戏区域的方格大小#define TOP 50 / 游戏左上角坐标#define LEFT 50#define EASY 500 / 游戏难度#define NORMAL 300#define HARD 200typedef struct tagComponetint intComID; / 部件的 ID 号int intDimension; / 存储该部件所需的数组维数int * pintArray; / 指向存储该部件的数组 Componet;class CRu

7、sBlockView:public CView/此处略去若干行系统生成的代码private:int m_intComID; / 当前下落的部件int m_intState HIGH WIDE; / 当前状态Componet m_Componets MAXCOM; / 所有部件的内部表示int m_intScore; / 分数int m_intLevel;Componet m_CurrentCom; / 当前的部件POINT ptIndex; / 部件数组在全局数组中的索引void NewComponet (void); / 产生一个新的部件bool CanDown (void); / 是否还可

8、以下落void MyInvalidateRect (POINT ptStart, int intDimension); / 刷新函数void Disappear (void); / 消去行bool CheckFail (void); / 判断游戏是否结束bool CanRotate (void); / 是否还可以旋转bool CanLeft (void); / 是否还可以左移bool CanRight (void); / 是否还可以右移/检查是否有足够的空位显示新的部件,否则游戏结束bool CanNew ( );(2)在类构造函数中创建记录部件形状的数组。CRusBlockView:CRus

9、BlockView()for (int i = 0;i SelectObject (pDC - Rectangle (LEFT - 1, TOP - 1, LEFT + WIDE * SIZE + 1,TOP + HIGH * SIZE + 1);/ 画不能移动的方块CBrush brushStick (RGB (127, 127, 127) );pDC -SelectObject(for (int i=0; i Rectangle (LEFT + SIZE * j, TOP + SIZE * i, LEFT + SIZE * (j + 1),TOP + SIZE * (i + 1) );/

10、画下落的部件if (m_CurrentCom. intComID = 0)CBrush brushCom (RGB (0, 255, 0) );pDC - SelectObject (int intDimension=m_CurrentCom. intDimension;for (int i=0; i Rectangle (LEFT + SIZE * n, TOP + SIZE * m, LEFT + SIZE * (n + 1),TOP + SIZE * (m + 1) ;/ 显示得分CString strOut;strOut. Format (“得分 % d“, m_intScore);p

11、DC - TextOut (LEFT + WIDE * SIZE + 50, TOP + 100, strOut);(5)在定时器消息处理函数中添加代码:void CRusBlockView:OnTimer(UINT nIDEvent) int intDimension = m_CurrentCom. intDimension;if (CanDown ( ) ) / 可以下落/ 擦除MyInvalidateRect (ptIndex, intDimension);/ 下落ptIndex. x +;/ 显示新位置上的部件MyInvalidateRect (ptIndex, intDimensio

12、n);elsefor (int i=0; i= HIGH | m_intState mn = 1) / 被挡住或出游戏区域boolDown=false;return boolDown;/ 可以左移bool CRusBlockView : CanLeft (void)bool boolLeft = true;int intDimension = m_CurrentCom. intDimension;POINT ptNewIndex = ptIndex; / 假设可以左移ptNewIndex. y -;for (int i=0; i= WIDE | m_intState m n = 1) / 被挡

13、住或出游戏区域boolRight = false;return boolRight;/ 可以转动bool CRusBlockView : CanRotate (void)bool boolRotate = true;int intDimension = m_CurrentCom. intDimension;POINT ptNewIndex = ptIndex;/ 假设可以转动/ 新的矩阵存储转动后的部件int * pintNewCom = new int intDimension * intDimension;/ 顺时针转动并判断for (int i=0; i= WIDE | m = HIGH

14、) / 被挡住或出游戏区域 boolRotate = false;delete pintNewCom;return boolRotate;/ 可以产生新的部件bool CRusBlockView : CanNew (void)bool boolNew = true;int intDimension = m_CurrentCom. intDimension;POINT ptNewIndex = ptIndex; / 假设可以for (int i = 0; i = 0; i -)bool boolLine = true;for (int j = 0; j 0; m -)for (int n = 0

15、; n 0)m_intScore += (intLine - 1) * 200 + 100;InvalidateRect (CRect (LEFT + WIDE * SIZE + 50,TOP + 100, LEFT + WIDE * SIZE + 200, TOP + 200) );InvalidateRect (CRect (LEFT, TOP, LEFT + WIDE * SIZE, TOP + HIGH * SIZE) );(10)添加菜单的消息代码:void CRusBlockView:OnGameStart()for (int i = 0; i LEFT? x1: LEFT;int

16、 y1 = TOP + ptStrat. x * SIZE;y1 = y1 TOP? y1: TOP;int x2 = LEFT + (ptStrat. y + intDimension) * SIZE;x2 = x2 LEFT + WIDE * SIZE? LEFT + WIDE * SIZE: x2;int y2 = TOP + (ptStrat. x + intDimension) * SIZE;y2 = y2 TOP + HIGH * SIZE? TOP + HIGH * SIZE: y2;InvalidateRect (CRect (x1, y1, x2, y2) );输入/输出:游戏时,程序的界面和运行效果图如下图 12.18、12.19 所示。图 12.18 程序界面图 12.19 运行效果图小结:本题较为繁杂,主要是对各种情况的判断要正确。此外,在动态分配内存时要格外小心,出错时容易引起系统的异常。进一步工作:本程序实现了一个初步的俄罗斯方块游戏,但还是有些功能未实现,如向下的加速键(通常为向下的方向键)。此外,一般的俄罗斯方块游戏在下落一个部件的时候,会将下一个将要下落的部件也显示在旁边,这该如何实现?请读者自行添加代码来完成。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报