📄 snakewnd.cpp
字号:
// SnakeWnd.cpp : implementation file
//
#include "stdafx.h"
#include "Snake.h"
#include "SnakeWnd.h"
#include "SnakeDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSnakeWnd
CSnakeWnd::CSnakeWnd()
{
m_ndirection=1;
m_nLastDriction=1;
m_RandPos=CPoint(-1,-1);
m_ms=200;
m_IsAnto=FALSE;
}
CSnakeWnd::~CSnakeWnd()
{
}
BEGIN_MESSAGE_MAP(CSnakeWnd, CWnd)
//{{AFX_MSG_MAP(CSnakeWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_TIMER()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSnakeWnd message handlers
int CSnakeWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
InitSnake();
return 0;
}
void CSnakeWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(m_RandPos==CPoint(-1,-1))
{
m_RandPos=GetPointInSHow();
}
CRect rect;
GetClientRect(&rect);
CDC memDC;
CBitmap Bitmap,*pBitmap;
memDC.CreateCompatibleDC(&dc);
Bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
pBitmap=(CBitmap*)memDC.SelectObject(&Bitmap);
memDC.FillSolidRect(rect,RGB(212,222,255));
memDC.SetBkMode(TRANSPARENT);
for(int i=0;i<m_SnakeList.GetCount();i++)
{
POSITION pos=m_SnakeList.FindIndex(i);
SNAKEBLOCK *psNakeBlock=m_SnakeList.GetAt(pos);
if(psNakeBlock->Ishoriz)
{
DrawBlockH(&memDC,psNakeBlock->rect);
}
else
{
DrawBlockV(&memDC,psNakeBlock->rect);
}
}
if(m_RandPos.x!=-1 && m_RandPos.y!=-1)
{
CBrush brush(RGB(0,0,255));
CRgn rgn;
rgn.CreateRoundRectRgn(m_RandPos.x-3,m_RandPos.y-3, m_RandPos.x+3, m_RandPos.y+3,180,180);
memDC.FillRgn(&rgn,&brush);
}
dc.BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
memDC.SelectObject(pBitmap);
pBitmap->DeleteObject();
memDC.DeleteDC();
// Do not call CWnd::OnPaint() for painting messages
}
void CSnakeWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(!m_IsAnto)
{
m_nLastDriction=m_ndirection;
if(nChar=='A')
{
if(m_ndirection!=3)
{
m_ndirection=1;
}
}
if(nChar=='W')
{
if(m_ndirection!=4)
{
m_ndirection=2;
}
}
if(nChar=='D')
{
if(m_ndirection!=1)
{
m_ndirection=3;
}
}
if(nChar=='S')
{
if(m_ndirection!=2)
{
m_ndirection=4;
}
}
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSnakeWnd::DrawBlockH(CDC *pDC,CRect rect)
{
pDC->FillSolidRect(rect,RGB(212,222,255));
CRect rect1=CRect(rect.left+BLOCKWIDTH/3,rect.top,rect.left+2*BLOCKWIDTH/3,rect.top+BLOCKHEIGHT/2);
pDC->FillSolidRect(rect1,RGB(250,0,0));
CRect rect2=CRect(rect.left+2*BLOCKWIDTH/3,rect.top,rect.right,rect.top+BLOCKHEIGHT/2);
pDC->FillSolidRect(rect2,RGB(250,0,100));
CRect rect3=CRect(rect.left,rect.top+BLOCKHEIGHT/2,rect.left+BLOCKWIDTH/3,rect.bottom);
pDC->FillSolidRect(rect3,RGB(250,0,0));
CRect rect4=CRect(rect.left+BLOCKWIDTH/3,rect.top+BLOCKHEIGHT/2,rect.left+2*BLOCKWIDTH/3,rect.bottom);
pDC->FillSolidRect(rect4,RGB(250,0,100));
}
void CSnakeWnd::DrawBlockV(CDC *pDC,CRect rect)
{
pDC->FillSolidRect(rect,RGB(212,222,255));
CRect rect1=CRect(rect.left,rect.top,rect.left+BLOCKHEIGHT/2,rect.top+BLOCKWIDTH/3);
pDC->FillSolidRect(rect1,RGB(250,0,0));
CRect rect2=CRect(rect.left,rect.top+BLOCKWIDTH/3,rect.left+BLOCKHEIGHT/2,rect.top+2*BLOCKWIDTH/3);
pDC->FillSolidRect(rect2,RGB(250,0,100));
CRect rect3=CRect(rect.left+BLOCKHEIGHT/2,rect.top+BLOCKWIDTH/3,rect.right,rect.top+2*BLOCKWIDTH/3);
pDC->FillSolidRect(rect3,RGB(250,0,0));
CRect rect4=CRect(rect.left+BLOCKHEIGHT/2,rect.top+2*BLOCKWIDTH/3,rect.right,rect.bottom);
pDC->FillSolidRect(rect4,RGB(250,0,100));
}
void CSnakeWnd::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==1)
{
if(IsOver())
{
InitSnake();
return;
}
if(m_IsAnto)
{
AutoMove();
}
SNAKEBLOCK *pHeadsNakeBlock =m_SnakeList.GetHead();
SNAKEBLOCK *psNakeBlock=new SNAKEBLOCK;
*psNakeBlock=*pHeadsNakeBlock;
if(m_ndirection==1)
{
if(psNakeBlock->Ishoriz)
{
psNakeBlock->rect.left-=BLOCKWIDTH;
psNakeBlock->rect.right-=BLOCKWIDTH;
if(psNakeBlock->rect.left<=0)
{
psNakeBlock->rect.left=rectWnd.right-BLOCKWIDTH;
psNakeBlock->rect.right=rectWnd.right;
}
}
else
{
psNakeBlock->Ishoriz=TRUE;
if(m_nLastDriction==2)
{
psNakeBlock->rect.left-=BLOCKWIDTH;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKHEIGHT;
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKWIDTH;
}
if(m_nLastDriction==4)
{
psNakeBlock->rect.left-=BLOCKWIDTH;
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKWIDTH;
psNakeBlock->rect.top=psNakeBlock->rect.bottom-BLOCKHEIGHT;
}
if(psNakeBlock->rect.left<=0)
{
psNakeBlock->rect.left=rectWnd.right-BLOCKWIDTH;
psNakeBlock->rect.right=rectWnd.right;
}
}
}
if(m_ndirection==2)
{
if(!psNakeBlock->Ishoriz)
{
psNakeBlock->rect.top-=BLOCKWIDTH;
psNakeBlock->rect.bottom-=BLOCKWIDTH;
if(psNakeBlock->rect.top<=0)
{
psNakeBlock->rect.top=rectWnd.bottom-BLOCKWIDTH;
psNakeBlock->rect.bottom=rectWnd.bottom;
}
}
else
{
psNakeBlock->Ishoriz=FALSE;
if(m_nLastDriction==1)
{
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKHEIGHT;
psNakeBlock->rect.top-=BLOCKWIDTH;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKWIDTH;
}
if(m_nLastDriction==3)
{
psNakeBlock->rect.left=psNakeBlock->rect.right-BLOCKHEIGHT;
psNakeBlock->rect.top-=BLOCKWIDTH;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKWIDTH;
}
if(psNakeBlock->rect.top<=0)
{
psNakeBlock->rect.top=rectWnd.bottom-BLOCKWIDTH;
psNakeBlock->rect.bottom=rectWnd.bottom;
}
}
}
if(m_ndirection==3)
{
if(psNakeBlock->Ishoriz)
{
psNakeBlock->rect.left+=BLOCKWIDTH;
psNakeBlock->rect.right+=BLOCKWIDTH;
if(psNakeBlock->rect.right>=rectWnd.right)
{
psNakeBlock->rect.left=rectWnd.left;
psNakeBlock->rect.right=rectWnd.left+BLOCKWIDTH;
}
}
else
{
psNakeBlock->Ishoriz=TRUE;
if(m_nLastDriction==2)
{
psNakeBlock->rect.left=psNakeBlock->rect.right;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKHEIGHT;
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKWIDTH;
}
if(m_nLastDriction==4)
{
psNakeBlock->rect.left=psNakeBlock->rect.right;
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKWIDTH;
psNakeBlock->rect.top=psNakeBlock->rect.bottom-BLOCKHEIGHT;
}
if(psNakeBlock->rect.right>=rectWnd.right)
{
psNakeBlock->rect.left=rectWnd.left;
psNakeBlock->rect.right=rectWnd.left+BLOCKWIDTH;
}
}
}
if(m_ndirection==4)
{
if(!psNakeBlock->Ishoriz)
{
psNakeBlock->rect.top+=BLOCKWIDTH;
psNakeBlock->rect.bottom+=BLOCKWIDTH;
if(psNakeBlock->rect.bottom>=rectWnd.bottom)
{
psNakeBlock->rect.top=rectWnd.top;
psNakeBlock->rect.bottom=rectWnd.top+BLOCKWIDTH;
}
}
else
{
psNakeBlock->Ishoriz=FALSE;
if(m_nLastDriction==3)
{
psNakeBlock->rect.left=psNakeBlock->rect.right-BLOCKHEIGHT;
psNakeBlock->rect.top=psNakeBlock->rect.bottom;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKWIDTH;
}
if(m_nLastDriction==1)
{
psNakeBlock->rect.right=psNakeBlock->rect.left+BLOCKHEIGHT;
psNakeBlock->rect.top=psNakeBlock->rect.bottom;
psNakeBlock->rect.bottom=psNakeBlock->rect.top+BLOCKWIDTH;
}
if(psNakeBlock->rect.bottom>=rectWnd.bottom)
{
psNakeBlock->rect.top=rectWnd.top;
psNakeBlock->rect.bottom=rectWnd.top+BLOCKWIDTH;
}
}
}
m_SnakeList.AddHead(psNakeBlock);
if(IsInSnakeHead(m_RandPos))
{
m_RandPos=GetPointInSHow();
}
else
{
m_SnakeList.RemoveTail();
}
CString str;
str.Format("%d",m_SnakeList.GetCount());
((CSnakeDlg*)GetParent())->m_SnakeLength.SetWindowText(str);
Invalidate();
}
CWnd::OnTimer(nIDEvent);
}
void CSnakeWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
GetClientRect(&rectWnd);
}
BOOL CSnakeWnd::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message==WM_KEYDOWN )
{
if(!m_IsAnto)
{
m_nLastDriction=m_ndirection;
if(pMsg->wParam==VK_LEFT)
{
if(m_ndirection!=3)
{
m_ndirection=1;
}
}
if(pMsg->wParam==VK_UP)
{
if(m_ndirection!=4)
{
m_ndirection=2;
}
}
if(pMsg->wParam==VK_RIGHT)
{
if(m_ndirection!=1)
{
m_ndirection=3;
}
}
if(pMsg->wParam==VK_DOWN)
{
if(m_ndirection!=2)
{
m_ndirection=4;
}
}
}
}
return CWnd::PreTranslateMessage(pMsg);
}
CPoint CSnakeWnd::GetPointInSHow()
{
int x=rand()%(rectWnd.Width()-2*BLOCKWIDTH)+BLOCKWIDTH;
int y=rand()%(rectWnd.Height()-2*BLOCKWIDTH)+BLOCKWIDTH;
x=(x/BLOCKWIDTH)*BLOCKWIDTH;
y=(y/BLOCKWIDTH)*BLOCKWIDTH;
CPoint pt(x,y);
while(IsInSnake(pt)&&IsInSnakeHead(pt))
{
x=rand()%(rectWnd.Width()-2*BLOCKWIDTH)+BLOCKWIDTH;
y=rand()%(rectWnd.Height()-2*BLOCKWIDTH)+BLOCKWIDTH;
x=(x/BLOCKWIDTH)*BLOCKWIDTH;
y=(y/BLOCKWIDTH)*BLOCKWIDTH;
pt=CPoint(x,y);
}
return pt;
}
BOOL CSnakeWnd::IsInSnakeHead(CPoint pt)
{
SNAKEBLOCK *psNakeBlock=m_SnakeList.GetHead();
if(psNakeBlock->rect.PtInRect(pt) || psNakeBlock->rect.PtInRect(CPoint(pt.x-2,pt.y-2)) || psNakeBlock->rect.PtInRect(CPoint(pt.x+2,pt.y+2)))
{
return TRUE;
}
return FALSE;
}
BOOL CSnakeWnd::IsInSnake(CPoint pt)
{
for(int i=1;i<m_SnakeList.GetCount();i++)
{
POSITION pos=m_SnakeList.FindIndex(i);
SNAKEBLOCK *psNakeBlock=m_SnakeList.GetAt(pos);
if(psNakeBlock->rect.PtInRect(pt))
{
return TRUE;
}
}
return FALSE;
}
void CSnakeWnd::InitSnake()
{
m_SnakeList.RemoveAll();
SNAKEBLOCK *psNakeBlock=new SNAKEBLOCK;
psNakeBlock->Ishoriz=TRUE;
psNakeBlock->rect=CRect(BLOCKWIDTH,BLOCKWIDTH,2*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock);
SNAKEBLOCK *psNakeBlock1=new SNAKEBLOCK;
psNakeBlock1->Ishoriz=TRUE;
psNakeBlock1->rect=CRect(2*BLOCKWIDTH,BLOCKWIDTH,3*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock1);
SNAKEBLOCK *psNakeBlock2=new SNAKEBLOCK;
psNakeBlock2->Ishoriz=TRUE;
psNakeBlock2->rect=CRect(3*BLOCKWIDTH,BLOCKWIDTH,4*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock2);
SNAKEBLOCK *psNakeBlock3=new SNAKEBLOCK;
psNakeBlock3->Ishoriz=TRUE;
psNakeBlock3->rect=CRect(4*BLOCKWIDTH,BLOCKWIDTH,5*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock3);
SNAKEBLOCK *psNakeBlock4=new SNAKEBLOCK;
psNakeBlock4->Ishoriz=TRUE;
psNakeBlock4->rect=CRect(5*BLOCKWIDTH,BLOCKWIDTH,6*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock4);
SNAKEBLOCK *psNakeBlock5=new SNAKEBLOCK;
psNakeBlock5->Ishoriz=TRUE;
psNakeBlock5->rect=CRect(6*BLOCKWIDTH,BLOCKWIDTH,7*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock5);
SNAKEBLOCK *psNakeBlock6=new SNAKEBLOCK;
psNakeBlock6->Ishoriz=TRUE;
psNakeBlock6->rect=CRect(7*BLOCKWIDTH,BLOCKWIDTH,8*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock6);
SNAKEBLOCK *psNakeBlock7=new SNAKEBLOCK;
psNakeBlock7->Ishoriz=TRUE;
psNakeBlock7->rect=CRect(8*BLOCKWIDTH,BLOCKWIDTH,9*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock7);
SNAKEBLOCK *psNakeBlock8=new SNAKEBLOCK;
psNakeBlock8->Ishoriz=TRUE;
psNakeBlock8->rect=CRect(9*BLOCKWIDTH,BLOCKWIDTH,10*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock8);
SNAKEBLOCK *psNakeBlock9=new SNAKEBLOCK;
psNakeBlock9->Ishoriz=TRUE;
psNakeBlock9->rect=CRect(10*BLOCKWIDTH,BLOCKWIDTH,11*BLOCKWIDTH,BLOCKWIDTH+BLOCKHEIGHT);
m_SnakeList.AddTail(psNakeBlock9);
}
BOOL CSnakeWnd::IsOver()
{
SNAKEBLOCK *psNakeBlock=m_SnakeList.GetHead();
CPoint pt(psNakeBlock->rect.left+psNakeBlock->rect.Width()/2,psNakeBlock->rect.top+psNakeBlock->rect.Height()/2);
if(IsInSnake(pt))
{
KillTimer(1);
InitSnake();
AfxMessageBox("Game Over...");
return TRUE;
}
return FALSE;
}
void CSnakeWnd::SetSpeed(int ms)
{
KillTimer(1);
SetTimer(1,ms,NULL);
m_ms=ms;
}
void CSnakeWnd::AutoMove()
{
m_nLastDriction=m_ndirection;
SNAKEBLOCK *psNakeBlock=m_SnakeList.GetHead();
CPoint pt(psNakeBlock->rect.left,psNakeBlock->rect.top);
if(pt.x<m_RandPos.x-2 && pt.y<m_RandPos.y-2)
{
if(m_ndirection==1)
{
m_ndirection=4;
}
if(m_ndirection==2)
{
m_ndirection=3;
}
}
if(pt.x<m_RandPos.x-2 && pt.y>m_RandPos.y+2)
{
if(m_ndirection==1)
{
m_ndirection=2;
}
if(m_ndirection==4)
{
m_ndirection=3;
}
}
if(pt.x>m_RandPos.x+2 && pt.y<m_RandPos.y-2)
{
if(m_ndirection==2)
{
m_ndirection=1;
}
if(m_ndirection==3)
{
m_ndirection=4;
}
}
if(pt.x>m_RandPos.x+2 && pt.y>m_RandPos.y+2)
{
if(m_ndirection==3)
{
m_ndirection=2;
}
if(m_ndirection==4)
{
m_ndirection=1;
}
}
if((pt.x>=m_RandPos.x-2 && pt.x<=m_RandPos.x+2) && pt.y<m_RandPos.y-2)
{
if(m_ndirection==1)
{
m_ndirection=4;
}
if(m_ndirection==3)
{
m_ndirection=4;
}
if(m_ndirection==2)
{
m_ndirection=1;
}
}
if((pt.x>=m_RandPos.x-2 && pt.x<=m_RandPos.x+2) && pt.y>m_RandPos.y+2)
{
if(m_ndirection==1)
{
m_ndirection=2;
}
if(m_ndirection==3)
{
m_ndirection=2;
}
if(m_ndirection==4)
{
m_ndirection=3;
}
}
if(pt.x<m_RandPos.x-2 && (pt.y>=m_RandPos.y-2 && pt.y<=m_RandPos.y+2))
{
if(m_ndirection==2)
{
m_ndirection=3;
}
if(m_ndirection==4)
{
m_ndirection=3;
}
if(m_ndirection==1)
{
m_ndirection=4;
}
}
if(pt.x>m_RandPos.x-2 && (pt.y>=m_RandPos.y-2 && pt.y<=m_RandPos.y+2))
{
if(m_ndirection==2)
{
m_ndirection=1;
}
if(m_ndirection==4)
{
m_ndirection=1;
}
if(m_ndirection==3)
{
m_ndirection=2;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -