⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game_yyllkview.cpp

📁 这程序是基于VC++/MFC机制应用开发的一款英语单词连连看游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Game_YYLLKView.cpp : implementation of the CGame_YYLLKView class
//

#include "stdafx.h"
#include <stdlib.h>
#include "Game_YYLLK.h"
#include "Game_YYLLKDefs.h"

#include "Game_YYLLKDoc.h"
#include "Game_YYLLKView.h"
#include "SettingDlg.h"
#include<windows.h>

#include<mmsystem.h>    //音乐MCI播放API接口函数的声明

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

#define BKCOLOR         RGB(128,128,128)	//背景颜色

#define ROWCOUNT        8					//行数
#define COLCOUNT        10					//列数

#define FRONTWIDTH	    50			    //前面方块的宽度
#define FRONTHEIGHT	   	50	    //前面方块的高度 	
#define BKWIDTH	        56					//背景方块的宽度
#define BKHEIGHT        56					//背景方块的高度

#define BLANK_STATE     -1                  //空方块


/////////////////////////////////////////////////////////////////////////////
// CGame_YYLLKView

IMPLEMENT_DYNCREATE(CGame_YYLLKView, CView)

BEGIN_MESSAGE_MAP(CGame_YYLLKView, CView)
	//{{AFX_MSG_MAP(CGame_YYLLKView)
	ON_WM_CREATE()
	ON_COMMAND(IDM_START, OnStart)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(IDM_PAUSE, OnPause)
	ON_COMMAND(IDM_EXIT, OnExit)
	ON_COMMAND(IDM_END, OnEnd)
	ON_UPDATE_COMMAND_UI(IDM_NUM, OnUpdateNum)
	ON_UPDATE_COMMAND_UI(IDM_ANIMAL, OnUpdateAnimal)
	ON_UPDATE_COMMAND_UI(IDM_PLANT, OnUpdatePlant)
	ON_WM_TIMER()
	ON_UPDATE_COMMAND_UI(IDM_START, OnUpdateStart)
	ON_UPDATE_COMMAND_UI(IDM_PAUSE, OnUpdatePause)
	ON_UPDATE_COMMAND_UI(IDM_END, OnUpdateEnd)
	ON_UPDATE_COMMAND_UI(IDM_SET, OnUpdateSet)
	ON_UPDATE_COMMAND_UI(IDM_EXIT, OnUpdateExit)
	ON_UPDATE_COMMAND_UI(ID_APP_ABOUT, OnUpdateAppAbout)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGame_YYLLKView construction/destruction

CGame_YYLLKView::CGame_YYLLKView()
{
	
}

CGame_YYLLKView::~CGame_YYLLKView()
{
	//释放动态数组空间
	delete[] m_map;
}

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

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CGame_YYLLKView drawing



/////////////////////////////////////////////////////////////////////////////
// CGame_YYLLKView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CGame_YYLLKView message handlers

int CGame_YYLLKView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	//初始化行列数
	m_nRow=ROWCOUNT;
	m_nCol=COLCOUNT;

	//根据行列数动态分配内核数据数组空间
	m_map=new int[m_nRow*m_nCol];

	//第一次开始游戏
	m_bFistPlay = TRUE;
	
	//缺省为不是游戏暂停状态
	m_bGamePaush = FALSE;

	//缺省为不插放背景音乐
	m_bMusic = FALSE;

	//左上角X,Y坐标
	m_iStartX = 40;
	m_iStartY = 20;

	//缺省级别为3级
	m_iLevel = 0;

	//缺省游戏是结束的
	m_bGameEnd = TRUE;

	//记录方块置为无效状态
	m_nY1= BLANK_STATE;
	m_nX1= BLANK_STATE;
	

	m_b_GAME_STATE = true;//欢迎界面是否显示:是
	return 0;
}

//OnDraw(CDC* pDC);承担所有绘制屏幕工作
void CGame_YYLLKView::OnDraw(CDC* pDC)
{
	DcEnvInitial();
	DrawGame(&m_memDC);  //在内存位图的游戏区域绘制

	pDC->BitBlt(0,0,m_nWidth,m_nHeight,&m_memDC,0,0,SRCCOPY);
}

//绘图设备环境的初始化
void CGame_YYLLKView::DcEnvInitial()
{
	if(m_bFistPlay)
	{
		m_bFistPlay = FALSE;
		//用默认的参数,获取当前屏幕设备环境
		CDC *pWindowDC = GetDC();

		//1.用于映射屏幕的内存设备环境
		//获取游戏窗口的大小用于下面设置内存位图的尺寸
		CRect windowRect;
		GetClientRect(&windowRect);
		m_nWidth = windowRect.Width();
		m_nHeight = windowRect.Height();

		//内存设备环境与屏幕设备环境关联(兼容)
		m_memDC.CreateCompatibleDC(pWindowDC);
		//内存位图与与屏幕关联(兼容),大小为游戏窗口的尺寸
		m_memBmp.CreateCompatibleBitmap(pWindowDC,m_nWidth,m_nHeight);
		//内存设备环境与内存位图关联,以便通过m_memDC在内存位图上作画
		m_memDC.SelectObject(&m_memBmp);
		//动物图样内存位图
		m_memPictureDC1.CreateCompatibleDC(pWindowDC);
		m_memPictureBmp1.LoadBitmap(IDB_BMP_ANIMAL1);
		m_memPictureDC1.SelectObject(&m_memPictureBmp1);


		//放在最桌面的前面显示
		HWND hWnd = ::AfxGetMainWnd()->m_hWnd;
		::SetWindowPos(hWnd,HWND_TOPMOST,m_iStartY,	m_iStartX,0,0,SWP_NOMOVE|SWP_NOSIZE);

		//黑色的黑笔
		m_pBlackPen  = new CPen(PS_SOLID,1,BLACK);

		//画刷
		m_pGrayBrush  = new CBrush(RGB(66,66,66));
		m_pBlackBrush  = new CBrush(BLACK);
	}
}

//释放绘图资源
void CGame_YYLLKView::DCEnvClear()
{
	//设备环境
	m_memDC.DeleteDC();

	//位图资源
	DeleteObject(m_memBmp);

	//画刷和画笔
	delete(m_pBlackPen);
	delete(m_pGrayBrush);
	delete(m_pBlackBrush);
}

//绘制游戏区域
void CGame_YYLLKView::DrawGame(CDC *pDC)
{
	//选用黑色画刷,绘制整个游戏所在窗口的背景
	pDC -> SelectObject(m_pBlackBrush);
	CRect rect;
	CListBox m_listbox;
	GetClientRect(&rect);
	pDC -> Rectangle(rect);

	//显示游戏区域及游戏级别的汉字描述
	if (!m_bGameEnd)
	{
		pDC -> SetBkColor(BLACK);
		pDC -> SetTextColor(WHITE);

		pDC -> TextOut(m_iStartY+610, m_iStartX, "游戏类型:");
		pDC -> TextOut(m_iStartY+680, m_iStartX,m_strLevel);
	}
	
	for(int i=0;i<m_nRow;i++)
	{
		for(int j=0;j<m_nCol;j++)
		{			
			if(m_map[i*m_nCol+j]==BLANK_STATE)
			{
			continue;
			}

			//绘制方块边框
			pDC->BitBlt(m_iStartY+j*FRONTWIDTH,m_iStartX+i*FRONTHEIGHT,
				BKWIDTH,BKHEIGHT,
				0,
				0,BKHEIGHT,
				SRCCOPY);
			//绘制方块
			pDC->BitBlt(m_iStartY+j*FRONTWIDTH,m_iStartX+i*FRONTHEIGHT,
				FRONTWIDTH,FRONTHEIGHT,
				&m_memPictureDC1,
				0,m_map[i*m_nCol+j]*(FRONTHEIGHT),
				SRCPAINT);
		}
	}

}

//游戏开始
void CGame_YYLLKView::OnStart() 
{
	if (!m_bGamePaush)  //如果不是游戏暂停状态,则必须作些初始工作
	{
		m_bGameEnd = FALSE;
	
		//显示当前的区域及游戏级别的汉字描述
		CurrentAreaAndLevel();
		
		CRect rect(m_iStartY, m_iStartX, m_iStartY+800, m_iStartX+600);
		InvalidateRect(&rect);
	}

	//初始化地图,将地图中所有方块区域位置置为空方块状态
	for(int iNum=0;iNum<(m_nCol*m_nRow);iNum++)
	{
		m_map[iNum] = BLANK_STATE;
	}

	//部下随机种子
	srand(time(NULL));

	//生成随机地图
	//将所有匹配成对的动物物种放进一个临时的地图中
	CDWordArray tmpMap;	
	for(int i=0;i<(m_nCol*m_nRow)/2;i++)
		for(int j=0;j<2;j++)
			tmpMap.Add(i);

	//每次从上面的临时地图中取走(获取后并在临时地图删除)
	//一个动物放到地图的空方块上
	for(i=0;i<m_nRow*m_nCol;i++)
	{	
		//随机挑选一个位置
		int nIndex=(int(rand()*0.1+rand()*0.01+rand()))%tmpMap.GetSize();

		//获取该选定物件放到地图的空方块
		m_map[i]=tmpMap.GetAt(nIndex);

		//在临时地图除去该动物
		tmpMap.RemoveAt(nIndex);
	}

	//更新显示
	Invalidate(TRUE);

	m_bGamePaush = FALSE;
	
}

//用于生成当前区域大小与级别所对应的汉字描述
void CGame_YYLLKView::CurrentAreaAndLevel()
{
	switch(m_iLevel)
	{
	case 0:
		m_strLevel = "动物"; break;
	case 1:
		m_strLevel = ""; break;
	case 2:
		m_strLevel = "植物"; break;
	}
}

// 鼠标左键消息处理
void CGame_YYLLKView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	//1.计算鼠标点击方块的的位置
	int x=(point.x-m_iStartY)/FRONTWIDTH+((point.x-m_iStartY)%FRONTWIDTH?1:0)-1;
	int y=(point.y-m_iStartX)/FRONTHEIGHT+((point.y-m_iStartX)%FRONTHEIGHT?1:0)-1;
	
	//2.在游戏区域内并且该区域还有该区域不是空的区域
	if(x<m_nCol&&y<m_nRow&&m_map[y*m_nCol+x]!= BLANK_STATE)
	{		
		//3.假设尚未记录第一个方块
		if(m_nX1==BLANK_STATE)
		{
			//4.记录第一个方块的位置
			m_nX1=x;
			m_nY1=y;
			
			//获取程序框架的设备环境
			CDC *pWinDC = GetDC();
			
			//临时绘制点中的方块外框
			//只绘屏幕不载入内存位图
			CPen myPen;
			CPen *pOldPen;
			myPen.CreatePen(PS_SOLID, 4, RGB(255,0,0));
			pOldPen = 	pWinDC->SelectObject(&myPen);
			//方块外框绘制,线条环绕绘制框架
			pWinDC->MoveTo(m_iStartY+x*FRONTWIDTH,m_iStartX+y*FRONTHEIGHT);
			pWinDC->LineTo(m_iStartY+x*FRONTWIDTH,m_iStartX+(y+1)*FRONTHEIGHT);
			pWinDC->LineTo(m_iStartY+(x+1)*FRONTWIDTH,m_iStartX+(y+1)*FRONTHEIGHT);
			pWinDC->LineTo(m_iStartY+(x+1)*FRONTWIDTH,m_iStartX+y*FRONTHEIGHT);
			pWinDC->LineTo(m_iStartY+x*FRONTWIDTH,m_iStartX+y*FRONTHEIGHT);
			//现场恢复
			pWinDC->SelectObject(pOldPen);
		}
		else
		{ 
			//5.判断是否点击的方块非本身, 是否点击同一种动物

			if((m_nX1!=x||m_nY1!=y)&&
				m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x]+20||
				(m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x]-20))
				//m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x])
			{
				//6.检测是否可以消除
				if(IsLink(m_nX1,m_nY1,x,y))
				{
					//7.数据清理
					m_map[m_nY1*m_nCol+m_nX1]=BLANK_STATE;
					m_map[y*m_nCol+x]=BLANK_STATE;
				}				
			}
			//8.清空记录方块的值
			m_nX1=BLANK_STATE;  
			m_nY1=BLANK_STATE;	
						
			//通知重绘
			Invalidate(FALSE);
		}
	}
	
	//察看是否已经胜利
	if(IsWin())
	{
		MessageBox("恭喜您胜利闯关,即将开始新局");
		OnStart();
	}
}

//判断选中的两个方块是否可以消除
BOOL CGame_YYLLKView::IsLink(int x1, int y1, int x2, int y2)
{
	//X直连方式
	if(x1==x2)
	{
		if(X1_Link_X2(x1,y1,y2))
			return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -