Visual C++ Realization of Tetris Game Combat II: Interface Design and Implementation (with source code and resources available for big jobs)

If you need source code and resources, please like and follow the collection and leave a private message in the comment area~~~

Our Visual C++ project adopts the MFC framework mode, and the interface implementation of each functional module is explained below

1. Implementation of the game menu

can be divided into the following steps

1: Add a menu resource to the project resource

2: Add a response function to each menu bar to the CTertisView class

3: The menu response function should try to call other functions in the class to reduce the process of direct processing, so that the program code is easy to read and has clear functions. The code of the menu response function is as follows

// TetrisView.cpp : implementation of the CTetrisView class
//

#include "stdafx.h"
#include "Tetris.h"

#include "TetrisDoc.h"
#include "TetrisView.h"

#include "HelpDlg.h"
#include "HeroDlg.h"
#include "LevelDlg.h"
#include "Russia.h"

#include <mmsystem.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CTetrisView

IMPLEMENT_DYNCREATE(CTetrisView, CView)

BEGIN_MESSAGE_MAP(CTetrisView, CView)
	//{
   
   {AFX_MSG_MAP(CTetrisView)
	ON_COMMAND(IDR_ABOUT, OnAbout)
	ON_COMMAND(IDR_HERO_LIST, OnHeroList)
	ON_COMMAND(IDR_LEVEL_SETUP, OnLevelSetup)
	ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)
	ON_COMMAND(IDR_START_GAME, OnStartGame)
	ON_COMMAND(IDR_HELP, OnHelp)
	ON_WM_KEYDOWN()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/
// CTetrisView construction/destruction

CTetrisView::CTetrisView()
{
	m_bStart = FALSE;
}

CTetrisView::~CTetrisView()
{
}

BOOL CTetrisView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/
// CTetrisView drawing

void CTetrisView::OnDraw(CDC* pDC)
{
	CTetrisDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CDC Dc;
	if(Dc.CreateCompatibleDC(pDC)==FALSE)
		AfxMessageBox("Can't create DC");
	//没有开始,显示封面
	if( m_bStart)
	{
		russia.DrawBK(pDC);
	}

}

/
// CTetrisView printing

BOOL CTetrisView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CTetrisView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CTetrisView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/
// CTetrisView diagnostics

#ifdef _DEBUG
void CTetrisView::AssertValid() const
{
	CView::AssertValid();
}

void CTetrisView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTetrisDoc* CTetrisView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTetrisDoc)));
	return (CTetrisDoc*)m_pDocument;
}
#endif //_DEBUG

/
// CTetrisView message handlers
void CTetrisView::OnAbout() 
{
	CAboutDlg aboutDlg;		//生成关于对话框
	aboutDlg.DoModal();		//弹出关于对话框
}

void CTetrisView::OnHeroList() 
{
	CHeroDlg dlg;			//生成英雄榜对话框
	dlg.DoModal();			//弹出英雄榜对话框
}

void CTetrisView::OnLevelSetup() 
{
	CLevelDlg	dlg;	//生成等级设置对话框
	dlg.DoModal();			//弹出等级设置对话框
}

void CTetrisView::OnPlayMusic() 
{
	CWnd*   pMain   =   AfxGetMainWnd();   
	CMenu*   pMenu   =   pMain->GetMenu();
	//判断播放音乐菜单当前状态
	BOOL bCheck = (BOOL)pMenu->GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED);
	
	if(m_bStart)
	{
		if(bCheck)
		{
			pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_UNCHECKED);
		}
		else
		{
			pMenu->CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);
		}
		
		PlayBackMusic(!bCheck);			//调用播放背景音乐功能函数
	}

}

void CTetrisView::OnStartGame() 
{
	m_bStart = true;
	russia.GameStart();					//调用RUSSIA对象的游戏开始函数
	SetTimer(1, russia.m_Speed, NULL);
}

void CTetrisView::OnHelp() 
{
	CHelpDlg dlg;						//生成帮助对话框
	dlg.DoModal();						//弹出对话框
}

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

}

void CTetrisView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	//没有开始
	if(!m_bStart)
		return;
	
	switch(nChar)
	{
	case VK_LEFT:
		russia.Move(KEY_LEFT);
		break;
	case VK_RIGHT:
		russia.Move(KEY_RIGHT);
		break;		
	case VK_UP:
		russia.Move(KEY_UP);
		break;
	case VK_DOWN:
		russia.Move(KEY_DOWN);
		break;
	}
	//重画
	CDC* pDC=GetDC();
	russia.DrawBK(pDC);
	ReleaseDC(pDC);

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CTetrisView::OnTimer(UINT nIDEvent) 
{
	//下移
	russia.Move(KEY_DOWN);
	//重画
	russia.DrawBK(GetDC());
	//关闭TIME1
	KillTimer(1);
	//调整速度
	SetTimer(1, russia.m_Speed, NULL);

	CView::OnTimer(nIDEvent);
}

Second, the realization of the game help dialog box

Create a dialog class to describe the game operation method through the text description in the resource

#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 dialog

class CHeroDlg : public CDialog
{
	// Construction
public:
	void SetWriteFlg(BOOL bflg);
	CHeroDlg(CWnd* pParent = NULL);   // standard constructor
	
	// Dialog Data
	//{
   
   {AFX_DATA(CHeroDlg)
	enum { IDD = IDD_HERO_LIST };
	int		m_level;
	CString	m_name;
	int		m_score;
	//}}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
	
	// Implementation
protected:
	
	// Generated message map functions
	//{
   
   {AFX_MSG(CHeroDlg)
	virtual void OnOK();
	afx_msg void OnBtn();
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_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_)

The implementation of the class is relatively simple, it is the structure of a basic dialog class, and only the button response function is realized, which is used to exit the current dialog box

// HelpDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Tetris.h"
#include "HelpDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CHelpDlg dialog


CHelpDlg::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_MAP
END_MESSAGE_MAP()

/
// CHelpDlg message handlers

void CHelpDlg::OnOK() 
{
	// TODO: Add extra validation here
	
	CDialog::OnOK();
}

3. Realization of the Game Hero List Dialog Box

To create a dialog resource and a setup.ini configuration file, the class declaration is as follows

#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 dialog

class CHelpDlg : public CDialog
{
// Construction
public:
	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

// Implementation
protected:

	// Generated message map functions
	//{
   
   {AFX_MSG(CHelpDlg)
	virtual void OnOK();
	//}}AFX_MSG
	DECLARE_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_)

In the implementation of the class, the configuration file is read and written by calling the system API function, and the interface function of setting the read and write flag is to assign a value to a member variable in the class to distinguish between writing or reading. The code is as follows

// HeroDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Tetris.h"
#include "HeroDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CHeroDlg dialog


CHeroDlg::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);
	DDX_Text(pDX, IDC_SCORE_EDIT, m_score);
	DDV_MinMaxInt(pDX, m_score, 0, 10000);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CHeroDlg, CDialog)
	//{
   
   {AFX_MSG_MAP(CHeroDlg)
	ON_BN_CLICKED(IDOK_BTN, OnBtn)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CHeroDlg message handlers

void 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", "score", "0", 
			pszTmp, 127, ".\\setup.ini");
		m_score = atoi(pszTmp);
		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;
		tmp.Format("%d", m_score);
		WritePrivateProfileString("HERO", "name", m_name, ".\\setup.ini");
		WritePrivateProfileString("HERO", "score", tmp, ".\\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; 
}

4. Realization of playing background music in the game

Playing game background music is realized by calling the Windows API function sndPlaySound, which requires the following steps

1: In the project file, add winmm.lib static library file and header file

2: Implement the PlayBackMusic member function in the CTetrisView class

5. Realization of game level setting dialog box

Create a dialog resource, and add a subsection to the configuration file to record the level of the set game, and bind the response function to the OK button and the cancel button. The class declaration is as follows

#if !defined(AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_)
#define AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// LevelDlg.h : header file
//

/
// CLevelDlg dialog

class CLevelDlg : public CDialog
{
// Construction
public:
	CLevelDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
	//{
   
   {AFX_DATA(CLevelDlg)
	enum { IDD = IDD_LEVEL_DLG };
	int		m_level;
	//}}AFX_DATA


// Overrides
	// ClassWizard generated virtual function overrides
	//{
   
   {AFX_VIRTUAL(CLevelDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:

	// Generated message map functions
	//{
   
   {AFX_MSG(CLevelDlg)
	virtual void OnOK();
	virtual void OnCancel();
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//{
   
   {AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_LEVELDLG_H__E423F5C3_7698_4365_A009_4E6C7BC62189__INCLUDED_)

When the game level setting dialog box passes the initialization dialog box, the current level parameter in the configuration file is read out and displayed, and then the corresponding write operation is performed according to the user clicking the OK button. The implementation code of the class is as follows

// LevelDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Tetris.h"
#include "LevelDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CLevelDlg dialog


CLevelDlg::CLevelDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLevelDlg::IDD, pParent)
{
	//{
   
   {AFX_DATA_INIT(CLevelDlg)
	m_level = 0;
	//}}AFX_DATA_INIT
}


void CLevelDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{
   
   {AFX_DATA_MAP(CLevelDlg)
	DDX_Text(pDX, IDC_LEVEL_EDIT, m_level);
	DDV_MinMaxInt(pDX, m_level, 1, 10);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CLevelDlg, CDialog)
	//{
   
   {AFX_MSG_MAP(CLevelDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CLevelDlg message handlers

void CLevelDlg::OnOK() 
{
	if(UpdateData(TRUE))
	{
		CString tmp;
		tmp.Format("%d", m_level);
		WritePrivateProfileString("SETUP", "level", tmp, ".\\setup.ini");
		CDialog::OnOK();
	}
}

void CLevelDlg::OnCancel() 
{

	CDialog::OnCancel();
}

BOOL CLevelDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	char pszTmp[128] = {0};

	GetPrivateProfileString("SETUP", "level", "0", 
		pszTmp, 127, ".\\setup.ini");
	m_level = atoi(pszTmp);

	UpdateData(FALSE);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

The test results are as follows

 

 

 

It's not easy to create and find it helpful, please like, follow and collect~~~

Guess you like

Origin blog.csdn.net/jiebaoshayebuhui/article/details/129291841