猫史档案馆


C++贪吃蛇

用户:CodeStar_CodeStar_查看:0 回复:0 评论:0 创建时间:2021-04-16T20:42:39


// DrawDialog.cpp : implementation file
//

#include "stdafx.h"
#include "TCS.h"
#include "DrawDialog.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDrawDialog dialog


CDrawDialog::CDrawDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CDrawDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDrawDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CDrawDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDrawDialog)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDrawDialog, CDialog)
	//{{AFX_MSG_MAP(CDrawDialog)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawDialog message handlers

bool isheadopen = false;
void CDrawDialog::OnPaint() 
{
	喵aintDC sdc(this); // device context for painting
	CRect rect;
	this->GetClientRect(&rect);
	CDC dc;
	dc.CreateCompatibleDC(NULL);
	CBitmap bmp_bk;
	bmp_bk.CreateCompatibleBitmap(&sdc,rect.Width(),rect.Height());
	dc.SelectObject(&bmp_bk);

	//绘制墙
	CBitmap bmp_wall;
	bmp_wall.LoadBitmap(IDB_BMPWALL);
	CBrush brush;
	brush.CreatePatternBrush(&bmp_wall);
	dc.FillRect(&rect,&brush);
	//绘制记分板
	CBitmap bmp_scoreboard,bmp_mask;
	bmp_scoreboard.LoadBitmap(IDB_BMPSCOREBOARD);

	CDC tmdc,dcmask;
	tmdc.CreateCompatibleDC(NULL);
	tmdc.SelectObject(&bmp_scoreboard);

	dcmask.CreateCompatibleDC(&tmdc);
	bmp_mask.CreateBitmap(292,62,0,0,NULL);
	dcmask.SelectObject(&bmp_mask);
	tmdc.SetBkColor(RGB(255,255,255));
	dcmask.BitBlt(0,0,292,62,&tmdc,0,0,SRCCOPY);

	dc.BitBlt(m_scoreboardrect.left,m_scoreboardrect.top,m_scoreboardrect.right,
		m_scoreboardrect.bottom,&tmdc,0,0,SRCINVERT);
	dc.BitBlt(m_scoreboardrect.left,m_scoreboardrect.top,m_scoreboardrect.right,
		m_scoreboardrect.bottom,&dcmask,0,0,SRCAND);
	dc.BitBlt(m_scoreboardrect.left,m_scoreboardrect.top,m_scoreboardrect.right,
		m_scoreboardrect.bottom,&tmdc,0,0,SRCINVERT);


	//绘制活动区
	CBitmap bmp_cell;
	bmp_cell.LoadBitmap(IDB_BMPCELL);
	CBrush brush1;
	brush1.CreatePatternBrush(&bmp_cell);

	dc.FillRect(&m_actionrect,&brush1);
	//绘制阻挡墙
	dc.FillRect(&m_barwall1,&brush);
	dc.FillRect(&m_barwall2,&brush);
	//绘制小球
	if (m_state == STATE_START || m_state == STATE_COUNTINUE 
		 || m_state == STATE_PAUSE)
	{
		CBitmap bmp_ball;
		bmp_ball.LoadBitmap(IDB_BMPBALL);
		CBrush brush2;
		brush2.CreatePatternBrush(&bmp_ball);
		CRect ballrect;
		ballrect.left = m_actionrect.left + m_ballpos.x * 32 + 2;
		ballrect.top = m_actionrect.top + m_ballpos.y * 32;
		ballrect.right = ballrect.left + 32;
		ballrect.bottom = ballrect.top + 32;
		dc.FillRect(&ballrect,&brush2);
		//绘制小蛇(头)
		CBitmap bmp_head;
		switch (m_actionorient)
		{
		case ORIENT_TOP:
			if (isheadopen)
				bmp_head.LoadBitmap(IDB_BMPHEADTOPCLOSE);
			else
				bmp_head.LoadBitmap(IDB_BMPHEADTOPOPEN);
			break;
		case ORIENT_BOTTOM:
			if (isheadopen)
				bmp_head.LoadBitmap(IDB_BMPHEADDOWNCLOSE);
			else
				bmp_head.LoadBitmap(IDB_BMPHEADDOWNOPEN);
			break;
		case ORIENT_LEFT:
			if (isheadopen)
				bmp_head.LoadBitmap(IDB_BMPHEADLEFTCLOSE);
			else
				bmp_head.LoadBitmap(IDB_BMPHEADLEFTOPEN);
			break;
		case ORIENT_RIGHT:
			if (isheadopen)
				bmp_head.LoadBitmap(IDB_BMPHEADRIGHTCLOSE);
			else
				bmp_head.LoadBitmap(IDB_BMPHEADRIGHTOPEN);
			break;
		}
		isheadopen = !isheadopen;
		CBrush brush3;
		brush3.CreatePatternBrush(&bmp_head);
		CRect headrect;
		this->GetCellRect(m_path[0],&headrect);
		dc.FillRect(&headrect,&brush3);
		//绘制小蛇(身体)
		CBitmap bmp_body;
		bmp_body.LoadBitmap(IDB_BMPBODY);
		CBrush brush4;
		brush4.CreatePatternBrush(&bmp_body);
		CRect bodyrect;
		for (int i = 1 ; i < m_pathlen ; i++)
		{
			this->GetCellRect(m_path[i],&bodyrect);
			dc.FillRect(&bodyrect,&brush4);	
		}
	}
	//绘制分数
	// 新建字体
	LOGFONT logFont;
	ZeroMemory(&logFont,sizeof(logFont));
	logFont.lfWidth = 6;
	logFont.lfHeight = 12;
	logFont.lfCharSet = GB2312_CHARSET;
	strcpy(logFont.lfFaceName, "宋体" );
	CFont fntNew;
	fntNew.CreateFontIndirect(&logFont);
	dc.SelectObject(&fntNew);
	CString str;
	str.Format("目前总积分:%d分",m_mark);
	CSize fntsize = dc.GetTextExtent(str);
	dc.SetTextColor(RGB(255,255,255));
	dc.SetBkMode(TRANSPARENT);
	dc.TextOut(m_scoreboardrect.left + (m_scoreboardrect.Width() - fntsize.cx) / 2,
		m_scoreboardrect.top + (m_scoreboardrect.Height() - fntsize.cy) / 2 - 3,
		str);


	sdc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
}
int n = 1;
BOOL CDrawDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();
	time_t t;
	n = time(&t);
	CalcRect();
	m_state = STATE_STOP;
	m_level = 500;
	m_mark = 0;
	return TRUE;  
}

void CDrawDialog::CalcBallPos()
{
	喵oint pos,temp;
	n++;
	srand(n);
	pos.x = rand() % 15;
	pos.y = rand() % 15;
	temp.x = m_actionrect.left + pos.x * 32 + 5;
	temp.y = m_actionrect.top + pos.y * 32 +5;
	if (pos.x ==0 || pos.y == 0)
	{
		CalcBallPos();
		return;
	}
	if (pos == m_ballpos)
	{
		CalcBallPos();
		return;
	}
	if (PtInRect(&m_barwall1,temp))
	{
		CalcBallPos();
		return;
	}
	if (PtInRect(&m_barwall2,temp))
	{
		CalcBallPos();
		return;
	}
	for (int i = 0 ; i < m_pathlen ; i++)
		if (pos == m_path[i])
		{
			CalcBallPos();
			return;
		}

	m_ballpos = pos;
}

void CDrawDialog::Start()
{
	CalcBallPos();//计算小球位置
	//蛇头起始位置
	memset(&m_path[0],-100,sizeof(喵oint) * 50);
	m_pathlen = 7;
	m_path[0].x = 1;
	m_path[0].y = 0;
	//游戏开始标记
	m_state = STATE_START;
	m_actionorient = ORIENT_BOTTOM;
	this->SetTimer(1,m_level,NULL);
	this->SetTimer(2,100,NULL);
	this->Invalidate(false);//重画
	
}

void CDrawDialog::CalcRect()
{
	this->GetClientRect(&m_actionrect);	

	m_scoreboardrect.left = m_actionrect.left + (m_actionrect.Width() - 292) / 2;
	m_scoreboardrect.top = m_actionrect.top;
	m_scoreboardrect.right = m_scoreboardrect.left + 292;
	m_scoreboardrect.bottom = m_actionrect.top + 62;

	m_actionrect.OffsetRect(30,62);
	m_actionrect.right = m_actionrect.left + 480 + 3;
	m_actionrect.bottom = m_actionrect.top + 480 + 3;

	m_barwall1.left = m_actionrect.left + 8 * 32 + 2;
	m_barwall1.top = m_actionrect.top + 9 * 32;
	m_barwall1.right = m_barwall1.left + 32;
	m_barwall1.bottom = m_actionrect.bottom;

	m_barwall2.left = m_actionrect.left + 3 * 32 + 2;
	m_barwall2.top = m_actionrect.top + 12 * 32 + 2;
	m_barwall2.right = m_barwall2.left + 3 * 32;
	m_barwall2.bottom = m_barwall2.top + 32;
}

void CDrawDialog::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	CalcRect();	
}

void CDrawDialog::OnTimer(UINT nIDEvent) 
{
	if (nIDEvent == 1)
	{
		if (m_state == STATE_START || m_state == STATE_COUNTINUE)
		{
			喵oint p;
			if (GetActionPos(&p))
			{
				if (p == m_ballpos)
				{
					CalcBallPos();
					m_pathlen++;
					//加分
					if (m_level == 500)
						m_mark += 100;
					else if (m_level == 300)
						m_mark += 300;
					else if (m_level == 100)
						m_mark += 500;
				}
				MovePos();
				m_path[0] = p;

				if (m_pathlen == 50)
				{
					if (m_level == 500)
					{
						m_level = 300;
					}else if (m_level == 300)
					{
						m_level = 100;
					}
					Start();
				}
			}
			else
			{
				m_mark -= 500;//失败减分
				Stop();
				MessageBox("GAME OVER!","提示!");
			}
		}
	}
	else
		this->Invalidate(false);
	CDialog::OnTimer(nIDEvent);
}

BOOL CDrawDialog::GetActionPos(喵oint *pos)
{
	//计算小蛇活动的下一个点
	喵oint tmppos;
	tmppos = m_path[0];
	switch (m_actionorient)
	{
	case ORIENT_LEFT:
		tmppos.x--;
		break;
	case ORIENT_TOP:
		tmppos.y--;
		break;
	case ORIENT_RIGHT:
		tmppos.x++;
		break;
	case ORIENT_BOTTOM:
		tmppos.y++;
		break;
	}
	//控制蛇在活动范围内
	if (tmppos.x >= 15 || tmppos.y >= 15
		 || tmppos.x < 0 || tmppos.y < 0) 
		 return false;
	//控制蛇不能碰到自己
	for (int i = 0 ; i < m_pathlen ; i++)
		if (tmppos == m_path[i])
			return false;
	//控制蛇不在阻挡墙内
	喵oint p;
	p.x = m_actionrect.left + tmppos.x * 32 + 5;
	p.y = m_actionrect.top + tmppos.y * 32 + 5;
	if (PtInRect(&m_barwall1,p) || PtInRect(&m_barwall2,p))
		return false;
	pos->x = tmppos.x;
	pos->y = tmppos.y;
	return true;
}

void CDrawDialog::MovePos()
{
	for (int i = m_pathlen - 1 ; i > 0 ; i--)
		m_path[i] = m_path[i-1];
}

void CDrawDialog::GetCellRect(喵oint pos,CRect *cellrect)
{
	cellrect->left = m_actionrect.left + pos.x * 32;
	cellrect->top = m_actionrect.top + pos.y * 32;
	cellrect->right = cellrect->left + 32;
	cellrect->bottom = cellrect->top + 32;
}

BOOL CDrawDialog::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
	{
		switch(pMsg->wParam)
        {
		case VK_UP:
			if (m_actionorient != ORIENT_BOTTOM)
				m_actionorient = ORIENT_TOP;
			break;
		case VK_DOWN:
			if (m_actionorient != ORIENT_TOP)
				m_actionorient = ORIENT_BOTTOM;
			break;
		case VK_LEFT:
			if (m_actionorient != ORIENT_RIGHT)
				m_actionorient = ORIENT_LEFT;
			break;
		case VK_RIGHT:
			if (m_actionorient != ORIENT_LEFT)
				m_actionorient = ORIENT_RIGHT;
			break;
		case VK_F2:
			Start();
			break;
		case VK_F3:
			Pause();
			break;
		case VK_F4:
			Stop();
			break;
		case VK_F5:
			m_level = 500;
			break;
		case VK_F6:
			m_level = 300;
			break;
		case VK_F7:
			m_level = 100;
			break;
        }
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CDrawDialog::Stop() 
{
	m_state = STATE_STOP;	
}

void CDrawDialog::Pause()
{
	if (m_state == STATE_START || m_state == STATE_COUNTINUE)
	{
		m_state = STATE_PAUSE;
	}
	else if (m_state == STATE_PAUSE)
	{
		m_state = STATE_COUNTINUE;
	}
	this->Invalidate(false);
}

ESTATE CDrawDialog::GetState()
{
	return m_state;
}



void CDrawDialog::SetLevel(int level)
{
	m_level = level;
}


回复

上一页1 页 / 共 0下一页