1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Visual C++实现连连看项目游戏实战二:界面实现(附源码和资源 可用于大作业)

Visual C++实现连连看项目游戏实战二:界面实现(附源码和资源 可用于大作业)

时间:2018-08-10 17:55:11

相关推荐

Visual C++实现连连看项目游戏实战二:界面实现(附源码和资源 可用于大作业)

需要源码请点赞关注收藏后评论区留言私信~~~

连连看游戏的Visual C++工程采用MFC对话框模式进行开发,下面主要讲解连连看游戏各个功能模块的代码实现

一、游戏菜单的实现

在连连看游戏中,通过如下几个步骤即可实现游戏的菜单

给每个菜单栏添加响应函数到CLlkDlg类中

菜单响应函数的实现代码如下

// llkDlg.cpp : implementation file//#include "stdafx.h"#include "llk.h"#include "llkDlg.h"#include "HeroDlg.h"#include "HelpDlg.h"#include <mmsystem.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif#define IDC_BLOCK 2000 /// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CLlkDlg dialogCLlkDlg::CLlkDlg(CWnd* pParent /*=NULL*/): CDialog(CLlkDlg::IDD, pParent){//{{AFX_DATA_INIT(CLlkDlg)//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CLlkDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CLlkDlg)DDX_Control(pDX, IDC_METHOD, m_method);DDX_Control(pDX, IDC_LINE, m_line);DDX_Control(pDX, IDC_BKPIC, m_bkPic);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CLlkDlg, CDialog)//{{AFX_MSG_MAP(CLlkDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_COMMAND(IDR_ABOUT, OnAbout)ON_COMMAND(IDR_EXIT_GAME, OnExitGame)ON_COMMAND(IDR_HELP, OnHelp)ON_COMMAND(IDR_HERO_LIST, OnHeroList)ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)ON_COMMAND(IDR_START_GAME, OnStartGame)ON_WM_TIMER()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CLlkDlg message handlersBOOL CLlkDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small iconm_main_menu.LoadMenu(IDR_MAIN_MENU);SetMenu(&m_main_menu);m_nLevel = 1;SetWindowPos(NULL, 100, 100, 800, 600, SWP_SHOWWINDOW|SWP_NOZORDER);m_method.SetWindowPos(NULL, 300, 500, 200, 25, SWP_SHOWWINDOW|SWP_NOZORDER);m_bkPic.SetWindowPos(NULL, 130, 70, 480, 280, SWP_SHOWWINDOW|SWP_NOZORDER);m_line.SetWindowPos(NULL, 90, 30, 560, 360, SWP_SHOWWINDOW|SWP_NOZORDER);m_MsgRgn.CreateRectRgn(150, 20, 550, 40);m_bStart = false;return TRUE; // return TRUE unless you set the focus to a control}void CLlkDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}void CLlkDlg::OnPaint() {CDialog::OnPaint();}HCURSOR CLlkDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CLlkDlg::OnAbout() {CAboutDlg dlg;dlg.DoModal();}void CLlkDlg::OnExitGame() {CDialog::OnCancel();}void CLlkDlg::OnHelp() {CHelpDlg dlg;dlg.DoModal();}void CLlkDlg::OnHeroList() {CHeroDlg dlg;dlg.DoModal();}void CLlkDlg::OnPlayMusic() {//判断播放音乐菜单当前状态BOOL bCheck = (BOOL)m_main_menu.GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED);if(m_bStart){//游戏如果开始才允许播放音乐if(bCheck){m_main_menu.CheckMenuItem(IDR_PLAY_MUSIC,MF_BYCOMMAND | MF_UNCHECKED);}else{m_main_menu.CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);}PlayBackMusic(!bCheck);//调用播放背景音乐功能函数}}void CLlkDlg::OnStartGame() {char pszTmp[128] = {0};m_hintNum = 3;m_exchangeNum = 3;m_line.m_lineNum = 0;m_method.SetWindowText("开 始 游 戏!");Start(1);GetPrivateProfileString("HERO", "level", "1", pszTmp, 127, ".\\setup.ini");m_nHighLevel = atoi(pszTmp);}////播放背景音乐//void CLlkDlg::PlayBackMusic(BOOL bflag){//指定文件并播放if(bflag){//播放音乐sndPlaySound("music.wav",SND_ASYNC); }else{//停止播放sndPlaySound(NULL,SND_PURGE); }}////游戏开始//void CLlkDlg::Start(int level){CString str;m_nLevel = level;m_timePoint = 130 - level * 10;//设置每个等级的限制时间//随机设置背景图片srand((unsigned int)time(NULL));str.Format("res\\b%d.bmp", m_nLevel);m_bkPic.ModifyStyle(0,SS_BITMAP|SS_CENTERIMAGE); HBITMAP m_bkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); m_bkPic.SetBitmap(m_bkBmp);InitMap(map);ShowMap(map);m_p = NULL;CRgn rgn;rgn.CreateRectRgn(420, 0, 560, 160);m_MsgRgn.CopyRgn(&rgn);ShowMsg(&m_MsgRgn);//设置计时器KillTimer(1);SetTimer(1, 1000, NULL);m_bStart = true;}////信息显示//void CLlkDlg::ShowMsg(CRgn *rgn){CClientDC *pDC = (CClientDC *)GetDC();//int nOldDC = pDC->SaveDC();CFont font; CString str;//设置字体if(0==font.CreatePointFont(150,"Comic Sans MS")){AfxMessageBox("Can't Create Font");}pDC->SelectObject(&font);//设置字体颜色及其背景颜色pDC->SetTextColor(RGB(39,244,10));pDC->SetBkColor(RGB(0,0,0));//输出数字str.Format("游戏等级: %d",m_nLevel);pDC->TextOut(650,420,str);str.Format("剩余时间: %03d", m_timePoint);pDC->TextOut(650, 450, str);str.Format("提示次数: %d",m_hintNum);pDC->TextOut(650,480,str);str.Format("换盘次数: %d", m_exchangeNum);pDC->TextOut(650, 510, str);}////初始化棋盘数组//void CLlkDlg::InitMap(int map[][MAXY]){int i, j;int x, y;//初始化边界for(i=0; i<MAXX; i++){for(j=0; j<MAXY; j++){if((i==0) || (i==MAXX-1) || (j==0) || (j==MAXY-1)){map[i][j] = -1;}else{map[i][j] = 0;}}}srand((unsigned int)time(NULL));//随机数种子//初始化地图for(i=0; i<SAME; i++){for(j=1; j<=TYPENUM; j++){x = rand()%MAXX;y = rand()%MAXY;if(map[x][y]){j--;}else{map[x][y] = j;}}}}////转换棋盘数组的中数据为棋子并显示出来//void CLlkDlg::ShowMap(int map[][MAXY]){this->Invalidate();int i, j;POINT p;CString str;//清除原有按钮for(i=0; i<m_cmGroup.GetSize(); i++)delete (CChessMan *)m_cmGroup.GetAt(i);m_cmGroup.RemoveAll();for(i=1; i<MAXX-1; i++){for(j=1; j<MAXY-1; j++){p.x = i;p.y = j;m_cmGroup.Add(new CChessMan(map[i][j], p));}}for(i=0; i<(MAXX-2)*(MAXY-2); i++){CChessMan *btn = (CChessMan *)m_cmGroup.GetAt(i);btn->Create(str, WS_CHILD|BS_BITMAP, //注意属性!!!CRect(130+(i%(MAXY-2))*40, 70+(i/(MAXY-2))*40, 170+(i%(MAXY-2))*40, 110+(i/(MAXY-2))*40), this, IDC_BLOCK+i);if(btn->m_id)//如果为0则不显示{str.Format("res\\%d.bmp", btn->m_id);HBITMAP m_fkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);if(m_fkBmp == NULL) {if(MessageBox("缺少图片资源!", "错误", MB_ICONERROR|MB_OK) == IDOK){CDialog::OnCancel();return;}}btn->SetBitmap(m_fkBmp);btn->ShowWindow(SW_SHOW);}else{btn->ShowWindow(SW_HIDE);}}}////换盘接口成员函数//void CLlkDlg::CallExchange(){if(m_exchangeNum){doExchange(map);while(!CChessMan::Hint(map));//至少有一个可消去ShowMap(map);m_exchangeNum--;}}////提示连接接口成员函数//void CLlkDlg::CallHint(){if(m_hintNum){if(CChessMan::Hint(map, &m_hintP1, &m_hintP2)){CChessMan *temp;temp = (CChessMan *)m_cmGroup.GetAt(m_hintP1);temp->SetButtonStyle(BS_DEFPUSHBUTTON);temp = (CChessMan *)m_cmGroup.GetAt(m_hintP2);temp->SetButtonStyle(BS_DEFPUSHBUTTON);m_hintNum--;}}}////换盘函数//void CLlkDlg::Exchange(int map[][MAXY]){int i, j;int k = 0;int temp[(MAXX-2)*(MAXY-2)+1] = {0};//比格子数多一个,防止数组越界!!!for(i=1; i<MAXX-1; i++){for(j=1; j<MAXY-1; j++){if(map[i][j]){temp[k++] = map[i][j];map[i][j] = 0;}}}srand((unsigned int)time(NULL));k = 0;while(temp[k]){i = rand()%MAXX;j = rand()%MAXY;if(map[i][j])k--;elsemap[i][j] = temp[k];k++;}}////更新棋盘数组//void CLlkDlg::RefreshMap(){CRgn resultRgn;resultRgn.CreateRectRgn(90,30,690,430);CRgn tmpRgn;tmpRgn.CreateRectRgn(0,0,0,0);for(int i=0; i<MAXX; i++){for(int j=0; j<MAXY; j++){CRect rect;CRgn srcRgn;if(map[i][j]==-1 || map[i][j]==0){rect.top = 30 + i*40;rect.bottom = 70 + i*40;rect.left = 90 + j*40;rect.right = 130 + j*40;srcRgn.CreateRectRgnIndirect(&rect);//把消去的区域加进来(覆盖原有区域),以便刷新bineRgn(&srcRgn,&tmpRgn,RGN_OR);tmpRgn.CopyRgn(&resultRgn);}}}//只刷新被消去的区域,防止界面闪烁this->InvalidateRgn(&resultRgn);}////定时器//void CLlkDlg::OnTimer(UINT nIDEvent) {m_timePoint -= 1;if(m_timePoint <= 0){KillTimer(1);int nRet = MessageBox("限 制 时 间 到!", "闯 关 失 败", MB_YESNO|MB_ICONINFORMATION);if(IDYES == nRet){OnStartGame();}else{isHighLevel();CDialog::OnCancel();}return;}InvalidateRgn(&m_MsgRgn);ShowMsg(&m_MsgRgn);}////截获用户消息//BOOL CLlkDlg::PreTranslateMessage(MSG* pMsg) {//键盘按下消息if(pMsg->message==WM_KEYDOWN){switch((int)pMsg->wParam){case VK_F5://快捷键F5CallHint();m_line.m_lineNum = 0;RefreshMap();m_line.Invalidate();break;case VK_F6://快捷键F6CallExchange();m_line.m_lineNum = 0;RefreshMap();m_line.Invalidate();break;default:break;}}return CDialog::PreTranslateMessage(pMsg);}void CLlkDlg::isHighLevel(){if(m_nHighLevel<m_nLevel){CHeroDlg dlg;dlg.m_level = m_nLevel;dlg.SetWriteFlg(TRUE);dlg.DoModal();}}

二、游戏帮助对话框的实现

连连看游戏中的帮助是使用一个对话框来实现的,实现的步骤如下所述

添加一个对话框资源到工程中,并填写说明文字

编写一个CHelpDlg对话框类,主要是加载对话框资源,通过资源中的文字说明对游戏操作方法进行描述,同时只包含单击知道了按钮的响应函数

#if !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)#define AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// HelpDlg.h : header file///// CHelpDlg dialogclass CHelpDlg : public CDialog{// Constructionpublic:CHelpDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CHelpDlg)enum { IDD = IDD_HELP };// NOTE: the ClassWizard will add data members here//}}AFX_DATA// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CHelpDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:// Generated message map functions//{{AFX_MSG(CHelpDlg)virtual void OnOK();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_HELPDLG_H__A6CEBADE_794E_4F8C_85FB_311FC78558A3__INCLUDED_)

CHelpDlg对话框类中,需要实现对话框类的构造函数,析构函数和知道了按钮响应函数

// HelpDlg.cpp : implementation file//#include "stdafx.h"#include "llk.h"#include "HelpDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/// CHelpDlg dialogCHelpDlg::CHelpDlg(CWnd* pParent /*=NULL*/): CDialog(CHelpDlg::IDD, pParent){//{{AFX_DATA_INIT(CHelpDlg)// NOTE: the ClassWizard will add member initialization here//}}AFX_DATA_INIT}void CHelpDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CHelpDlg)// NOTE: the ClassWizard will add DDX and DDV calls here//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CHelpDlg, CDialog)//{{AFX_MSG_MAP(CHelpDlg)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CHelpDlg message handlersvoid CHelpDlg::OnOK() {// TODO: Add extra validation hereCDialog::OnOK();}

三、游戏英雄榜对话框的实现

创建一个对话框资源,和配置文件setup.ini

#if !defined(AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_)#define AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// HeroDlg.h : header file///// CHeroDlg dialog// CHeroDlg dialogclass CHeroDlg : public CDialog{// Constructionpublic:void SetWriteFlg(BOOL bflg);CHeroDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CHeroDlg)enum { IDD = IDD_HERO_LIST };intm_level;CStringm_name;//}}AFX_DATA// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CHeroDlg)public:virtual int DoModal();protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:// Generated message map functions//{{AFX_MSG(CHeroDlg)virtual void OnOK();afx_msg void OnBtn();virtual BOOL OnInitDialog();//}}AFX_MSGDECLARE_MESSAGE_MAP()private:BOOL m_bWriteflg;};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_HERODLG_H__6D0A81F3_A5F6_4816_899E_ACC62CDE229A__INCLUDED_)

CHeroDlg类的实现中通过调用系统API函数,来对配置文件进行读写操作,而设置读写标志接口函数,是对类的一个成员变量进行负值操作,达到写入或者读取的区分

// HeroDlg.cpp : implementation file//#include "stdafx.h"#include "llk.h"#include "HeroDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/// CHeroDlg dialogCHeroDlg::CHeroDlg(CWnd* pParent /*=NULL*/): CDialog(CHeroDlg::IDD, pParent){m_bWriteflg = FALSE;}void CHeroDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CHeroDlg)DDX_Text(pDX, IDC_LEVEL_EDIT, m_level);DDX_Text(pDX, IDC_NAME_EDIT, m_name);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CHeroDlg, CDialog)//{{AFX_MSG_MAP(CHeroDlg)ON_BN_CLICKED(IDOK_BTN, OnBtn)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CHeroDlg message handlersvoid CHeroDlg::OnOK() {}void CHeroDlg::SetWriteFlg(BOOL bflg){m_bWriteflg = bflg;}int CHeroDlg::DoModal() {char pszTmp[128] = {0};//读取配置文件GetPrivateProfileString("HERO", "name", "0", pszTmp, 127, ".\\setup.ini");m_name = CString(pszTmp);if(!m_bWriteflg){GetPrivateProfileString("HERO", "level", "0", pszTmp, 127, ".\\setup.ini");m_level = atoi(pszTmp);}return CDialog::DoModal();}void CHeroDlg::OnBtn() {UpdateData(TRUE);if(m_bWriteflg){CString tmp;WritePrivateProfileString("HERO", "name", m_name, ".\\setup.ini");tmp.Format("%d", m_level);WritePrivateProfileString("HERO", "level", tmp, ".\\setup.ini");}m_bWriteflg = FALSE;CDialog::OnOK();}BOOL CHeroDlg::OnInitDialog() {CDialog::OnInitDialog();if(m_bWriteflg){SetDlgItemText(IDOK_BTN, "记录");}return TRUE; }

四、游戏播放背景音乐的实现

游戏背景音乐播放,是通过调用Windows的API函数sndPlaySound来实现的,当玩家选择游戏设置,播放音乐命名时,就播放音乐,相反如果取消,就停止播放音乐,要实现这个功能,需要如下几个步骤

1:在工程文件中,添加winmm.lib静态库文件以及头文件

2:实现CLlkDlg类中的PlayBackMusic成员函数

void CLlkDlg::PlayBackMusic(BOOL bflag){//指定文件并播放if(bflag){//播放音乐sndPlaySound("music.wav",SND_ASYNC); }else{//停止播放sndPlaySound(NULL,SND_PURGE); }}

创作不易 觉得有帮助请点赞关注收藏~~~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。