📄 snakeview.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 + -