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

📄 snakewnd.cpp

📁 贪吃蛇自动吃事,暂无处理碰壁情况,可以自己试着处理下
💻 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 + -