贪食蛇源代码,初学写的第一个MFC 程序,帮忙找缺陷,谢谢
第一次写MFC程序```帮忙找点不规范或者错误的代码,谢谢````
exe程序在这里
http://edgepersonzhang.googlepages.com/snake.exe
源代码如下:
Snake.h
#include <deque>using namespace std;class CSnakeApp : public CWinApp{public: BOOL InitInstance ();};class CSnakeWnd : public CFrameWnd{public://因为超过发贴最大字数,函数声明只有省了. :)private: CPoint food; CPoint foodready; deque<CPoint> Snake; UINT SnakeWay; CPoint temp; bool map_on; UINT way; bool timer; int length;protected: void OnPaint(); void OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags ); void OnTimer(UINT nTimerID); DECLARE_MESSAGE_MAP()};
#include <afxwin.h>
#include <cstdlib>
#include "snake.h"
#include "resource.h"
CSnakeApp SnakeApp;
BOOL CSnakeApp::InitInstance()
{
this->m_pMainWnd=new CSnakeWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return true;
}
BEGIN_MESSAGE_MAP(CSnakeWnd,CFrameWnd)
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_TIMER()
ON_COMMAND(ID_Start, &CSnakeWnd::OnStart)
ON_COMMAND(ID_Quit, &CSnakeWnd::SnakeQuit)
ON_COMMAND(ID_map_on, &CSnakeWnd::SnakeMapON)
ON_COMMAND(ID_map_off, &CSnakeWnd::OnMapOff)
ON_COMMAND(ID_About, &CSnakeWnd::OnAbout)
ON_COMMAND(ID_Pause, &CSnakeWnd::OnPause)
ON_WM_SIZE()
END_MESSAGE_MAP()
CSnakeWnd::CSnakeWnd()
{
RECT wndrect;
wndrect.top=100;
wndrect.bottom=736;
wndrect.left=100;
wndrect.right=750;
this->Create(NULL,_T("Snake"),WS_OVERLAPPEDWINDOW &~WS_MAXIMIZEBOX &~WS_THICKFRAME,wndrect,NULL,MAKEINTRESOURCE(IDR_MENU1));
food.SetPoint(-50,-50);
map_on=false;
timer=false;
}
void CSnakeWnd::OnPaint()
{
CPaintDC BDDC(this);
BDDC.SelectStockObject(WHITE_BRUSH);
BDDC.Rectangle(-1,99,641,581);
BDDC.Rectangle(-1,-1,641,99);
BDDC.DeleteDC();
if(map_on)
{
DrawMap();
}
else
{
DrawBD();
}
Title();
DrawSnake();
DrawFood(food);
}
BOOL CSnakeWnd::DrawBD()
{
CClientDC BDDC(this);
BDDC.SelectStockObject(WHITE_BRUSH);
BDDC.Rectangle(-1,99,641,581);
BDDC.Rectangle(-1,-1,641,99);
BDDC.DeleteDC();
return true;
}
BOOL CSnakeWnd::DrawMap()
{
CClientDC MapDC(this);
CPen pen(PS_DOT,1,RGB(192,192,192));
MapDC.SelectObject(pen);
CRect rect(0,100,640,580);
int start;
for(start=0;start <641;start+=10)
{
MapDC.MoveTo(start,rect.top);
MapDC.LineTo(start,rect.bottom);
}
for(start=100;start <581;start+=10)
{
MapDC.MoveTo(rect.left,start);
MapDC.LineTo(rect.right,start);
}
MapDC.DeleteDC();
return true;
}
BOOL CSnakeWnd::DrawSnake()
{
deque <CPoint>::iterator pos;
for(pos=Snake.begin();pos!=Snake.end();++pos)
{
DrawSnakePart(*pos);
}
DelSnakePart(foodready);
return true;
}
BOOL CSnakeWnd::DrawSnakePart(CPoint Snake)
{
CClientDC SnakeDC(this);
SnakeDC.SelectStockObject(GRAY_BRUSH);
SnakeDC.Ellipse(Snake.x,Snake.y,Snake.x+10,Snake.y+10);
SnakeDC.DeleteDC();
return true;
}
BOOL CSnakeWnd::DrawFood(CPoint Food)
{
CClientDC FoodDC(this);
FoodDC.SelectStockObject(WHITE_BRUSH);
FoodDC.Ellipse(Food.x,Food.y,Food.x+10,Food.y+10);
FoodDC.DeleteDC();
return true;
}
BOOL CSnakeWnd::DelSnakePart(CPoint Snake)
{
CClientDC SnakeDC(this);
SnakeDC.SelectStockObject(WHITE_BRUSH);
SnakeDC.SelectStockObject(WHITE_PEN);
SnakeDC.Ellipse(Snake.x,Snake.y,Snake.x+10,Snake.y+10);
SnakeDC.DeleteDC();
return true;
}
void CSnakeWnd::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags )
{
SnakeWay=nChar;
}
void CSnakeWnd::OnTimer(UINT nTimerID)
{
if(Afoul())
{
gameover();
}
else
{
SnakeMove();
OnPaint();
}
}
BOOL CSnakeWnd::eat()
{
if(food==Snake.front())
{
Snake.push_back(foodready);
makefood();
}
return true;
}
BOOL CSnakeWnd::makefood()
{
loop:const int RANGE_MIN_X = 0;
const int RANGE_MAX_X = 63;
const int randx = (((double) rand() / (double) RAND_MAX) * RANGE_MAX_X + RANGE_MIN_X);
const int RANGE_MIN_Y = 10;
const int RANGE_MAX_Y = 47;
const int randy = (((double) rand() / (double) RAND_MAX) * RANGE_MAX_Y + RANGE_MIN_Y);
food.x=randx*10;
food.y=randy*10;
deque <CPoint>::iterator pos;
for(pos=Snake.begin(),++pos;pos!=Snake.end();++pos)
{
if(food==*pos)
{
goto loop;
}
}
DrawFood(food);
return true;
}
BOOL CSnakeWnd::InitSnake()
{
way=VK_RIGHT;
Snake.clear();
CPoint Init(50,150);
for(int i=0;i!=5;++i )
{
Snake.push_front(Init);
Init.x+=10;
}
SnakeWay=VK_RIGHT;
SnakeMove();
return true;
}
BOOL CSnakeWnd::SnakeLeft()
{
if(way==VK_RIGHT)
{
SnakeRight();
return true;
}
else
{
temp=Snake.front();
temp.x-=10;
if(Afoul())
{
gameover();
}
else
{
Snake.push_front(temp);
foodready=Snake.back();
Snake.pop_back();
eat();
}
way=VK_LEFT;
}
return true;
}
BOOL CSnakeWnd::SnakeRight()
{
if(way==VK_LEFT)
{
SnakeLeft();
return true;
}
else
{
temp=Snake.front();
temp.x+=10;
if(Afoul())
{
gameover();
}
else
{
Snake.push_front(temp);
foodready=Snake.back();
Snake.pop_back();
eat();
}
way=VK_RIGHT;
}
return true;
}
BOOL CSnakeWnd::SnakeUp()
{
if(way==VK_DOWN)
{
SnakeDown();
return true;
}
else
{
temp=Snake.front();
temp.y-=10;
if(Afoul())
{
gameover();
}
else
{
Snake.push_front(temp);
foodready=Snake.back();
Snake.pop_back();
eat();
}
way=VK_UP;
}
return true;
}
BOOL CSnakeWnd::SnakeDown()
{
if(way==VK_UP)
{
SnakeUp();
return true;
}
else
{
temp=Snake.front();
temp.y+=10;
if(Afoul())
{
gameover();
}
else
{
Snake.push_front(temp);
foodready=Snake.back();
Snake.pop_back();
eat();
}
way=VK_DOWN;
}
return true;
}
void CSnakeWnd::startgame()
{
DrawBD();
InitSnake();
makefood();
SetTimer(1,50,NULL);
timer=true;
}
void CSnakeWnd::gameover()
{
this->KillTimer(1);
timer=false;
MessageBox(_T("Game Over"));
}
BOOL CSnakeWnd::SnakeMove()
{
switch(SnakeWay)
{
case VK_LEFT :SnakeLeft();
break;
case VK_RIGHT :SnakeRight();
break;
case VK_UP :SnakeUp();
break;
case VK_DOWN :SnakeDown();
break;
default:
;
}
return true;
}
BOOL CSnakeWnd::Title()
{
CClientDC TitleDC(this);
CRect rect(0,0,630,100);
length=Snake.size();
rect.SetRect(500,70,630,100);
CString text("分数: ");
TitleDC.DrawText(text,&rect,DT_SINGLELINE);
rect.SetRect(540,70,630,100);
length-=5;
if(length <0)
{
length=0;
}
text.Format("%d",length);
TitleDC.DrawText(text,&rect,DT_SINGLELINE);
return true;
}
BOOL CSnakeWnd:: Afoul()
{
deque <CPoint>::iterator pos;
for(pos=Snake.begin(),++pos;pos!=Snake.end();++pos)
{
CPoint Afoultemp=*pos;
if(temp==Afoultemp || temp.x < 0 || temp.x > 639 || temp.y < 99 || temp.y > 579 )
{
return true;
}
}
return false;
}
void CSnakeWnd::OnStart()
{
startgame();
}
void CSnakeWnd::SnakeQuit()
{
PostMessage(WM_QUIT);
}
void CSnakeWnd::SnakeMapON()
{
map_on=true;
OnPaint();
}
void CSnakeWnd::OnMapOff()
{
map_on=false;
OnPaint();
}
void CSnakeWnd::OnAbout()
{
MessageBox(_T("Snake by edgeperson @ 2007.10.15"));
}
void CSnakeWnd::OnPause()
{
if(timer)
{
this->KillTimer(1);
timer=false;
}
else
{
SetTimer(1,100,NULL);
timer=true;
}
}
void CSnakeWnd::OnSize(UINT nType, int cx, int cy)
{
if(nType==SIZE_MINIMIZED)
{
OnPause();
}
}
pDLMemDC.SelectStockObject(WHITE_BRUSH);
pDLMemDC.Rectangle(-1,99,641,581);
pDLMemDC.Rectangle(-1,-1,641,99);
pDLMemDC.DeleteDC();