用户:
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;
}