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

📄 ltlview.cpp

📁 一个实现连连看游戏功能的程序。8*8的图片大小
💻 CPP
字号:
// LTLView.cpp : implementation of the CLTLView class
//

#include "stdafx.h"
#include "LTL.h"
#include "LTLDoc.h"
#include "LTLView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLTLView

IMPLEMENT_DYNCREATE(CLTLView, CView)

BEGIN_MESSAGE_MAP(CLTLView, CView)
	//{{AFX_MSG_MAP(CLTLView)
		ON_WM_LBUTTONDOWN()
     	ON_WM_RBUTTONDOWN()
    	ON_COMMAND(ID_FILE_NEW, OnGameNew)
		ON_WM_TIMER()
    	ON_WM_CREATE()
    	ON_WM_CANCELMODE()
   	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLTLView construction/destruction

CLTLView::CLTLView()
{	
}

CLTLView::~CLTLView()
{
}

BOOL CLTLView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CLTLView drawing

void CLTLView::OnDraw(CDC* pDC)
{
	if(pDoc->overflag)                            //game over 清空显示
		return;

    CClientDC dc(this);                    //初始化边框
	dc.MoveTo(63, 63);
	dc.LineTo(833, 63);
	dc.LineTo(833, 577);
	dc.LineTo(63, 577);
	dc.LineTo(63, 63);

	CDC MemDC;                           //根据PicMark矩阵作位图
	MemDC.CreateCompatibleDC(NULL);
    for(int i=1; i<9; i++)
		for(int j=1; j<13; j++)
		{
			if(pDoc->PicMark[i][j] != 0){
				pDoc->m_Bitmap.DeleteObject();	                         //attention 
				pDoc->m_Bitmap.LoadBitmap(130+pDoc->PicMark[i][j]-'a');
				MemDC.SelectObject(pDoc->m_Bitmap);
				pDC->BitBlt(64*j, 64*i, 64, 64, &MemDC, 0, 0, SRCCOPY);
			//MessageBox("23");
			}
		}
	CPoint pt;
	for(i=0; i<pDoc->m_pointA.GetSize(); i++)                        //作选择框
		{
			pt = pDoc->m_pointA[i];		
			dc.MoveTo(pt.x+1, pt.y+1);
			dc.LineTo(pt.x+63, pt.y+1);
			dc.LineTo(pt.x+63, pt.y+63);
			dc.LineTo(pt.x+1, pt.y+63);
			dc.LineTo(pt.x+1, pt.y+1);
		}
	if(pDoc->m_pointA.GetSize() == 2){
		dc.MoveTo(pDoc->m_pointA[0].x+32, pDoc->m_pointA[0].y+32);
		dc.LineTo(pDoc->Path[0].x+32, pDoc->Path[0].y+32);
		dc.LineTo(pDoc->Path[1].x+32, pDoc->Path[1].y+32);
		dc.LineTo(pDoc->m_pointA[1].x+32, pDoc->m_pointA[1].y+32);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CLTLView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CLTLView message handlers

void CLTLView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	int a = pDoc->m_pointA.GetSize();
	if(a == 2) {
		if(ClearTwoPic())
			return;
		a = 0;
	}
//	char s[20];
//	sprintf(s,"X=%d,Y=%d",point.x/64*64,point.y/64*64);
//	MessageBox(s);
	int x = point.x/64*64;               //计算单击点所属图片(无效)区域的左上角的点坐标
	int y = point.y/64*64;	  
	if(x<64 || x>=832 || y<64 || y>=576)	
	{CView::OnRButtonDown(nFlags, point);return;   }       //越界
	int i = y/64;
	int j = x/64;
	if(pDoc->PicMark[i][j] == 0)		return;                 //图已删去,为空	              

	CPoint pt(x, y);
	CRect Rect;
    
    if(a == 0){
		Rect.SetRect(x, y, x+64, y+64);
		pDoc->m_pointA.Add(pt);
		InvalidateRect(Rect,false);
	}
	else{                                     //a==1		
		CPoint pt0(pDoc->m_pointA[0].x, pDoc->m_pointA[0].y);		
		if(pDoc->IfLine(pt0, pt, pDoc->Path) == true){
			pDoc->disappear++;
			pDoc->m_pointA.Add(pt);
			/*Rect.SetRect(x, y, x+64, y+64);	         //不加连线可如此 减少更新量	
			InvalidateRect(Rect,true);*/	
			Invalidate(false);
		}
	}
    CView::OnLButtonDown(nFlags, point);
}

void CLTLView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	int a = pDoc->m_pointA.GetSize();
	if(a <2 ){
		CRect *Rect = new CRect[a];
		for(int i=0; i<a; i++)
		{
			int	x = pDoc->m_pointA[i].x;
			int y = pDoc->m_pointA[i].y;
			Rect[i].SetRect(x, y, x+64, y+64);            //生成a个无效区域
		}
		pDoc->m_pointA.RemoveAll();                        //清空CPoint数组
		for(i=0; i<a; i++)
			InvalidateRect(Rect[i],true);	              //对a个无效区域进行擦除更新
	}
	else
		ClearTwoPic();	
	CView::OnRButtonDown(nFlags, point);
}

void CLTLView::OnGameNew() 
{	
//	KillTimer(1);
	MessageBox("START A NEW GAME..", "提示");
	pDoc->Init();
	InitProgBar();
//	SetTimer(1, 500, NULL);	                //启动定时器
	Invalidate(true);
}

void CLTLView::OnTimer(UINT NIDEvent)        //这个函数里的操作过于复杂 将会影响时间准确性
{
    pDoc->TimeUsed += 0.5;
	m_Progbar.SetPos(--pDoc->pos);
	if(pDoc->pos == 0)
		TimeOver();
}

////////////////////////////////////////////////////////////////////////
//////      other functions

void CLTLView::swap(int &a, int &b)
{
	int t = a;
	a = b;
	b = t;
}

bool CLTLView::ClearTwoPic()
{	
	int j0, i0, j1, i1;		                    //清空所去图片
	i0 = pDoc->m_pointA[0].x;
	j0 = pDoc->m_pointA[0].y;
	i1 = pDoc->m_pointA[1].x;
	j1 = pDoc->m_pointA[1].y;
	pDoc->PicMark[j1/64][i1/64] = 0;
	pDoc->PicMark[j0/64][i0/64] = 0;

	int	p0i, p0j, p1i, p1j;                     //计算原图片与路径构成的矩形无效区域
	p0i = pDoc->Path[0].x;
	p0j = pDoc->Path[0].y;
	p1i = pDoc->Path[1].x;
	p1j = pDoc->Path[1].y;
	if(i0 > i1)		swap(i0, i1);                //左上点置于点0
	if(p0i > p1i)	swap(p0i, p1i);	             //右下点置于点1
	if(i0 > p0i)    swap(i0, p0i);
	if(i1 < p1i)    swap(i1, p1i);
	if(j0 > j1)		swap(j0, j1);
	if(p0j > p1j)	swap(p0j, p1j);
	if(j0 > p0j)    swap(j0, p0j);
	if(j1 < p1j)    swap(j1, p1j);	

	pDoc->m_pointA.RemoveAll();
	CRect Rect;
	Rect.SetRect(i0, j0, i1+64, j1+64);
	InvalidateRect(Rect, true);
	if(pDoc->disappear == 48){                   //设置需完成数量
	//	KillTimer(1);                           //停止定时器 ATTENTION!
		double tTime = pDoc->TimeUsed;
		pDoc->pos = 0;
		MessageBox(" STAGE CLEAR!\nCONGRATUATIONS!", "提示");
		char s[20];
		sprintf(s,"You Have Used %.2f Seconds",tTime);
		MessageBox(s, "提示");
		MessageBox("      NEXT STAGE!\t", "提示");		
		pDoc->Init();
		InitProgBar();
//		SetTimer(1, 500, NULL);	                //启动定时器
		Invalidate(true);		
		return true;		
	}
	return false;
}

int CLTLView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{		
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;	
	InitView();
	return 0;
}

void CLTLView::OnCancelMode() 
{
	CView::OnCancelMode();		
}

void CLTLView::InitView()             //仅供第一次调用
{
	pDoc = GetDocument();        //此处pDoc统一初始化,(可以节约时间)在OnCreate函数中调用
	ASSERT_VALID(pDoc);	                     //注意不可在构造函数中调用!
	SetTimer(1, 500, NULL);	
	pDoc->TimeUsed = 0;
	TimeSet = 120;                             //设置x秒时限
//  m_Progbar.DestroyWindow();
	m_Progbar.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, CRect(250,20,700,32),
		this, IDC_PROGBAR);	                //构造进度条
	InitProgBar();
	SetTimer(1, 500, NULL);	                //启动定时器
}

void CLTLView::InitProgBar()          //初始化进度条及相关参数
{
	pDoc->pos = int(TimeSet/0.5);
	pDoc->TimeUsed = 0;
	pDoc->overflag = 0;
	m_Progbar.SetRange(0, pDoc->pos);
	m_Progbar.SetStep(1);
	m_Progbar.SetPos(pDoc->pos);	
}

void CLTLView::TimeOver()
{
//	KillTimer(1);
//	m_Progbar.DestroyWindow();	
	char s[40];
	sprintf(s,"You Have Used Out Of %.2f Seconds",pDoc->TimeUsed);
	MessageBox(s, "提示");		                //每次选择确定都会更新
	MessageBox("Game  Over!", "提示");	
    MessageBox("To Restart Game, Select \"Begin\" -> \"New Game\"..", "提示");		
//	pDoc->Init();
//	InitProgBar();
	pDoc->pos = 0;
	pDoc->overflag = 1;
	Invalidate(true);	
}


//如何在非视图类中调用视图类里的成员函数 或使用成员?
//如何设置全局变量可以各类共享使用
//如何解决新建命令生成无文件名文档,或如何在其他地方调用CWinApp里的OnFileNew;

⌨️ 快捷键说明

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