📄 snakeview.cpp
字号:
0, 0, SRCAND);
dcMem1.SelectObject(pOldBmp1);
// Step 5
// invert the bit mask
CBitmap bmpBW2;
bmpBW2.CreateBitmap(bmpInfo.bmWidth, bmpInfo.bmHeight,1,1,0);
pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpBW1);
pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpBW2);
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 6
// COPY with original then AND with mask
bmpSprite.GetBitmap(&bmpInfo);
pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpMask1);
pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpSprite);
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);
pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpBW2);
pOldBmp2 = (CBitmap *)dcMem2.SelectObject(&bmpMask1);
dcMem1.SetMapMode(MM_TEXT); dcMem2.SetMapMode(MM_TEXT);
dcMem2.BitBlt(0, 0,
bmpInfo.bmWidth, bmpInfo.bmHeight,
&dcMem1,
0, 0, SRCAND);
dcMem1.SelectObject(pOldBmp1);
dcMem2.SelectObject(pOldBmp2);
// Step 7
// BitBlt the sprite
bmpMask1.GetBitmap(&bmpInfo);
sizeBmp = CSize(bmpInfo.bmWidth, bmpInfo.bmHeight);
// pDC->DPtoLP(&sizeBmp);
// dcMem1.SetMapMode(MM_LOENGLISH);
pOldBmp1 = (CBitmap *)dcMem1.SelectObject(&bmpMask1);
pDC->BitBlt(ix, iy,
sizeBmp.cx, sizeBmp.cy,
&dcMem1, // MM_LOENGLISH mode
0, 0, SRCPAINT);
dcMem1.SelectObject(pOldBmp1);
}
// type IActionHandler::left=0 up=1 right=2 down=3
// leftOpen=10, upOpen=11, rightOpen=12, downOpen=13
void CSnakeView::drawHead(int type, int x, int y)
{
int xCoord=(x+1)*32;
int yCoord=(m_numCellsY-y+1)*32;
// TRACE("type=%d (x=%d,y=%d) pDC=%p\n", type,xCoord,yCoord, m_pDC);
if (m_pDC)
{
switch (type)
{
case IActionHandler::left:
drawSprite(m_pDC, IDB_HEADLEFTCLOSE, xCoord, yCoord);
break;
case IActionHandler::leftOpen:
drawSprite(m_pDC, IDB_HEADLEFTOPEN, xCoord, yCoord);
break;
case IActionHandler::up:
drawSprite(m_pDC, IDB_HEADUPCLOSE, xCoord, yCoord);
break;
case IActionHandler::upOpen:
drawSprite(m_pDC, IDB_HEADUPOPEN, xCoord, yCoord);
break;
case IActionHandler::right:
drawSprite(m_pDC, IDB_HEADRIGHTCLOSE, xCoord, yCoord);
break;
case IActionHandler::rightOpen:
drawSprite(m_pDC, IDB_HEADRIGHTOPEN, xCoord, yCoord);
break;
case IActionHandler::down:
drawSprite(m_pDC, IDB_HEADDOWNCLOSE, xCoord, yCoord);
break;
case IActionHandler::downOpen:
drawSprite(m_pDC, IDB_HEADDOWNOPEN, xCoord, yCoord);
break;
}
}
}
void CSnakeView::drawBody(int x, int y)
{
if (m_pDC)
drawSprite(m_pDC, IDB_BODY,
(x+1)*32, (m_numCellsY-y+1)*32);
}
// type: IGraphicOut::fruit=0 flower=1
void CSnakeView::drawFood(int type, int x, int y)
{
if (m_pDC)
switch (type)
{
case fruit:
drawSprite(m_pDC, IDB_FRUIT,
(x+1)*32, (m_numCellsY-y+1)*32);
break;
case flower:
drawSprite(m_pDC, IDB_FLOWER,
(x+1)*32, (m_numCellsY-y+1)*32);
break;
}
}
void CSnakeView::drawHorzWall(int x1, int x2, int y)
{
int x1Coord=(x1+1)*32;
int x2Coord=(x2+1)*32;
int yCoord=(m_numCellsY-y+1)*32;
CRect rect(x1Coord, yCoord, x2Coord+32, yCoord+32);
if (m_pDC)
{
CBitmap bmpBrick;
bmpBrick.LoadBitmap(IDB_BRICK);
CBrush brBrick;
brBrick.CreatePatternBrush(&bmpBrick);
CBrush *pBrOld = m_pDC->SelectObject(&brBrick);
m_pDC->PatBlt(rect.left, rect.top,
rect.Width(), rect.Height(),
PATCOPY);
m_pDC->SelectObject(pBrOld);
}
}
void CSnakeView::drawVertWall(int x, int y1, int y2)
{
int xCoord=(x+1)*32;
int y1Coord=(m_numCellsY-y1+1)*32;
int y2Coord=(m_numCellsY-y2+1)*32;
CRect rect(xCoord, y2Coord, xCoord+32, y1Coord+32);
if (m_pDC)
{
CBitmap bmpBrick;
bmpBrick.LoadBitmap(IDB_BRICK);
CBrush brBrick;
brBrick.CreatePatternBrush(&bmpBrick);
CBrush *pBrOld = m_pDC->SelectObject(&brBrick);
m_pDC->PatBlt(rect.left, rect.top,
rect.Width(), rect.Height(),
PATCOPY);
m_pDC->SelectObject(pBrOld);
}
}
void CSnakeView::drawScore(int score)
{
char scoreBuf[100];
if (m_pDC)
{
wsprintf(scoreBuf, "%d", score);
m_pDC->TextOut((int)((m_numCellsX-9)/2.0+2)*32+70, 16,
scoreBuf);
}
}
void CSnakeView::setDisplaySize(int width, int height)
{
m_numCellsX = width;
m_numCellsY = height;
((CMainFrame*)AfxGetMainWnd())->adjustDisplaySize(width, height);
}
void CSnakeView::SetActionHandler(IActionHandler *pHandler)
{
m_pActionHandler = pHandler;
}
void CSnakeView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
ASSERT(menu);
CMenu* menu1 = menu.GetSubMenu(0);
ASSERT(menu1);
menu1->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
point.x, point.y, AfxGetMainWnd());
}
int CSnakeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// if (m_timerID == 0)
// m_timerID = SetTimer(IDT_TIMER, 55, 0);
#define TARGET_RESOLUTION 1 // 1-millisecond target resolution
TIMECAPS tc;
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
{
// Error; application can't continue.
}
m_wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
// TRACE("wTimerRes=%d tc.wPeriodMin=%d tc.wPeriodMax=%d\n",
// m_wTimerRes, tc.wPeriodMin, tc.wPeriodMax);
timeBeginPeriod(m_wTimerRes);
m_timerID =
timeSetEvent(4, // delay (ms)
m_wTimerRes, // resolution (global variable)
myTimerCallback, // callback function
(DWORD)this, // user data
TIME_PERIODIC ); // single timer event
return 0;
}
void CALLBACK myTimerCallback(UINT wTimerID,
UINT msg,
DWORD dwUser,
DWORD dw1,
DWORD dw2)
{
CSnakeView *pView = (CSnakeView *) dwUser;
if ((UINT)pView->m_timerID == wTimerID)
{
if (pView->m_pActionHandler)
(pView->m_pActionHandler)->timeUp();
}
}
void CSnakeView::OnDestroy()
{
CView::OnDestroy();
if (m_timerID) // is timer event pending?
{
timeKillEvent(m_timerID); // cancel the event
timeEndPeriod(m_wTimerRes);
}
// if (m_timerID)
// KillTimer(m_timerID);
}
void CSnakeView::OnTimer(UINT nIDEvent)
{
// if (nIDEvent == (UINT)m_timerID)
// m_pActionHandler->timeUp();
CView::OnTimer(nIDEvent);
}
void CSnakeView::redraw()
{
Invalidate(FALSE); // do not clear screen
}
void CSnakeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
case VK_LEFT:
if (m_pActionHandler)
m_pActionHandler->leftMove();
break;
case VK_RIGHT:
if (m_pActionHandler)
m_pActionHandler->rightMove();
break;
case VK_UP:
if (m_pActionHandler)
m_pActionHandler->upMove();
break;
case VK_DOWN:
if (m_pActionHandler)
m_pActionHandler->downMove();
break;
case VK_ESCAPE:
close(); // window could be destroyed
return;
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSnakeView::close()
{
if (m_pActionHandler)
{
if (m_timerID)
{
timeKillEvent(m_timerID);
timeEndPeriod(m_wTimerRes);
m_timerID = 0;
}
m_pActionHandler->exit();
}
closeWindow();
}
void CSnakeView::closeWindow()
{
AfxGetMainWnd()->DestroyWindow();
}
void CSnakeView::scoreBoard(char *scoreMessages)
{
CScoreBoardDlg dlg;
CString messages(scoreMessages);
messages.Replace("\n", "\r\n");
dlg.m_scoreBoardMessages = messages;
dlg.DoModal();
}
void CSnakeView::OnChangeLevel()
{
CChangeSpeedDlg dlg;
dlg.m_speed = m_pActionHandler->getSpeed();
if (dlg.m_speed<0)
dlg.m_speed = 0;
else if (dlg.m_speed > 10)
dlg.m_speed = 10;
if (dlg.DoModal()==IDOK)
{
m_pActionHandler->changeSpeed(11-dlg.m_speed);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -