嵌入式大作业连连看文档Word文档下载推荐.docx
《嵌入式大作业连连看文档Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《嵌入式大作业连连看文档Word文档下载推荐.docx(34页珍藏版)》请在冰豆网上搜索。
如何设置整个游戏的界面;
如何控制连连看游戏中随机图片的生成且每种图片必须为偶数个;
游戏开始后,判断鼠标两次点击的图片能否消去,即图片是否相同且图片之间路径的判断
1.1.4、需求分析
整个游戏程序通过在处理鼠标响应事件中伴随着绘图。
程序通过调试运行,实现了设计目标,能够满足连连看游戏玩家的需要,关于连连看的功能描述如下:
运行游戏并进行初始化工作,将整个游戏区域分成纵向和横向扩展的若干个小方块,并且这些小方块是由多种动物图案成对地分布于游戏区域的不同位置。
玩家可以通过选取相同的两个物件来对它们进行消除的操作,直到将游戏区域中的所有方块对都被消除后为胜利
1.2、总体设计
1.2.1、系统的开发环境
●Intel(R)Core(TM)i5-2430M4G内存500G硬盘
●MicrosoftWindows7
●MicrosofteMbeddedvisualC++4.0
●NewEmulator_SDK
1.2.2、系统的总体功能
1.2.3、系统的结构及模块
1.2.4、功能说明
1)游戏地图设计
对于整个游戏区域,可以把它看作一个是由若干个小方块构成的地图,而且每一个小方块放置着不同的动物图案,可将其称之为图案小方块。
这些图案小方块零散地分布在地图的不同位置区域,并且每一个图案小方块都有与其对应的完全一样的另外一个小方块,整个游戏游戏区域被抽象成一个有坐标位置属性的平面,平面上零散地分布着若干个小方块,并且这些小方块的物种起码是成对出现的。
经过前面的描述和分析后,可以把游戏区域地图用一个数组m_Player;
来表示。
m_Player;
是把地图设计成一个动态分配的int整形一维数组,对地图中的行列数的表达,用一个转换法则即可。
可以在PocketLianDlg类对象定义中添加地图核心数据的成员变量,具体如下:
//地图位置相关属性组
int*m_Player;
//动态地图数据头指针(一维数组)
intm_nRow;
//地图的行数(虚拟)
intm_nCol;
//地图的列数(虚拟)
2)初始化游戏界面
该部分主要由执行窗口创建函数及位图加载函数来实现。
通过数据的初始化及位图资源的加载为用户呈现一个游戏初始的界面。
3)图片的选择
该功能主要由鼠标来完成。
在OnLButtonDown()事件函数中通过鼠标的点击事件选取所要消除的两个相同图片。
4)图形的判断与消除
对于第
(2)步所选的两个图片,对其连通性进行判断:
如果两图片直线连通,则相互消去;
如果两图片连接为一个拐点且相通,则相互消去;
如果两图片连接为两个拐点且相通,则相互消去;
否则,不能消去。
5)判断游戏是否死锁或结束
如果所有的图片全部消去,则提示“游戏结束!
”的信息。
当游戏玩家不可能在消去任意两个图片时,游戏进入死锁状态。
此时提示相关信息
二、系统的详细设计
2.1、游戏地图设计
经过前面的描述和分析后,可以把游戏区域地图用一个数组m_Player来表示。
m_Player是把地图设计成一个动态分配的int整形一维数组,对地图中的行列数的表达,用一个转换法则即可。
上面的成员变量中定义了一个整形指针标量m_Player,用于记录动态分配出来的一维数组地图空间的首地址。
对于地图区域中的某个小方块的类型,可以用一个整形的ID来进行识别。
这里为标识地图的行列位置分别添加m_nRow和m_nCol变量,到此,地图的数据结构已经设计好。
在PocketLianDlg类的构造函数对地图数据进行相关的初始化:
#defineROWCOUNT7//7//8//9
#defineCOLCOUNT12//12//14//16
CPocketLianDlg:
:
CPocketLianDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CPocketLianDlg:
IDD,pParent)
{
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
m_nY1=-1;
m_nX1=-1;
m_nRow=ROWCOUNT;
m_nCol=COLCOUNT;
m_Player=newint[m_nRow*m_nCol];
}
~CPocketLianDlg()
delete[]m_Player;
PocketLianDlg类对象的实现中,定义了一些关于地图行列数的宏,如ROWCOUNT和COLCOUNT,并且在PocketLianDlg类对象的构造函数中,进行了行列的真实确认赋值,并根据当前行列数的大小对地图数据空间进行动态创建。
因为地图数据是用new在堆栈动态创建的,所以在销毁该对象时要将这些内存空间释放,见代码所示在PocketLianDlg类对象的析构函数中调用delete将m_Player指向的所有空间都释放掉。
2.2、初始化界面
首先调用CenterWindow()函数创建一个居中的窗口,再执行m_bitmap.LoadBitmap()函数来加载指定的位图资源,然后通过调用m_MemDC.CreateCompatibleDC()创建一个与指定设备兼容的内存设备上下文环境(DC),再调用CreateCompatibleBitmap()函数创建与指定的设备环境相关的设备兼容的位图;
最后调用FillMemDC()函数填充所创建的窗口。
该部分的实现代码下:
BOOLCPocketLianDlg:
OnInitDialog()
{
CDialog:
OnInitDialog();
SetIcon(m_hIcon,TRUE);
SetIcon(m_hIcon,FALSE);
CenterWindow(GetDesktopWindow());
//创建一个居中的窗口
m_bitmap.LoadBitmap(IDB_BITMAP_129);
//加载指定的位图资源
CClientDCdc(this);
//创建一个与指定设备兼容的内存设备上下文环境
m_MemDC.CreateCompatibleDC(&
dc);
CBitmapbitmap;
bitmap.CreateCompatibleBitmap(&
dc,m_nCol*FRONTWIDTH+5,m_nRow*FRONTHEIGHT+5);
//创建与指定的设备环境相关的设备兼容的位图
m_MemDC.SelectObject(&
bitmap);
intn=GetTickCount();
srand(n);
//time(NULL));
CDWordArrayarPlayer;
for(inti=0;
i<
(m_nCol*m_nRow)/4;
i++)
for(intj=0;
j<
4;
j++)
arPlayer.Add(i);
for(i=0;
m_nRow*m_nCol;
{
intnIndex=(int(rand()*0.1+rand()*0.01+rand()))%arPlayer.GetSize();
m_Player[i]=arPlayer.GetAt(nIndex);
arPlayer.RemoveAt(nIndex);
}
FillMemDC();
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
2.3、图形的判断与消除
在检验两个方块能否消掉的时候,我们要让两个方块同时满足两个条件才行,就是两者配对并且连线成功。
对于选中的两个图片的销毁,它们必须符合下面3个条件:
(1)选中的两个图片图案相同。
(2)选中的两个图片之间没有障碍物阻碍的情况下,可以用若干个垂直的直线线段连接起来。
(3)这些将它们连接起来的直线线段的折点不超过两个(连接线由x轴和y轴的平行线组成)。
现在针对
(2)和(3)进行分析,同种物件的连接方式大致可以分成以下3种:
(1)直接方式
(2)有一个折点的垂直线段连接。
(3)有两个折点的垂直线段连接.。
1.直接连接方式
或
在直接连接方式中,必须要求所选定的两个方块在同一水平直线上(可以为x方向或y方向),并且两个方块之间没有任何其他图案方块。
2.一个这点连接方式
所选定的两个方块如果通过折点的方式连接,那么对于折点来说,每个折点必定有且至少有一个坐标(x或y)是和其中一个目标点相同的,即折点必定在两个目标点所在的x方向或y方向的直线上。
此外,对于一个折点连接的情况,折点应该为第一个选中方块的横向线或纵向线与第二个选中方块的纵向线和横向线相交而得出。
3.两个折点的连接方式
或
这种方式的两个折点所连成的直线与两物件的直接连线可以构成平行线,因此可以根据这个规律,将这条水平线在游戏区域允许的条件上下移动,然后通过判断整条带垂直折线点的曲线之间有无障碍物方式来确定是否可以连同。
这种情况可以分为两种情况:
(1)选中的两图案方块在同一直线,两折点间的直连线可在其这两个方块之间的空间位置作移动,其约束是不超过游戏边界区域。
(2)选中的两图案方块不在同一直线,两折点间的直连线可在两个方块之间的空间位置作移动,其约束是两方块之间的区域。
经过上面详细的分析后,可以对选定的两方块是否可以作抵消操作可以这样设计下去。
首先,对简单的直接连情况进行判断,看其是否符合条件,假如不能,再加深一个级别的复杂度,对一个折点的情况进行判断,依次类推
具体判断流程图为:
2.4、鼠标交互功能
对于用户交互的实现,这里选择鼠标交互方式。
下面简单描述一下通过鼠标交互方式实现的功能。
鼠标选取两个图案方块后,程序将自动判断所选定的两个方块是否能进行抵消操作,能则进行抵消操作。
在游戏过程中,我们不断重复上面描述的功能,直到游戏的胜利结束。
下面将鼠标事件处理工作归纳为如图所示的流程
下面将按照流程的子功能模块的划分方式,对整个功能模块的具体协调和实现过程进行简单的描述。
(1)首先,利用鼠标的当前坐标位置point对每个小单元方块的宽度FRONTWIDTH和高度FRONTHEIGHT分别取模,获取当前鼠标落点所在的游戏区域的具体行列数(x,y)。
(2)判断出该行列数(x,y)是否符合条件。
保证运算出来的行数x和列数y的预定义区域最大的行数m_nCol和列数m_nRow内,并且点击的区域状态不是空白方块区域
(3)对判断此次鼠标书剑的选取是否与第一个方块的选取一样,只需通过用于记录第一个被选中的方块的行列数的成员变量m_nX1是否为有效即可。
这里将m_nX1以及m_nY1来记录它所在的行、列数,并且每次经过判断后都会将它们的状态恢复为空白无选中状态BLANK_STATE。
关于这两个用作记录第一个选中图案方块行列数的成员变量,在对话框类中的具体定义如下所示:
intm_nX1;
//鼠标选中的记录方块列数
intm_nY1;
//鼠标选中的记录方块行数
(4)对于本次选中的方块为第一选中的情况,先用m_nX1和m_nY1对当前的选中方块位置做记录,然后直接在屏幕的该区域绘制图像,为该方块区域添加一个红色的矩形外边框,用以提示用户当前的第1个图案方块选中所在的位置。
需要注意的是,对于标记方块的加亮边框绘制是通过GetDC()函数来获取对话框窗体(屏幕)的设备环境,对绘制的图像数据没有作历史记录的方式来绘制的。
(5)在这一处理中,对该选定方块作一些判断,以便更高效地处理。
判断选中的方块与前一方块是否为同一图案方块,并且此次选择不与上一次选定的方块为同一方块,然后才跳到下一步对两个选定的方块是否可以抵消的流程中去。
(6)调用前面已经实现的答功能函数IsLink()来判断当前所选定的两个图案方块是否可以抵消。
(7)如果可以抵消,对选中的两个方块在内部核心地图对应的数据状态作适当的修改,将它们的状态记作已经被销毁的空方块状态BLANK_STATE。
(8)完成第二个图案的选取与相关的功能操作后,我们需要前面已经选去第1个方块位置的记录作清理工作,以便下一个新方块的选择。
(9)最后,判断此次的鼠标操作是否已经胜利结束,如果是则给予用户结束提示,否则继续。
5、游戏结束
要判断游戏的结束,只需对地图中的所有区域的状态进行检测就可以了,若检测到地图中所有的图片都被消除,则证明游戏结束。
IsWin()
//检测所有是否尚有非未被消除的方块
for(inti=0;
{
if(m_Player[i]>
=0)
{
returnfalse;
}
returntrue;
三、系统实现与调试
3.1、调试过程
刚开始调试程序时出现错误如图:
解决方法:
当安装的文件目录查找文件,然后拷贝文件地址MicrosofteMbeddedvisualC++4.0下的菜单栏tool—>
Options—>
Directories如图
调试程序时再次出现错误如图:
当安装的文件目录查找文件,找到文件然后把查找的文件名分别修改为mfcee400d.lib—>
mfcce500d.libolecc500d.lib——>
olecc500d.lib
3.2、系统运行的结果
1)、初始界面截图
2)、相邻图像的消除和边界双折线图像的消除
3)、图像选定的标志
4)、单折线图像的消除
5)、游戏结束
四、附有程序代码打印
PocketLianDlg.cpp程序代码:
//PocketLianDlg.cpp:
implementationfile
#include"
stdafx.h"
PocketLian.h"
PocketLianDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
#defineBKCOLORRGB(128,128,128)
#defineFRONTWIDTH(39+2)
#defineFRONTHEIGHT(39+12)
#defineBKWIDTH46
#defineBKHEIGHT56
#defineROWCOUNT7//7//8//9
/////////////////////////////////////////////////////////////////////////////
//CPocketLianDlgdialog
//{{AFX_DATA_INIT(CPocketLianDlg)
//NOTE:
theClassWizardwilladdmemberinitializationhere
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
voidCPocketLianDlg:
DoDataExchange(CDataExchange*pDX)
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPocketLianDlg)
theClassWizardwilladdDDXandDDVcallshere
//}}AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CPocketLianDlg,CDialog)
//{{AFX_MSG_MAP(CPocketLianDlg)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CPocketLianDlgmessagehandlers
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'
smainwindowisnotadialog
//Setbigicon
//Setsmallicon
//centertothehpcscreen
//TODO:
Addextrainitializationhere
//ZeroMemory(m_Player,sizeof(m_Player));
FillMemDC()
CDCMemDC;
MemDC.CreateCompatibleDC(&
CBitmapbitmap1;
bitmap1.LoadBitmap(IDB_BITMAP_129);
MemDC.SelectObject(&
bitmap1);
m_MemDC.Fill