MFC扫雷课程设计报告.docx

上传人:b****7 文档编号:26224635 上传时间:2023-06-17 格式:DOCX 页数:20 大小:292.78KB
下载 相关 举报
MFC扫雷课程设计报告.docx_第1页
第1页 / 共20页
MFC扫雷课程设计报告.docx_第2页
第2页 / 共20页
MFC扫雷课程设计报告.docx_第3页
第3页 / 共20页
MFC扫雷课程设计报告.docx_第4页
第4页 / 共20页
MFC扫雷课程设计报告.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

MFC扫雷课程设计报告.docx

《MFC扫雷课程设计报告.docx》由会员分享,可在线阅读,更多相关《MFC扫雷课程设计报告.docx(20页珍藏版)》请在冰豆网上搜索。

MFC扫雷课程设计报告.docx

MFC扫雷课程设计报告

宿迁学院

Windows程序设计

课程考核报告

班级:

学号:

姓名:

得分:

2013年12月20日

1.设计目的及要求1

1.1设计目的及问题描述1

1.2设计要求1

1.3软件、硬件环境1

2.课程设计步骤1

3.课程设计内容1

3.1概要设计2

3.1.1程序总体框架描述2

3.1.2程序常用类声明3

3.2主要技术4

3.3系统设计结果(界面截图、操作流程)13

4.设计总结16

4.1遇到的问题及如何解决16

题目:

扫雷游戏

1.设计目的及要求1.1设计目的及问题描述

系统地学习面向对象编程思想,了解MFC架构,逐步熟悉可视化编程环境VisualC++

并在此环境下设计并实现一个简单扫雷游戏,该扫雷游戏应能实现如下功能:

(1)雷区上部左侧显示总雷数减被标明有雷区域的数目。

(2)雷区上部中间位置显示一按钮用于开局和显示鼠标动作的结果。

(3)雷区上部右侧显示扫雷的时间。

1.2设计要求

(1)能独立搭建可视化程序编程环境,掌握VisualG+6.0的安装、运行和使用。

(2)总体要求:

用面向对象编程的思想与方法,实现一个扫雷游戏的分

析与设计阶段的开发工作,开发工具使用Vsuac+a

(3)编写设计方案,设计过程,源程序文件结构,分析实验方案,并对实验做出总结。

1.3软件、硬件环境

开发工具:

MicrosoftVisualC++6.0软件和Windows2000/XP操作系统

2.课程设计内容

扫雷小游戏的开发与实现

3.课程设计步骤

步骤大致上可以分为三个部分,分别为:

画面初始、游戏者按下第一个方块和为非地雷方块时展开。

画面初始时,以游戏者最后一次设定的地雷区大小为范围画出地雷区,但此时并未产生地雷。

当游戏者按下第一个方块时产生地雷资料并启动定时器,为何在游戏者按下第一个

方块才产生地雷资料呢?

其主要的用意在于不要让游戏者第一次就踩到地雷,这样在某种程

度上可以提高游戏者游玩的气氛。

接着就是如何判断按下的方块是非地雷时的处理,这也是

整个游戏的技术核心,我们可以通过递归的观念来检查周边的方块是否含有地雷及是否继续往外翻开。

3.1概要设计

相信大多数使用Windows操作系统的使用者,对这款游戏都不陌生。

这款游戏不止操作简单,规则也不难,再加上游戏速度的控制机制得宜,让整个游戏在操作过程中充满了快

乐与紧张的气氛。

除了游乐当中能带给使用者快乐之外,游戏的设计内容无形中也不断训练

使用者的逻辑思考能力,对于依靠高度脑力工作的现代人,都可以通过这个游戏,不时的检

验一下自己,所以我们不难发现,在各种可携带的电子产品上都有这款游戏的踪影。

当按下的方块不是地雷,且周边八个方块也都没有地雷时,方块会以被翻开方块的八

个方向将空白方块翻开。

3.1.1程序总体框架描述

扫雷游戏的开发主要包括两大部分:

一个部分是布雷,该部分主要将雷随机布置在游

戏区域内,以避免出现相同的雷区布置地图。

另一部分是扫雷,该部分包括判断鼠标左键点

击某区域该区域是否是雷,如果是雷该如何操作,如果不是雷该如何操作,鼠标右键点击某

区域时如果判断该区域是雷则加以标记,如果不是雷也加以标记,以及当鼠标双击某区域时,

判断与该区域相邻的其它8个区域是否是雷并做一个标记。

图1系统功能图

3.1.2程序常用类声明

首先定义一个雷类:

classLei243//定义一个雷类

{

public:

intweitu;//显示哪一个位图

intshumu;//这个位置相应的值};

接着是在View类添加变量和函数:

intleftnum;//剩下雷数

intleinum;//雷数

intjieshu;//结束

shortsecond;//计时

intsecondstart;//开始计时

CBitmapm_Bitmap[12];//位图数组

CBitmapm_anniu[4];//按扭位图数组

intm_RowCount;//intm_ColCount;//Lei243lei[50][50];//

voidleizero();//

雷区行数

雷区列数

最大雷区

这个位置周围雷数为0

鼠标按下左键

鼠标左键抬起

鼠标按下右键

afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct);afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);//afx_msgvoidOnLButtonUp(UINTnFlags,CPointpoint);//afx_msgvoidOnRButtonDown(UINTnFlags,CPointpoint);//afx_msgvoidOnTimer(UINTnIDEvent);//计时器函数

afx_msgvoidOnStart();//开始函数

3.2主要技术

构造函数:

由于构造函数是程序运行时就执行的,所以,除了对变量赋值之外,游戏的核心结构即内部数组赋值:

先是把全部格子的位图和雷数赋值为机函数按指定雷数赋值为-1,最后把不是雷的格子的雷数赋值为相应的值。

我们还可以把

0,然后调用随

CMy243ztyslView:

:

CMy243ztyslView()

{

//TODO:

addconstructioncodehere

for(intii=0;ii<16;ii++)

m_Bitmap[ii].LoadBitmap(IDB_BITMAP14+ii);

for(intjj=0;jj<4;jj++)

m_anniu[jj].LoadBitmap(IDB_ANNIU1+jj)

second=0;//计时

secondstart=0;//1m_RowCount=25;//m_ColCount=16;//leinum=80;//leftnum=leinum;//jieshu=0;//jieshu=1

intaa=0;

时开始计时

行数

列数

雷数

剩余雷数

时停止

for(inti=0;i

{

for(intj=0;j

{

lei[i][j].shumu=0;lei[i][j].weitu=0;

}

}

CTimetime=GetCurrentTime();

ints;

//初始化为0

//获取当前时间

 

s=time.GetSecond();//获取秒数

do//设置40个雷

{

intk=(rand()*s)%m_RowCount;//以当前秒数为产生随机算法

intl=(rand()*s)%m_ColCount;

if(lei[k][l].shumu!

=-1)//为了避免一个位置同时算两个雷//只允许当前位置不是雷时赋值为雷

{

lei[k][l].shumu=-1;

aa++;

}

}while(aa!

=leinum);

//给方格赋值,计算雷数

for(inta=0;a

for(intb=0;b

if(lei[a][b].shumu==0)

{

for(intc=a-1;c

for(intd=b-1;d

if(c>=0&&c=0&&d

lei[a][b].shumu++;

}

}

界面函数:

现在,可以开始画界面了。

如下函数:

很明显,前面部分是用画的方法画出整个界面,但是,后面for循环显示的位图并不是现在画界面的内容,为什么要写呢?

这是为了用户框重画的需要,当我们的游戏玩了一半后最小化,或是把部分窗口移出屏幕,或是执行了新的应用程序覆盖了原来的程序时,必须重画。

我们调用重画函数,它都要重新执行OnDraw(CDC*pDC)函数,那么,此时它就必须把已经显示出来的位图也显示出来。

而开始时雷区位图是不可见的,并不影响界面的初始化。

voidCMy243ztyslView:

:

OnDraw(CDC*pDC)

{

CMy243ztyslDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

CBrushmybrush1;//画背景mybrush1.CreateSolidBrush(RGB(192,192,192));

CRectmyrect1(0,0,1200,800);

pDC->FillRect(myrect1,&mybrush1);

CBrushmybrush;//画黑框

mybrush.CreateSolidBrush(RGB(0,0,0));

CRectmyrect(20,10,70,40);

pDC->FillRect(myrect,&mybrush);

CRectmyrect2(325,10,375,40);

pDC->FillRect(myrect2,&mybrush);

CPenmypen;

CPen*myoldPen;

mypen.CreatePen(PS_SOLID,2,RGB(255,255,255));

myoldPen=pDC->SelectObject(&mypen);

pDC->MoveTo(20,40);//画黑框的白线

pDC->LineTo(70,40);

pDC->LineTo(70,10);

pDC->MoveTo(325,40);

pDC->LineTo(375,40);

pDC->LineTo(375,10);

for(inti=0;i

for(intj=0;j

{

pDC->MoveTo(10+i*15,50+j*15+14);pDC->LineTo(10+i*15,50+j*15);

pDC->LineTo(10+i*15+14,50+j*15);

}

pDC->SelectObject(myoldPen);

CPenmypen2;

CPen*myoldPen2;

mypen2.CreatePen(PS_SOLID,1,RGB(0,0,0));

myoldPen2=pDC->SelectObject(&mypen2);

for(intii=0;ii

for(intjj=0;jj

{

pDC->MoveTo(10+ii*15,50+jj*15+14);pDC->LineTo(10+ii*15+14,50+jj*15+14);

pDC->LineTo(10+ii*15+14,50+jj*15);

}

pDC->SelectObject(myoldPen2);

CDCDc;

if(Dc.CreateCompatibleDC(pDC)==FALSE)

AfxMessageBox("Can'tcreateDC");

Dc.SelectObject(m_anniu[0]);//显示按钮

pDC->BitBlt(180,10,160,160,&Dc,0,0,SRCCOPY);

for(inta=0;a

数字区//weitu=2显示旗//weitu=3显示问号

for(intb=0;b

{

if(lei[a][b].weitu==1)

{

Dc.SelectObject(m_Bitmap[lei[a][b].shumu]);

pDC->BitBlt(a*15+10,b*15+50,160,160,&Dc,0,0,SRCCOPY);

}

if(lei[a][b].weitu==2)

{

Dc.SelectObject(m_Bitmap[9]);

pDC->BitBlt(a*15+10,b*15+50,160,160,&Dc,0,0,SRCCOPY);

}

if(lei[a][b].weitu==3)

{

Dc.SelectObject(m_Bitmap[10]);

pDC->BitBlt(a*15+10,b*15+50,160,160,&Dc,0,0,SRCCOPY);

}

if(jieshu==1&&lei[a][b].shumu==-1)//结束

{

Dc.SelectObject(m_Bitmap[11]);

pDC->BitBlt(a*15+10,b*15+50,160,160,&Dc,0,0,SRCCOPY);

Dc.SelectObject(m_anniu[3]);

pDC->BitBlt(180,10,160,160,&Dc,0,0,SRCCOPY);

}

}

intnOldDC=pDC->SaveDC();//显示黑框里的数字

pDC->SetTextColor(RGB(255,0,0));

pDC->SetBkColor(RGB(0,0,0));

CFontfont;

if(0==font.CreatePointFont(160,"ComicSansMS"))

{

AfxMessageBox("Can'tCreateFont");

}pDC->SelectObject(&font);CStringstr;

if(leftnum<10)//利用判断显示位数,不够三位前面加0str.Format("00%d",leftnum);

else

str.Format("0%d",leftnum);pDC->TextOut(25,10,str);

if(second<10)str.Format("00%d",second);

elseif(second<100)

str.Format("0%d",second);

else

str.Format("%d",second);pDC->TextOut(330,10,str);pDC->RestoreDC(nOldDC);

}

计时器函数:

OnTimer(UINTnIDEvent)函数,同时也可以实现计时显示。

添加OnCreate(LPCREATESTRUCTlpCreateStruct)和OnTimer(UINTnIDEvent):

intCMy243View:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{

if(CView:

:

OnCreate(lpCreateStruct)==-1)return-1;

//TODO:

Addyourspecializedcreationcodehere

SetTimer(1,50,NULL);//20次为一秒

return0;

}

voidCMy243View:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefaultif(jieshu==1)return;

//显示个数为0的方格leizero();//结束,返回if(secondstart>0)//计时secondstart++;

if(secondstart==20)//二十次为一秒

{secondstart=1;second++;

CRectrect3;rect3.left=325;

rect3.right=375;rect3.top=10;

rect3.bottom=40;

InvalidateRect(&rect3);//重画时间

}

CView:

:

OnTimer(nIDEvent);

开始函数:

点击笑脸图标和开始键都可以重新开始。

voidCMy243ztyslView:

:

OnStart()

{

SetTimer(1,50,NULL);

//TODO:

Addyourcommandhandlercodeheresecond=0;//计时

secondstart=0;//1时开始计时

leftnum=leinum;//剩余雷数jieshu=0;//jieshu=1时停止intaa=0;

for(inti=0;i

{

for(intj=0;j

{

lei[i][j].shumu=0;

lei[i][j].weitu=0;

}

}

do//设置40个雷

{

intk=rand()%m_RowCount;

intl=rand()%m_ColCount;

if(lei[k][l].shumu!

=-1)

{

lei[k][l].shumu=-1;

aa++;

}

}while(aa!

=leinum);

for(inta=0;a

for(intb=0;b

if(lei[a][b].shumu==0)

{

for(intc=a-1;c

for(intd=b-1;d

if(c>=0&&c=0&&d

lei[a][b].shumu++;

}//给方格赋值

Invalidate();

}

3.3系统设计结果(界面截图、操作流程)

1)游戏开始界面。

图2游戏初始界面

2)我们可以点击开始游戏。

图3点击开始游戏

3)点击小方块游戏开始并计时。

图4开始扫雷

4)可以右击标机雷的位置,这样雷的个数会减少。

图5标机雷的位置

 

5)当点到雷时,游戏结束停止计时。

羽24浊引.

1

1|«

.4

:

*

1|

1|2

2

1

11

1

1

1

|1

1

»:

1

1

o

>

1

11

Z

1

I

2

Z

1|

1

1|

Z

>

r

LLI

1

b

±1

1

9

Z\2

2

2

Wl

«

.・

*1

*

4

A

图6踩到地雷

 

6)可以点笑脸或开始重新开始游戏。

图7新的一局游戏

4.设计总结

随着扫雷游戏的开发完成,本游戏中预期的主要功能也基本实现。

本系统以

VisualC++6.0作为前台开发工具,VisualC++6.0以简单、易用等优点成为开发本系统的首选工具。

本论文阐述了扫雷游戏的分析与设计的全过程,并在论文中相应的位置插入了图片、流程图以及一些具有技巧性的程序代码,更加清晰的描述了该游戏是如何实现的。

扫雷游戏是一款益智类游戏,该游戏与那些网络游戏和3D游戏相比,它有编写简单容易上手等特点,非常适合人们在完成工作的时候适当的娱乐要求。

这些小游戏大都是以益智和娱乐为目的,不仅给紧张工作的人们以放松,还可以让人们的大脑得到开发。

由于我学习VisualC++6.0的时间比较短,其中的很多知识还没有了解和掌握,在扫雷游戏中有些功能还不够完善,例如在扫雷游戏中不能实现玩家成绩的排名。

希望在以后的工作和学习中不断的充实自己的知识结构,把扫雷游戏的功能进一步完善,使它成为一个更具有实用价值的游戏软件,同时也恳请老师给予批评指正。

4.1遇到的问题及如何解决

在程序写好后运行游戏时发现以下问题:

1.游戏中显示的位图错乱。

2.在点击笑脸重新开始时出现错误,只显示一个雷。

解决方案:

1.重新把位图的ID检查一下,发现ID有错误,改之。

2.在OnStart()函数中初始化雷后,再重新步地雷的代码书写错误,及时改正了过来。

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

当前位置:首页 > 医药卫生 > 临床医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1