www.pudn.com > C++02.rar > 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_KEYDOWN() 
	ON_WM_TIMER() 
	ON_COMMAND(ID_GAME_START, OnGameStart) 
	//}}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() 
{ 
	IniGame();       
} 
 
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); 
	 
	CBitmap bitmap; 
	bitmap.LoadBitmap(IDB_BITMAP1); 
	CDC MemDC; 
	MemDC.CreateCompatibleDC(pDC); 
	CBitmap *pOldBitmap=MemDC.SelectObject(&bitmap); 
	BITMAP bm; 
	bitmap.GetBitmap(&bm); 
	pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&MemDC,0,0,SRCCOPY); 
	MemDC.SelectObject(pOldBitmap); 
	 
	// 画游戏区域 
   pDC->SelectStockObject(WHITE_BRUSH); 
   pDC->Rectangle(CRect(m_nLeft-1,m_nTop-1,m_nLeft+m_nWidth*m_nSize+1, 
	   m_nTop+m_nHeight*m_nSize+1)); 
    
    
    
   //显示当前用时 
   CString uStr; 
   uStr.Format("当前用时:%d",m_nTime); 
   pDC->TextOut(m_nLeft+m_nWidth*m_nSize+30,40,uStr); 
    
    
   //显示当前得分 
   uStr.Format("当前得分:%d",m_nCount); 
   pDC->TextOut(m_nLeft+m_nWidth*m_nSize+30,140,uStr); 
    
    
   //显示目标 
   pDC->SelectStockObject(LTGRAY_BRUSH); 
   pDC->Rectangle(CRect(m_nLeft+m_pAim.y*m_nSize,m_nTop+m_pAim.x*m_nSize, 
	   m_nLeft+(m_pAim.y+1)*m_nSize,m_nTop+(m_pAim.x+1)*m_nSize)); 
    
    
    
    
   //draw snake 
   for(int i=0;i<=m_aBody.GetUpperBound();i++) 
    {   
      CPoint uPoint=m_aBody.GetAt(i); 
      pDC->Rectangle(CRect(m_nLeft+uPoint.y*m_nSize,m_nTop+uPoint.x*m_nSize, 
		  m_nLeft+(uPoint.y+1)*m_nSize,m_nTop+(uPoint.x+1)*m_nSize)); 
     } 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// 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 
 
void CSnakeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	// 设置各方向的值 
	switch(nChar){ 
   case 38: 
	   if(m_nDirect!=3) 
         m_nDirect=4; 
       break; 
   case 40: 
	   if(m_nDirect!=4) 
         m_nDirect=3; 
       break; 
   case 37: 
	   if(m_nDirect!=1) 
         m_nDirect=2; 
       break; 
   case 39: 
	   if(m_nDirect!=2) 
         m_nDirect=1; 
       break;  
   } 
	CView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
void CSnakeView::OnTimer(UINT nIDEvent)  
{ 
	m_nTime1++;      //计时 
 
  if(m_nTime1==10)     //达到1秒 
  { 
   m_nTime++; 
   m_nTime1=0; 
   Invalidate(); 
  } 
   
   
  CPoint uPoint=m_aBody.GetAt(0);    //sanke head 
  int uTag=0; 
 
  switch(m_nDirect)       
  { 
  case 1:    //right 
        uPoint.y++; 
      if(uPoint.y>=m_nWidth) 
        uTag=1; 
      break; 
  case 2:   //left 
        uPoint.y--; 
      if(uPoint.y<0) 
        uTag=1; 
      break; 
  case 3:    //down 
	    uPoint.x++; 
      if(uPoint.x>=m_nHeight) 
        uTag=1; 
      break;  
  case 4:     //up 
        uPoint.x--; 
      if(uPoint.x<0) 
        uTag=1; 
      break; 
  } 
 
  if(uTag==0) 
  { 
    for(int i=0; i<=m_aBody.GetUpperBound();i++) 
    { 
      CPoint uPoint1=m_aBody.GetAt(i); 
      if(uPoint1.x==uPoint.x&& uPoint1.y==uPoint.y) 
      { 
       uTag=1; 
       break; 
      } 
    } 
  } 
 
if(uTag==0)                   
{ 
  m_aBody.InsertAt(0,uPoint); 
  ReDisplay(uPoint); 
  if(uPoint.x==m_pAim.x&&uPoint.y==m_pAim.y) 
  { 
    m_nCount++; 
    IniAim(); 
    Invalidate(); 
   } 
   else 
  { 
     CPoint uPoint1=m_aBody.GetAt(m_aBody.GetUpperBound()); 
     m_aBody.RemoveAt(m_aBody.GetUpperBound()); 
     ReDisplay(uPoint1); 
  } 
} 
 
 
 
else      //Game Over 
  { 
    KillTimer(1); 
    AfxMessageBox("Fail!"); 
  } 
	 
	CView::OnTimer(nIDEvent); 
} 
 
 
 
 
 
 
void CSnakeView::OnGameStart()  
{ 
    IniGame(); 
    m_nGameStatus=1; 
    SetTimer(1,100,NULL);    //启动定时器 
    Invalidate();	 
} 
 
 
//该随机函数产生一个供蛇吃的目标,如与蛇身重合,则重新产生一个  
void CSnakeView::IniAim() 
   { 
      int uX,uY;    //目标位置 
      while(1) 
      { 
 
          uX=rand()%m_nHeight; 
          uY=rand()%m_nWidth; 
          int uTag=0;            //0:不与蛇身重合;1:重合 
      
          for(int i=0;i<=m_aBody.GetUpperBound();i++) 
          {   
              CPoint uPoint=m_aBody.GetAt(i); 
              if(uPoint.x==uX||uPoint.y==uY)    //重合 
              { 
                 uTag=1; 
                 break; 
              } 
          } 
          if(uTag==0) 
            break; 
       } 
       m_pAim=CPoint(uX,uY);     //目标保存于成员变量中 
    } 
     
 
 
//初始化游戏 
void CSnakeView::IniGame()  //这个类中的方法 
    {  
 
        //initialize game area 
	    m_nLeft=20; 
        m_nTop=20; 
        m_nWidth=40; 
        m_nHeight=30; 
        m_nSize=10; 
 
		//initialize game status 
        m_nGameStatus=0; 
        m_nDirect=1; 
        m_nCount=0; 
 
        //initialize snake body 
		m_aBody.RemoveAll(); 
        m_aBody.Add(CPoint(2,7)); 
        m_aBody.Add(CPoint(2,6)); 
        m_aBody.Add(CPoint(2,5)); 
        m_aBody.Add(CPoint(2,4)); 
 
        //clean timer 
		m_nTime=0; 
        m_nTime1=0; 
 
        srand((unsigned)time(NULL));   //初始化随机数发生器 
 
        IniAim();    //产生一个目标 
     } 
 
 
 
 
//刷新游戏区域中pPoint处的一个小方格 
void CSnakeView::ReDisplay(CPoint pPoint) 
     { 
        InvalidateRect(CRect(m_nLeft+pPoint.y*m_nSize,m_nTop+pPoint.x*m_nSize, 
                       m_nLeft+(pPoint.y+1)*m_nSize,m_nTop+(pPoint.x+1)*m_nSize)); 
     }