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

📄 snakeview.cpp

📁 C语言的贪吃蛇代码 绝对正确无误 保证TC2.0平台上正常运行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SnakeView.cpp : implementation of the CSnakeView class
//

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

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

#include "ScoreBoardDlg.h"
#include "ChangeSpeedDlg.h"

#include <mmsystem.h>

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

#define IDT_TIMER 1000
/////////////////////////////////////////////////////////////////////////////
// CSnakeView

IMPLEMENT_DYNCREATE(CSnakeView, CView)

BEGIN_MESSAGE_MAP(CSnakeView, CView)
    //{{AFX_MSG_MAP(CSnakeView)
    ON_WM_SIZE()
    ON_WM_PAINT()
	ON_WM_CONTEXTMENU()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_WM_CLOSE()
	ON_COMMAND(IDM_CHANGELEVEL, OnChangeLevel)
	//}}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()
    : m_pDCMemDB(0),
      m_pBmpDB(0),
      m_pActionHandler(0),
      m_numCellsX(10),
      m_numCellsY(10),
      m_timerID(0)
{
}

CSnakeView::~CSnakeView()
{
    if (m_pDCMemDB)
        delete m_pDCMemDB;
    if (m_pBmpDB)
        delete m_pBmpDB;
    if (m_pActionHandler)
        delete m_pActionHandler;
}

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);

    m_pDC = pDC;

    CRect rect;
    GetClientRect(&rect);

//  draw boundary

    CBitmap bmpBrick;
    bmpBrick.LoadBitmap(IDB_BRICK);
    CBrush brBrick;
    brBrick.CreatePatternBrush(&bmpBrick);
    CBrush *pBrOld = pDC->SelectObject(&brBrick);
    pDC->PatBlt(rect.left, rect.top,
                rect.Width(), rect.Height(),
                PATCOPY);
    pDC->SelectObject(pBrOld);

//  draw interior field

    CBitmap bmpCell;
    bmpCell.LoadBitmap(IDB_CELL);
    CBrush brCell;
    brCell.CreatePatternBrush(&bmpCell);
    pBrOld = pDC->SelectObject(&brCell);
    pDC->PatBlt(rect.left+32, rect.top+32+32,
                rect.Width()-64, rect.Height()-64-32,
                PATCOPY);
    pDC->SelectObject(pBrOld);

//  draw scoreboard

    drawSprite(pDC, IDB_SCOREBOARD, 
               (int)((m_numCellsX-9)/2.0+1)*32, 5);

    pDC->SetBkMode(TRANSPARENT);
    pDC->TextOut((int)((m_numCellsX-9)/2.0+2)*32, 16, 
                 "Scores:");

//  draw all game components

    if (m_pActionHandler)
        m_pActionHandler->draw();

    m_pDC = 0;
}

/////////////////////////////////////////////////////////////////////////////
// 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::OnInitialUpdate() 
{
    CView::OnInitialUpdate();
    
    CClientDC dcClient(this);
    OnPrepareDC(&dcClient);

    m_pDCMemDB = new CDC;
    m_pDCMemDB->CreateCompatibleDC(&dcClient);
    m_pDCMemDB->SetMapMode(dcClient.GetMapMode());
}

void CSnakeView::OnSize(UINT nType, int cx, int cy) 
{
    CView::OnSize(nType, cx, cy);
    
    CRect rect;
    GetClientRect(&rect); // device coordinates
                          // API without DC as arguments, 
                          // always use device coordinates

    if ((rect.right <= m_sizeDB.cx) &&
        (rect.bottom <= m_sizeDB.cy)) return;

    if (rect.right > m_sizeDB.cx)
        m_sizeDB.cx = rect.right;

    if (rect.bottom > m_sizeDB.cy)
        m_sizeDB.cy = rect.bottom;

    CClientDC dcClient(this);
    OnPrepareDC(&dcClient); // order dependency: after adjustScrollSizes()

    if (m_pBmpDB) delete m_pBmpDB;
    m_pBmpDB = new CBitmap;
    m_pBmpDB->CreateCompatibleBitmap(&dcClient, m_sizeDB.cx, m_sizeDB.cy);
}

void CSnakeView::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    OnPrepareDC(&dc);

    CBitmap *pBmpOld = m_pDCMemDB->SelectObject(m_pBmpDB);

    CRect rectInvalid;
    dc.GetClipBox(&rectInvalid); // logical coordinate

    m_pDCMemDB->SelectClipRgn(NULL);
    m_pDCMemDB->IntersectClipRect(&rectInvalid);

/*
    CBrush brBackground((COLORREF)::GetSysColor(COLOR_WINDOW));
    CBrush *pBrOld = m_pDCMemDB->SelectObject(&brBackground);
    m_pDCMemDB->PatBlt(rectInvalid.left, rectInvalid.top,
                       rectInvalid.Width(), rectInvalid.Height(),
                       PATCOPY);
    m_pDCMemDB->SelectObject(pBrOld);
*/

    OnDraw(m_pDCMemDB);

    dc.BitBlt(rectInvalid.left, rectInvalid.top,
              rectInvalid.Width(), rectInvalid.Height(),
              m_pDCMemDB, // MM_TEXT mode
              rectInvalid.left, rectInvalid.top,
              SRCCOPY);

    m_pDCMemDB->SelectObject(pBmpOld);
}

void CSnakeView::drawSprite(CDC *pDC, int resID, 
                            int ix, int iy)
{
    BITMAP bmpInfo;
    CSize  sizeBmp;
    CDC dcMem1, dcMem2;

    dcMem1.CreateCompatibleDC(pDC);
    dcMem2.CreateCompatibleDC(pDC);

    //  Step 1
//  create mask step 1: XOR the specified color

    CBitmap bmpSprite;
    bmpSprite.LoadBitmap(resID);
    bmpSprite.GetBitmap(&bmpInfo);
    sizeBmp = CSize(bmpInfo.bmWidth, bmpInfo.bmHeight);

    CBitmap bmpMask1;
    bmpMask1.CreateCompatibleBitmap(pDC, bmpInfo.bmWidth, bmpInfo.bmHeight);

    CBitmap *pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpMask1);

    CPen *pPen = (CPen *) dcMem1.SelectStockObject(NULL_PEN);
    CBrush br(RGB(131,0,0));
    CBrush *pBr = (CBrush *)dcMem1.SelectObject(&br);
    dcMem1.Rectangle(0,0,bmpInfo.bmWidth+1, bmpInfo.bmHeight+1);
    dcMem1.SelectObject(pBr);
    dcMem1.SelectObject(pPen);

    CBitmap *pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpSprite);

// transparent color will now be black

    dcMem1.SetMapMode(MM_TEXT); dcMem2.SetMapMode(MM_TEXT);
    dcMem1.BitBlt(0, 0,
                  bmpInfo.bmWidth, bmpInfo.bmHeight,
                  &dcMem2,
                  0, 0, SRCINVERT);
    dcMem1.SelectObject(pOldBmp1);
    dcMem2.SelectObject(pOldBmp2);

//  Step 2
//  create mask step 2: make transparent color region white

    CBitmap bmpMask2;
    bmpMask2.CreateCompatibleBitmap(pDC, bmpInfo.bmWidth, bmpInfo.bmHeight);
    pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpMask2);

    pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpMask1);
    dcMem1.SetMapMode(MM_TEXT); dcMem2.SetMapMode(MM_TEXT);
    dcMem2.BitBlt(0, 0,
                  bmpInfo.bmWidth, bmpInfo.bmHeight,
                  &dcMem1,
                  0, 0, NOTSRCCOPY);
    dcMem1.SelectObject(pOldBmp1);
    dcMem2.SelectObject(pOldBmp2);

//  Step 3
//  create mask step 3: copy to Black-white bitmap so that
//                      nontransparent color region is black

    CBitmap bmpBW1;
    bmpBW1.CreateBitmap(bmpInfo.bmWidth, bmpInfo.bmHeight,1,1,0);
    pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpBW1);
    pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpMask2);
    dcMem1.SetMapMode(MM_TEXT); dcMem2.SetMapMode(MM_TEXT);
    dcMem1.BitBlt(0, 0,
                  bmpInfo.bmWidth, bmpInfo.bmHeight,
                  &dcMem2,
                  0, 0, SRCCOPY);
    dcMem1.SelectObject(pOldBmp1);
    dcMem2.SelectObject(pOldBmp2);

/*
// view the mask
    dcMemMaskBW.SetMapMode(MM_LOENGLISH);
    pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpBW1);
    pDC->BitBlt(m_ptMouse.x-sizeBmp.cx/2, m_ptMouse.y-sizeBmp.cy/2, 
                sizeBmp.cx, sizeBmp.cy, 
                &dcMem1, // MM_LOENGLISH mode
                0, 0, SRCCOPY);
    dcMem1.SelectObject(pOldBmp1);
*/

//  Step 4
//  cut off the sprite from the background

    bmpBW1.GetBitmap(&bmpInfo);
    sizeBmp = CSize(bmpInfo.bmWidth, bmpInfo.bmHeight);

    // both DC must be in the same mapping mode
//    dcMem1.SetMapMode(MM_LOENGLISH);
    pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpBW1);
    pDC->BitBlt(ix, iy, 
                sizeBmp.cx, sizeBmp.cy, 
                &dcMem1, // MM_LOENGLISH mode

⌨️ 快捷键说明

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