核心代码.docx
《核心代码.docx》由会员分享,可在线阅读,更多相关《核心代码.docx(19页珍藏版)》请在冰豆网上搜索。
核心代码
六.核心代码计科系0901班
1扫雷游戏的界面实现陈金林20091080605031
在扫雷游戏中,通过如下几步即可实现添加游戏的菜单。
(1)在扫雷游戏工程的资源中添加一个菜单资源,其属性如表4所示。
ID
类别
说明
IDR_MAIN_MENU
弹出菜单
游戏的主菜单
IDR_START_GAME
菜单栏
开始游戏
IDM_COLOR
选择菜单
背景更换
IDR_EXIT_GAME
菜单栏
退出游戏
IDR_PLAY_MUSIC
选择菜单
播放音乐
IDR_HELP
菜单栏
帮助
IDR_ABOUT
菜单栏
关于
(2)给每个菜单栏添加响应函数到CMineDlg类中。
(3)菜单响应函数的实现,如代码1所示。
代码1菜单响应函数的实现
01BEGIN_MESSAGE_MAP(CMineDlg,CDialog)
02ON_WM_SYSCOMMAND()
03ON_WM_PAINT()
04ON_WM_QUERYDRAGICON()
//菜单资源与函数映射表
05ON_COMMAND(IDR_ABOUT,OnAbout)
06ON_COMMAND(IDR_EXIT_GAME,OnExitGame)
07ON_COMMAND(IDR_HELP,OnHelp)
08ON_COMMAND(IDR_PLAY_MUSIC,OnPlayMusic)
09ON_COMMAND(IDR_START_GAME,OnStartGame)
10END_MESSAGE_MAP()
12BOOLCMineDlg:
:
OnInitDialog()//初始化对话框
13{
14CDialog:
:
OnInitDialog();
15
16m_bStart=FALSE;//设置游戏状态
17
18InitMenu();//初始化菜单
19
20returnTRUE;//初始化成功
21}
22...//省略部分代码
23voidCMineDlg:
:
OnOK()//单击"确认"按钮响应函数
24{
25CDialog:
:
OnOK();
26}
28voidCMineDlg:
:
OnCancel()//单击"退出"按钮响应函数
29{
30CDialog:
:
OnCancel();
31}
33voidCMineDlg:
:
OnAbout()//关于菜单栏响应函数
34{
35CAboutDlgdlg;//创建关于对话框
36dlg.DoModal();//弹出关于对话框
37}
39voidCMineDlg:
:
OnExitGame()//退出菜单栏响应函数
40{
41CDialog:
:
OnCancel();//调用基类退出函数
42}
44voidCMineDlg:
:
OnHelp()//帮助菜单栏响应函数
45{
46CHelpDlgdlg;//创建帮助对话框
47dlg.DoModal();//弹出帮助对话框
48}
2游戏帮助对话框的实现
扫雷游戏中的帮助是使用一个对话框来实现的。
其实现步骤如下。
(1)添加一个对话框资源到工程中,并填写说明文字,如图1所示。
图1帮助对话框
(2)编写一个CHelpDlg对话框类,主要是加载IDD_HELP对话框资源。
通过资源中的文字说明对游戏操作方法进行描述。
同时只包含单击"知道了"按钮的响应函数。
其类声明如代码2所示。
代码2CHelpDlg对话框类声明
01//CHelpDlg对话框类
02classCHelpDlg:
publicCDialog//公共继承于CDialog类
03{
04public:
05CHelpDlg(CWnd*pParent=NULL);//构造函数
06//对话框资源
07enum{IDD=IDD_HELP};//加载资源
08//重载函数
09protected:
10virtualvoidDoDataExchange(CDataExchange*pDX);
11protected:
12virtualvoidOnOK();//单击"确定"按钮响应函数声明
13DECLARE_MESSAGE_MAP()
14};
(3)CHelpDlg对话框类的实现,需要实现对话框类的构造函数、析构函数和"知道了"按钮响应函数,其代码如代码3所示。
代码3CHelpDlg对话框类的实现
00//CHelpDlg对话框类实现
01CHelpDlg:
:
CHelpDlg(CWnd*pParent/*=NULL*/)//构造函数
02:
CDialog(CHelpDlg:
:
IDD,pParent)
03{
04}
05voidCHelpDlg:
:
DoDataExchange(CDataExchange*pDX)
06{
07CDialog:
:
DoDataExchange(pDX);
08}
09BEGIN_MESSAGE_MAP(CHelpDlg,CDialog)
10END_MESSAGE_MAP()
11//CHelpDlg消息响应函数
12voidCHelpDlg:
:
OnOK()//单击"知道了"按钮响应函数
13{
14CDialog:
:
OnOK();
游戏英雄榜对话框的实现
扫雷游戏英雄榜的实现,分为如下几步:
(1)创建一个对话框资源,并添加相应的控件,如图2所示。
图2英雄榜对话框资源
(2)添加CHeroDlg类,其中需要包含IDD_HERO_DLG对话框资源和"设置可写记录标志"接口函数声明,用于外部函数调用时,设置是否对配置文件进行写操作。
类的声明如代码4所示。
代码4
00//CHeroDlgdialog
01classCHeroDlg:
publicCDialog
02{
03public:
04voidSetWriteFlg(BOOLbflg);
//接口函数,设置可记录标志变量
05CHeroDlg(CWnd*pParent=NULL);//构造函数
06enum{IDD=IDD_HERO_LIST};//对话框资源
07intm_time;//保存时间变量
08CStringm_name;//保存姓名变量
09public:
10virtualintDoModal();//弹出对话框函数声明
11protected:
12virtualvoidDoDataExchange(CDataExchange*pDX);
13protected:
14virtualvoidOnOK();//单击"久仰"按钮响应函数声明
15DECLARE_MESSAGE_MAP()
16private:
17BOOLm_bWriteflg;//记录标志变量
18};
(4)CHeroDlg类的实现中通过调用系统API函数,来对配置文件进行读写操作。
而"设置读写标志"接口函数,是对类的一个成员变量m_bWrite进行赋值操作,达到写入或者读取的区分。
其代码如代码5所示。
代码5CHeroDlg类的实现
00CHeroDlg:
:
CHeroDlg(CWnd*pParent/*=NULL*/)//构造函数
01:
CDialog(CHeroDlg:
:
IDD,pParent)
02{
03m_bWriteflg=FALSE;//初始化写标志变量为假
04}
05voidCHeroDlg:
:
DoDataExchange(CDataExchange*pDX)
06{
07CDialog:
:
DoDataExchange(pDX);//变量与资源映射
08//{{AFX_DATA_MAP(CHeroDlg)
09DDX_Text(pDX,IDC_TIME_EDIT,m_time);
10DDX_Text(pDX,IDC_NAME_EDIT,m_name);
11//}}AFX_DATA_MAP
12}
13BEGIN_MESSAGE_MAP(CHeroDlg,CDialog)
14ON_BN_CLICKED(IDOK_BTN,OnBtn)//按钮与函数映射
15END_MESSAGE_MAP()
17////////////////////////////////////////////////////
18//CHeroDlg消息句柄
19voidCHeroDlg:
:
SetWriteFlg(BOOLbflg)//设置写入标志
20{
21m_bWriteflg=bflg;
22}
23
24intCHeroDlg:
:
DoModal()//弹出对话框
25{
26charpszTmp[128]={0};
//读取配置文件
GetPrivateProfileString("HERO","name","无名氏",
pszTmp,127,".\\hero.ini");//读入姓名
m_name=CString(pszTmp);
if(!
m_bWriteflg)
{
GetPrivateProfileString("HERO","time","0",
pszTmp,127,".\\hero.ini");//读入等级
m_time=atoi(pszTmp);
}
returnCDialog:
:
DoModal();
}
voidCHeroDlg:
:
OnBtn()//按钮响应
{
UpdateData(TRUE);
if(m_bWriteflg)
{
CStringtmp;
//写入姓名和时间记录
WritePrivateProfileString("HERO","name",
m_name,".\\hero.ini");
tmp.Format("%d",m_time);
WritePrivateProfileString("HERO",
"time",tmp,".\\hero.ini");
}
m_bWriteflg=FALSE;
CDialog:
:
OnOK();
}
BOOLCHeroDlg:
:
OnInitDialog()//初始化对话
{
CDialog:
:
OnInitDialog();
if(m_bWriteflg)
{//当为写入时,把按钮名称改变
SetDlgItemText(IDOK_BTN,"记录");
}
returnTRUE;
3游戏播放背景音乐的实现
播放游戏背景音乐,是通过调用Windows的API函数sndPlaySound()来实现的。
当玩家选择"游戏设置"|"播放音乐"命令时,就播放音乐。
相反,如果取消,就停止播放音乐。
要实现这个功能,需要如下几步:
(1)在工程文件中,添加winmm.lib静态库文件及头文件。
参见第5.4节。
(2)实现CMineDlg类中的PlayBackMusic()成员函数,其代码如代码15.6所示。
代码15.6CMineDlg类的PlayBackMusic成员函数实现
01#include//插入系统API头文件
02...
03voidCMineDlg:
:
PlayBackMusic(BOOLbCheck)
04{
05//指定文件并播放
06if(bCheck)
07{//播放指定音乐文件
08sndPlaySound("music.wav",SND_ASYNC);
09}
10else
11{//停止播放
12sndPlaySound(NULL,SND_PURGE);
13}
14}
4游戏更换背景颜色的实现
voidCMyMine:
:
OnMemuColor()
{
m_bColorful=!
m_bColorful;
LoadBitmap();
SetCheckedColor();
Invalidate();
}
调用的方法:
/载入位图
//
voidCMyMine:
:
LoadBitmap()
{
if(m_bColorful)
{
m_clrDark=COLOR_WHITE;
m_bmpMine.DeleteObject();
m_bmpMine.LoadBitmap(IDB_MINE_COLOR);
m_bmpNumber.DeleteObject();
m_bmpNumber.LoadBitmap(IDB_NUM_COLOR);
m_bmpButton.DeleteObject();
m_bmpButton.LoadBitmap(IDB_BTN_COLOR);
}
else
{
m_clrDark=COLOR_BLACK;
m_bmpMine.DeleteObject();
m_bmpMine.LoadBitmap(IDB_MINE_GRAY);
m_bmpNumber.DeleteObject();
m_bmpNumber.LoadBitmap(IDB_NUM_GRAY);
m_bmpButton.DeleteObject();
m_bmpButton.LoadBitmap(IDB_BTN_GRAY);
}
}
voidCMyMine:
:
SetCheckedColor()
{
if(m_pSubMenu)
{
if(m_bColorful)
{
m_pSubMenu->CheckMenuItem(IDM_COLOR,MF_CHECKED|MF_BYCOMMAND);
}
else
{
m_pSubMenu->CheckMenuItem(IDM_COLOR,MF_UNCHECKED|MF_BYCOMMAND);
}
}
}
5游戏规则的实现
/*初始化游戏*/
voidCMyMine:
:
InitGame()
{
LoadBitmap();
LoadConfig();
m_nLeaveNum=m_uMineNum;
m_uSpendTime=0;
m_uBtnState=BS_NORMAL;//设置当前方块状态
m_uGameState=GS_WAIT;//设置当前游戏状态
if(m_uTimer){
KillTimer(ID_TIMER_EVENT);
m_uTimer=0;
}
m_pNewMine=NULL;//清空当前选中的小方块
m_pOldMine=NULL;//清空上次选中的小方块
//初始化表示雷区的二维数组
for(UINTi=0;ifor(UINTj=0;jm_pMines[i][j].uRow=i;
m_pMines[i][j].uCol=j;
m_pMines[i][j].uState=STATE_NORMAL;
m_pMines[i][j].uAttrib=ATTRIB_EMPTY;
m_pMines[i][j].uOldState=STATE_NORMAL;
}
}
}
voidCMyMine:
:
StartGame()
{
InitGame();
Invalidate();
}
/*在雷区铺设地雷*/
voidCMyMine:
:
LayMines(UINTrow,UINTcol)
{
srand((unsigned)time(NULL));
UINTi,j;
for(UINTindex=0;indexi=rand()%m_uYNum;
j=rand()%m_uXNum;
if(i==row&&j==col)continue;
if(m_pMines[i][j].uAttrib!
=ATTRIB_MINE){
m_pMines[i][j].uAttrib=ATTRIB_MINE;
index++;
}
}
}
/*自动打开相关不是地雷的格子*/
voidCMyMine:
:
ExpandMines(UINTrow,UINTcol)
{
UINTi,j;
UINTminRow=(row==0)?
0:
row-1;
UINTmaxRow=row+2;
UINTminCol=(col==0)?
0:
col-1;
UINTmaxCol=col+2;
UINTaround=GetAroundNum(row,col);
m_pMines[row][col].uState=15-around;
m_pMines[row][col].uOldState=15-around;
//在指定位置画出地雷
DrawSpecialMine(row,col);
if(around==0){
for(i=minRow;ifor(j=minCol;jif(!
(i==row&&j==col)&&
m_pMines[i][j].uState==STATE_NORMAL
&&m_pMines[i][j].uAttrib!
=ATTRIB_MINE){
if(!
IsInMineArea(i,j))continue;
ExpandMines(i,j);
}}}}
/*获得周围地雷个数*/
UINTCMyMine:
:
GetAroundNum(UINTrow,UINTcol)
{
UINTi,j;
UINTaround=0;
UINTminRow=(row==0)?
0:
row-1;
UINTmaxRow=row+2;
UINTminCol=(col==0)?
0:
col-1;
UINTmaxCol=col+2;
for(i=minRow;ifor(j=minCol;jif(!
IsInMineArea(i,j))continue;
if(m_pMines[i][j].uAttrib==ATTRIB_MINE)around++;
}}
returnaround;}
/*得到周围格子状态*/
UINTCMyMine:
:
GetAroundFlags(UINTrow,UINTcol)
{UINTi,j;
UINTflags=0;
UINTminRow=(row==0)?
0:
row-1;
UINTmaxRow=row+2;
UINTminCol=(col==0)?
0:
col-1;
UINTmaxCol=col+2;
for(i=minRow;ifor(j=minCol;jif(!
IsInMineArea(i,j))continue;
if(m_pMines[i][j].uState==STATE_FLAG)flags++;
}}
returnflags;}
/*地雷判断*/
BOOLCMyMine:
:
IsMine(UINTrow,UINTcol)
{
return(m_pMines[row][col].uAttrib==ATTRIB_MINE);
}
/*雷区判断*/
BOOLCMyMine:
:
IsInMineArea(UINTrow,UINTcol)
{
return(row>=0&&row=0&&col}
/*游戏结束*/
voidCMyMine:
:
Dead(UINTrow,UINTcol)
{
CRectrcBtn(m_uBtnRect[1],15,m_uBtnRect[2],39);
CRectrcMineArea(MINE_AREA_LEFT,MINE_AREA_TOP,
MINE_AREA_LEFT+m_uXNum*MINE_WIDTH,MINE_AREA_TOP+m_uYNum*MINE_HEIGHT);
UINTi,j;
if(m_pMines[row][col].uAttrib==ATTRIB_MINE){//打开了是地雷的格子
for(i=0;ifor(j=0;jm_pMines[row][col].uState=STATE_BLAST;
m_pMines[row][col].uOldState=STATE_BLAST;
if(m_pMines[i][j].uAttrib==ATTRIB_MINE
&&m_pMines[i][j].uState!
=STATE_FLAG){
m_pMines[i][j].uState=STATE_MINE;
m_pMines[i][j].uOldState=STATE_MINE;
}}}}
else{//打开了判断