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

📄 snakeview.cpp

📁 利用MFC编写的一个贪吃蛇游戏
💻 CPP
字号:
// SnakeView.cpp : implementation of the CSnakeView class
//

#include "stdafx.h"
#include "Snake.h"

#include "SnakeDoc.h"
#include "SnakeView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSnakeView

IMPLEMENT_DYNCREATE(CSnakeView, CView)

BEGIN_MESSAGE_MAP(CSnakeView, CView)
	//{{AFX_MSG_MAP(CSnakeView)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_NEWGAME, OnNewgame)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSnakeView construction/destruction

CSnakeView::CSnakeView()
{
	// TODO: add construction code here

	//初始化标记	
	init_flag=0;


/////////////////////初始化蛇的属性///////////////////////
	life=1;
    node_num=10;
	node_size=20;
	direction=1;
    
	
    // 蛇头初始化	
	node[0].x=320;
	node[0].y=240;
	
    
	
	//初始化蛇身体各节点坐标
	for(int i=1;i<=(node_num-1);i++) 
	{
		node[i].x=node[0].x+i*node_size;
		node[i].y=node[0].y;
	}
    
	////////////初始化食物的相关数据///////////////////////

	food_exist=0;

	food_pos.x=100;
	food_pos.y=100;

    /////////////////////初始化分数 //////////////////////
	score=0;
	m_str="";


	
}

CSnakeView::~CSnakeView()
{
}

BOOL CSnakeView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSnakeView drawing


/*************************每次窗口更新时都重绘************************/
void CSnakeView::OnDraw(CDC* pDC)
{
	CSnakeDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here


	
    //画出下边线
	pDC->MoveTo(0,480);
	pDC->LineTo(640,480);

    //显示分数
    m_str.Format("SCORE:%u",score);
	pDC->TextOut(0,485,m_str);

	//画背景
	pDC->BitBlt(0,0,640,480,&m_BkgDC,0,0,SRCCOPY);
	


	CRect rect1,rect2,rect3;

	//画食物
	if(!IsGameOver()&&IsInitGame())
	{
	
	rect1.top=food_pos.y;
    rect1.left=food_pos.x;
	rect1.bottom=food_pos.y+node_size;
	rect1.right=food_pos.x+node_size;
    

	pDC->BitBlt(rect1.left,rect1.top,20,20,&m_FoodDC,0,0,SRCCOPY);
	}



  

	

    
//每次窗口重绘时都重画蛇

	
	CBitmap  bitmap_head;

	if(!IsGameOver())
	{

	
		for(int i=1;i<node_num;i++)
		{
			rect2.top=node[i].y;
			rect2.left=node[i].x;
	        rect2.bottom=node[i].y+node_size;
	        rect2.right=node[i].x+node_size;
		    
			pDC->BitBlt(rect2.left,rect2.top,20,20,&m_BodyDC,0,0,SRCCOPY);
		}

		
		switch(direction)
		{
		case 1:
			bitmap_head.LoadBitmap(IDB_HEAD_LEFT);break;
		case 2:
			bitmap_head.LoadBitmap(IDB_HEAD_RIGHT);break;
		case 3:
			bitmap_head.LoadBitmap(IDB_HEAD_UP);break;
		case 4:
			bitmap_head.LoadBitmap(IDB_HEAD_DOWN);break;
		}

		CBrush brush_head(&bitmap_head);
		rect3.top=node[0].y;
		rect3.left=node[0].x;
	    rect3.bottom=node[0].y+node_size;
	    rect3.right=node[0].x+node_size;
		pDC->FillRect(rect3,&brush_head);

	}

}

/////////////////////////////////////////////////////////////////////////////
// CSnakeView printing

BOOL CSnakeView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CSnakeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CSnakeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CSnakeView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CSnakeView message handlers



BOOL CSnakeView::IsDirectionChange()
{
	if(old_direction==direction)return FALSE;
	else
		return TRUE;

}

/**********************蛇移动***************************/
void CSnakeView::SnakeMove(int direction)
{
	for(int i=node_num-1;i>0;i--)//重新给各节点坐标赋值,具体画出来在OnDraw中
	{
		node[i].x=node[i-1].x;
		node[i].y=node[i-1].y;
	}

	
	switch(direction)
	{
	     case 1:
			node[0].x=node[0].x-node_size;break;
	     case 2:
			node[0].x=node[0].x+node_size;break;
	     case 3:
			node[0].y=node[0].y-node_size;break;
	     case 4:
			node[0].y=node[0].y+node_size;break;
	}
	
	

	
   
}
/**********************窗口创建前的准备工作***************************/
int CSnakeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;


	// TODO: Add your specialized creation code here

	//每100毫秒发送一条消息,用于设置蛇的运动速度
	
	SetTimer(1,100,NULL);
	
	//初始化内存位图

	//背景
    m_BkgDC.CreateCompatibleDC(GetDC());
	m_BkgBmp.LoadBitmap(IDB_BACKGROUND);
	m_BkgDC.SelectObject(&m_BkgBmp);
    //蛇身
	m_BodyDC.CreateCompatibleDC(GetDC());
	m_BodyBmp.LoadBitmap(IDB_BODY);
	m_BodyDC.SelectObject(&m_BodyBmp);
    //食物
	m_FoodDC.CreateCompatibleDC(GetDC());
	m_FoodBmp.LoadBitmap(IDB_FOOD);
	m_FoodDC.SelectObject(&m_FoodBmp);

	
	
	return 0;
}
/***********************对TIMER消息的响应**************************/
void CSnakeView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default

	Invalidate(FALSE);//窗口更新
 	if(!IsInitGame())
	{
		InitGame();
		init_flag=1;
	}
	if(!IsFoodExist())
	{
		CreateFood();
		food_exist=1;
	}

	
 
	if(!IsGameOver())
	{ 
		SnakeMove(direction);
		
		if(IsEat())
		{
			BecomeLonger();
			ScoreIncrease();
		    DisappearFood();
		    food_exist=0;
		}
	
		
	
		if(IsGameOver())
		{
		AfxMessageBox("GameOver");
		}
		
	}

	
	CView::OnTimer(nIDEvent);
}


/***********************捕获键盘消息**************************/
void CSnakeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
    switch(nChar)
	{
	case VK_LEFT:
		if(direction!=2) direction=1;;break;
	
	case VK_RIGHT:
		if(direction!=1) direction=2;old_direction=2;break;
	
	case VK_UP:
		if(direction!=4) direction=3;old_direction=3;break;
	
	case VK_DOWN:
		if(direction!=3) direction=4;old_direction=4;break;
	
	}



	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


/******************判断游戏是否结束****************/
BOOL CSnakeView::IsGameOver()
{
	
	for(int i=1;i<=node_num-1;i++)
	{
		if(node[0].x==node[i].x&&node[0].y==node[i].y)
			return TRUE;
	}
	
   // if(life==1)
	//	return FALSE;
	if(node[0].x<0||node[0].x>(640-node_size)||node[0].y>(480-node_size)||node[0].y<0)
		return TRUE;
    
	else
		return FALSE;
}


/***********************创建食物*************************/
void CSnakeView::CreateFood()
{
	int equal;
	while(1)
	{
		food_pos.x=rand()%640/node_size*node_size;
		food_pos.y=rand()%480/node_size*node_size;
	    for(int i=0;i<=node_num-1;i++)
		{
				if(node[i].x==food_pos.x&&node[i].y==food_pos.y) 
				{
					equal=1;
					break;
				}
				else
					equal=0;
		}

		if(equal==0)break;
	}
		
     
}

/************************判断食物是否存在*************************/
BOOL CSnakeView::IsFoodExist()
{
	if(0==food_exist) return FALSE;
	else
		return TRUE;

}

/****************食物消失********************/
void CSnakeView::DisappearFood()
{
///////////把食物的坐标赋值/////////////	
	m_rect.left=food_pos.x;
	m_rect.top=food_pos.y;
	m_rect.right=food_pos.x+node_size;
	m_rect.bottom=food_pos.y+node_size;
	
}
/*******************判断是否吃了食物****************/
BOOL CSnakeView::IsEat()
{
    if((node[0].x==food_pos.x)&&node[0].y==food_pos.y)
		return TRUE;
	else
		return FALSE;
}


/*****************蛇变长***********************/
void CSnakeView::BecomeLonger()
{
    node_num=node_num+1;
}


/*********************分数增加****************************/
void CSnakeView::ScoreIncrease()
{
	score=score+10;
}

/*****************初始化函数**********************/
void CSnakeView::InitGame()
{
	////////////初始化蛇的属性////////////
	life=1;
    node_num=10;
	node_size=20;
	direction=1;
   
	
	//蛇头
	node[0].x=320;
	node[0].y=240;
	
    
	
	//初始化蛇身各节点坐标
	for(int i=1;i<=(node_num-1);i++) 
	{
		node[i].x=node[0].x+i*node_size;
		node[i].y=node[0].y;
	}
    //////////////初始化食物的相关数据/////////////

	food_exist=0;

	food_pos.x=-100;
	food_pos.y=-100;

    /////////////初始化分数////////////////// 
	score=0;
	m_str="";

	
    
    
	
}
/*************************判断是否初始化游戏********************************/
BOOL CSnakeView::IsInitGame()
{
     if(0==init_flag)return FALSE;
	 else
		 return TRUE; 
   
}

/*********************对菜单项“新游戏”的响应****************************/
void CSnakeView::OnNewgame() 
{
	// TODO: Add your command handler code here
   init_flag=1;	
   InitGame();
   Invalidate(TRUE);
}

⌨️ 快捷键说明

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