VC++6.0
新建工程,这里新建的是单文档程序,然后一步步按照图示来,就能把工程建好了。这里注意的是一定要建立的是 单文档程序
新建 贪吃蛇类 ,CSnakeGame,这个类实现贪吃蛇的大部分功能,包含,初始化贪吃蛇,生成食物的位置,eat一个实物,向上下左右四个方向,next是下一步。代码如下// SnakeGame.h: interface for the CSnakeGame class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_SNAKEGAME_H__074FBCE0_CE02_48E4_978F_AF89899F85A5__INCLUDED_)#define AFX_SNAKEGAME_H__074FBCE0_CE02_48E4_978F_AF89899F85A5__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include
然后就是编写界面和实现响应函数了,界面部分就是注意添加一个菜单,按照图中的说明,添加好菜单项的属性ID等信息。在通过类向导添加每个菜单项的响应函数。如图所示。添加定时器相应函数,添加KeyUp和keydown响应函数
实现相应的响应函数代码,整个程序就基本完成了。下面是全部的实现代码SnakeView.cpp// SnakeView.cpp : implementation of the CSnakeView class//#include 'stdafx.h'#include 'Snake.h'#include 'SnakeDoc.h'#include 'SnakeView.h'#include 'SnakeGame.h'#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCSnakeGame snakeGame ;/////////////////////////////////////////////////////////////////////////////// CSnakeViewIMPLEMENT_DYNCREATE(CSnakeView, CView)BEGIN_MESSAGE_MAP(CSnakeView, CView) //{{AFX_MSG_MAP(CSnakeView) ON_COMMAND(ID_MENUITEM_START, OnMenuitemStart) ON_WM_TIMER() ON_WM_KEYUP() ON_WM_KEYDOWN() ON_COMMAND(ID_MENUITEM_STOP, OnMenuitemStop) ON_COMMAND(ID_MENUITEM_GOON, OnMenuitemGoon) //}}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/destructionCSnakeView::CSnakeView(){ // TODO: add construction code here my_start = false ; my_gameOver = false ; my_stop = false ; WhiteBrush.CreateSolidBrush(RGB(255,255,255)); BlackBrush.CreateSolidBrush(RGB(0,0,0)); GreenBrush.CreateSolidBrush(RGB(0,255,0)); RedBrush.CreateSolidBrush(RGB(255,0,0)); YellowBrush.CreateSolidBrush(RGB(255,255,0)); datas = new int[10][10] ;}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 drawingvoid CSnakeView::OnDraw(CDC* pDC){ CSnakeDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here if(my_start){ RECT rect ; GetClientRect(&rect) ; //pDC->FillRect(&rect,&GreenBrush) ; InitFace(pDC); } }/////////////////////////////////////////////////////////////////////////////// CSnakeView printingBOOL 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 _DEBUGvoid 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 handlersvoid CSnakeView::OnMenuitemStart() { // TODO: Add your command handler code here my_start = true ; my_gameOver = false ; snakeGame.InitGame() ; Invalidate(TRUE) ;}void CSnakeView::InitFace(CDC* pDC){ CDC *cdc = this->GetDC(); CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 CRect crect; this->GetClientRect(crect); MemDC.CreateCompatibleDC(NULL);//随后建立与屏幕显示兼容的内存显示设备 //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 MemBitmap.CreateCompatibleBitmap(cdc, main_rect.right-main_rect.left, main_rect.bottom-main_rect.top); //将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,颜色自选 MemDC.FillSolidRect(0,0, main_rect.right-main_rect.left, main_rect.bottom-main_rect.top,RGB(255,255,255)); //这里加入自己的画图代码,此时画图都是在内存中完成,操作对象是MemDC //然后将内存中的图拷贝到屏幕上进行显示 RECT rect ; CBrush* brush ; for(int i = 0 ; i < 10 ;i ++) { for(int j = 0 ; j < 10 ;j++){ rect.left = uWidth * j - 1; rect.top = uHeight * i - 1; rect.right = rect.left + uWidth -1 ; rect.bottom = rect.top + uHeight -1 ; if(datas[i][j] == 0 )brush = &BlackBrush ; else if(datas[i][j] == 1)brush = &GreenBrush ; else if(datas[i][j] == 2)brush = &RedBrush ; else if(datas[i][j] == 3)brush = &YellowBrush ; MemDC.FillRect(&rect,brush) ; } } cdc->BitBlt(0,0, crect.Width(), crect.Height(),&MemDC,0, 0,SRCCOPY); //绘图完成后清理临时对象 MemBitmap.DeleteObject(); MemDC.DeleteDC();}void CSnakeView::OnInitialUpdate() { CView::OnInitialUpdate(); GetClientRect(&main_rect) ; uWidth = (main_rect.right - main_rect.left) / 10; uHeight = (main_rect.bottom - main_rect.top) / 10; InitArr(datas,10,10) ; SetTimer(1,1000,NULL) ;}void CSnakeView::InitArr(int (*datas) [10],int x,int y){ for(int i = 0 ; i < x ; i++) { for(int j = 0 ; j < y ; j++){ datas[i][j] = 0 ; } }}void CSnakeView::GetPicMap(){ InitArr(datas,10,10) ; int len = snakeGame.arr.GetSize() ; for(int i = 0 ; i < len ; i++ ){ Point p = snakeGame.arr.GetAt(i) ; datas[p.x][p.y] = 1 ; } datas[snakeGame.head.x][snakeGame.head.y] = 2 ; datas[snakeGame.food.x][snakeGame.food.y] = 3 ;}void CSnakeView::drawOver(){ CDC* pcd = this->GetDC(); CString str = 'GAME OVER' ; CRect rect ; rect.left = main_rect.Width() / 2 - 100; rect.top = main_rect.Height() / 2 - 100; rect.right = main_rect.Width() / 2; rect.bottom = main_rect.Height() / 2; pcd->DrawText(str,rect, 0) ;}void CSnakeView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent == 1){ if(my_start && !my_gameOver && !my_stop){ my_gameOver = !snakeGame.Next() ; if(my_gameOver){ drawOver(); return ;} GetPicMap() ; Invalidate() ; } } CView::OnTimer(nIDEvent);}void CSnakeView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default switch(nChar){ case VK_UP: snakeGame.Up() ; break; case VK_LEFT: snakeGame.Left() ; break; case VK_RIGHT: snakeGame.Right() ; break; case VK_DOWN: snakeGame.Down() ; break; } CView::OnKeyUp(nChar, nRepCnt, nFlags);}void CSnakeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(my_gameOver){ drawOver(); return ;} // TODO: Add your message handler code here and/or call default if(my_gameOver){ drawOver(); return ;} switch(nChar){ case VK_UP: snakeGame.Up() ; break; case VK_LEFT: snakeGame.Left() ; break; case VK_RIGHT: snakeGame.Right() ; break; case VK_DOWN: snakeGame.Down() ; break; } my_gameOver = !snakeGame.Next() ; GetPicMap(); Invalidate() ; if(my_gameOver){ drawOver(); return ;} CView::OnKeyDown(nChar, nRepCnt, nFlags);}void CSnakeView::OnMenuitemStop() { // TODO: Add your command handler code here my_stop = true ;}void CSnakeView::OnMenuitemGoon() { // TODO: Add your command handler code here my_stop = false ;}
最后就是调试运行了,结果图如下
先调试后运行
VC6.0容易崩溃,崩溃了使用任务管理器,重启就好了