还剩44页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
手把手教“MFC版贪吃蛇教程”本次贪吃蛇教程主要学问点包括以下几个方11写在前面的话类中的消息响应1CView控件的消息响应2基于类内的具体嬉戏实现3CView数组4嬉戏图形的实现用类实现5CDC本版嬉戏的具体实现是在类中实现,所以其他类不用添加任何代码CViewlSNAKE dastesMe■ss二age MapsMember VariablesAutomation ActiveXEvents Class Info♦CAboulDIg AddFunction...••*CMainFrame ProjectClass name•••CSNAKFApp AddClass...▼;♦CSNAKEDoc▼CSNAKEView•CSNAKE VIcwOSbNjeAcKtEJDs MessagesDelete FunctionAsserlValidyIDM_PAUSE CancelID^FILECSSNAAKVEEVieIwDO fxIDMSTARTD:\MFC\SNAKE\SN EditCode♦TSNAKEVIewflNEXT PANEID MessageCOMMANDPMReEmVb♦ePrD Aufm uNpnEf cCtD iIuoDm nMpsC onhON WM KEYDOWN♦GefDocumcntO MObemjecbteIrDfuncIDtioMn-EnXaImTeCONTINUEOK■OnBeginPrintkngfCI♦ON IDMPAUSE COMMANDOnContinucO♦OnDrawfCDC,ON WM RBUTTONDOWN*pDCJ,OnEndPrinting{CD AKEView.h,D:\MFC\SNAKE\SNAKEView.cppOntxitO♦OnlnitialUpdatcQ IDMEXIT、OnKeyDownfUINT iOnlnitialUpdate OnKeyDownOnPause OnPreparePrintingOnRButtonDown海OnPauscO的OnPrcparePrintinglDescription Handle a command from menu,accel,cmd button、OnRRu1lonDownU XOnSUrtOWOnTimerUINT nIDE♦确定取消消息的分类有种,标准消息,吩咐消息,通告消息标准消息除PS Windows31COMMAND之外,所以开头都是标准消息吩咐消息就是WM_2COMMAND通告消息由控件产生的消息,这类信息也能以类型3WM_COMMAND出现最终我们回到原来的去看看我们一共添加的函数ClassViewvoid CSNAKEUiew::OnTireerUlNl nlDEvent//IODO:Add yourmessage handler code here and/or calldefaultCUiew::OnHiwrnlDtuent;void CSNAKEUiew::0nKeyDownUlN1nUhar.U1NI nRepCnt.U1NT nf-lags〃IODO:Add yourmessage handlercode here and/or calldefaultCUiew:;OnKeyDownnChdr nRepCnt•nF]ags|;evoid CSHHKEUiew::0nR6uttonDownUINT nFLig*CPoint pointr//TODO:Add yourhandlercod here and/or calldefaultCUiew::0nR8utton0o*nnF laqq,point;void CSNAKEUiew::0nlnitilUpd4trCUirw:OnlnitidlUpd«te;//TODO:Add yourspecialized codehrrt*and/or callthe g*cl4ssvoid CSNAKEUiew::OnSt^rt〃TODO:Add yourcofifMand handlercode hereOnContinurQuoid CSNAKEUiew:OnP«iuse♦OnDrawCDC*pDCOnEndPrintingfCDC//IODO:Add yourconnand handlercode here“OnExitQ♦OnlnitialUpdateO中%OnKeyOownUINT iuoid CSNAKEUiew::OnExit♦OnPauseQ、OnPrcparePrintingl//TODO:Add yourconnand handlercodhere、“OnRButtonDuwnfUlOnStadO“OnTimerUINT nIDEuoidCSNAKEUiPw::OnContinup♦PreCrcatcWindow^♦_|Globals//TODO:Add yourconnand handlercode here臼号SNAKE classes国F CAboutDIg+卜F CMainFrame@F CSNAKEAppI4*i CSNAKEDocIQ^CSNAKEViewl I,AssertValidQ CSNAKE ViewOI CSNAKEView:♦DumpCDumpContext•GetDocumentQ…辛,|-%OnBeginPrintingfCDC*OnContinueQ;三■OnDrawCDC*pDC;为OnEndPrintingCDC*p[g…%OnExitfl•oninitQ©OnlnitialllpdateQ;OnKeyDownUINT nChshOnPauseQ$♦OnPreparePrintingCPri.
1.OnRButtonDownUINT ik9^OnStartQ二为OnTimerUINT nIDEven@Pre Cre ateWi nd owC RE.由F Food+1Snake v|匚一一疝c1!1药■:Clastil ResFile\VA^VA全部的函数集合全部有以下L在此处我们可以看到我们添加的消息全部的消息响应函数的声明Windows///////////////////////////////////////////////////////////////////////////////CSNAKEUiewIMPLEMENT_DVNCREATECSNAKEUiew,CUiewBEGIN_MESSAGE__MAPCSNAKEUiew,CUiew/7{AFX_MSG MAPCSNAKEUiew--T ONWM TMER#C ONJKEVDOWN#C ONJRBUTTONDOWNONZCOMMANDIDMJTfiRT,OnStartONZCOMMANDlDn±AUSEOnPauseT TILTDM XONZCOMMANDOnExitUN—COMMANDf■OnContinue」苒//}}AF X__MS GF-//Standard printingcommandsON_COMMANDID_FILE_PRINT,CUiew::OnFilePrintONZcOMMfiNDID^FILE^PRINT_DIRECT,CUiew::OnFilePrintONZCOMMANDID^FILERINT^PREUIEW,CUiew::OnFilePrintPreuiew一一END_MESSAGE_MAP/////////////////////////////////////////////////////lllll其次部分具体实现嬉戏、Step1首先我们在文件开头处分别定义蛇和食物的全局变量struct Snakeint x,y;int len;int direct;}Snake
[50];struct Food{int x;int y;int isfood;}Food;白翎公SNAKE classes//SNAKEUiew.cpp:inplenentation ofthe CSHAKEUie^class4广・CAboutDIg♦CMainFrameSnake空F CSNAKEApp值二》士|J—ZZZ1F CSNAKEDoc^E CSNAKEViewl善画画词•封噜同■i34♦AssertValidQllinclude stdafK.h0:\CSNAKEViewO•include-SHAKE.h,a•include♦TSNAKEViewQ SHAKEDoc.hla llinclude-SHAKEUiew.h-♦DumpCDumpContext i♦GetDocumentO HiFdeFDEBUGOnBeginPrintingCDC*•define newDEBUG NEW一,::OnContinueQ HundeFTHIS-FILE,static charTHIS„FILE[]=_FILE_;ttendiF“♦OnDrawCDC wpDC%OnEndPrintingCDC*p£struct Snake{OnExitOint xy;9j♦oninitQint len;int direct;0OnlnitialUpdateQSnake
[50];OnKeyDownfUINT nCh2%OnPauseQstruct Foodint x;int y;int isFood;%OnPreparePrintingfCPri}Food;OnRButtonDownUINT i%OnStartQ;■OnTimerfUINT nIDEven♦Pre Create WindowC RE.IHJJ♦F Food再者void CSNAKEView::OnInitialUpdateCView::OnlnitialUpdateO;Snake
[0].x=10;Snake
[0].y=10;Snake[l].x=l1;Snake[l].y=10;Snake
[2].x=12;Snake
[2].y=10;Snake[O].direct=3;Snake
[0].len=3;Food.isfood=l;//TODO:Add yourspecialized code hereand/or callthe baseclass}uoid CSNAKEUieu::OnInitialUpdate CUievi::OnInitialUpdate;Snake
[0].x=10;Snake
[0].y=18;Snake
[1].x=11;Snake
[1].y=18;Snake
[2].x-12;Snake
[2].y=18;Snake
[0].direct=3;Snake
[0].len=3;Food.isFood=1;//TODO:Add yourspecialized code hereand/or c代码说明初始化贪吃蛇起初有个节点,长度为起始坐标;33,食物默认为无有当然我更加喜爱无有汾11对具体添加代码Step2OnKeyDownvoidCSNAKEView::OnKeyDownUINT nChar,UINT nRepCnt,UINT nFlags//TODO:Add yourmessage handlercode hereand/or calldefaultswitchnChar|case VK_UP:ifSnake
[0].direct!=2Snake
[0].direct=1;break;case VK_DOWN:ifSnake
[0].direct!=lSnake
[0].direct=2;break;case VK_LEFT:ifSnake[O].direct!=4Snake[O].direct=3;break;case VK_RIGHT:ifSnake
[0].direct!=3Snake
[0].direct=4;break;}CView::OnKeyDownnChar nRepCnt,nFlags;,CView::OnKeyDownnChar,nRepCnt,nFlags;void CSMAKEUiew::OnKeyDowiiUINT iiChai.UINT hRrpCnt«MINTnFldqs//TODO:Add yourvie55dgehandler codehereand/or CdlldeFaultswitchnCh^r{当蛇次的归的匕匕技“右当的侯向候case UKUP:iFSiidlce
[0].dirt*1f-2Snjke0].di recI1bredlc;ejseUK_DOWI:iFSndle[t].di iI*I if v1Snjke0].direct-2;tire^l;ease松头的时此胃匕长二左”二的候不时UK_LErT:lFSfidle[t].f*^Snake0].direct-3;breiilc;C«se UK当警於思畲胃匕匕地,篦斗的当蛇头的射力校后下的舌馍下RIGHT:iFS«idke[d].illl ettf-3Sndke0].direct U;bredlc;CUiew::OnKe9DiMi5i€iidi nRepCnlvw,;CUiew6nKeyDoMinChjr nHepCnleFl-g vv函数的第一个参数是接收用户键入的信息,然后我们OnKeyDown UINTnChar用进行选择推断switch代码说明WCLr•S代表的是蛇头,我们对蛇头的方向进行推断Snake
[0]Snake
[0].directcase VK_UP:ifSnake
[0].direct!=2Snake
[0].direct=1;break;意思就是当的方向此时并不等于“下”的时候,才能做出“上”Snake
[0].direct的操作动作,否则则忽视用户“向上”的操作按键效果具体添加代码Step3OnRButtonDown void CSNAKEView::OnRButtonDownUINT nFlags,CPoint point{//TODO:Add yourmessage handlercode hereand/or calldefault//TODO:Add yourmessage handlercode hereand/or calldefaultCStringstr;str.Format%d,%d,point.x,point.y;AfxMessageBoxstr;CView::OnRButtonDownnFlags,point;CView::OnRButtonDownnFlags,point;CView::OnRButtonDownfnFlags,point;}这个函数功能是用鼠标右键屏幕,就会立刻显示当前位置的坐标信息其实这个函数并不是本嬉戏中必要添加的函数,只是为了在后面嬉戏页面的设计的时候可以用鼠标右键屏幕了解也许的屏幕坐标信息,才特地做的这里补充一个学问点坐标系有种WIN323世界坐标系1页面坐标系2设备坐标系3世界坐标系与页面坐标系称谓“逻辑空间”,事实上就等同于我们现实生活中的数学坐标系一样设备坐标系则不然,电脑屏幕就是一个用设备坐标系的,特征为以用户区窗口左上角为原点,坐标向右为正,坐标向下为正0,0X Y由于此次贪吃蛇须要的开发环境,所以打开新建一个MFC VisualC++文件工程|工作区|其它文档|工程名称^ATL COMAppWizard M刁Cluster ResourceType WizardSNAKE困Custom AppWizard^DatabaseProject位置慢IQDevStudio Add-in Wizard%.D:\MFC\SNAKEExtended StoredProc Wizard单文档工程,随意取名一个工程名称MFC AppWizard4RISAR ExtensionWizard嚏Makefile涯MFC ActiveXControlwizard窗创建新的工作空间回MFC AppWizarddll G二MFC AppWizardfexe添加到当前工作空间CI/rj\New DatabaseWizardJr*i-M-t rayIUtility Project从属于必r国Win32Application22]Win32Console ApplicationWin32Dynamic-Link Library酎Win32Static Library平台旧:Win32确定取消Step4void CSNAKEView::oninitCDC*pDC=GetDC;CBrush DrawBrush=RGB100,100,100;CBrush*Drawbrush=pDC-SelectObjectDrawBrush;forfint i=0;i=snake
[0].1-1;i++pDC-Rectanglesnake[i].x*20,snake[i].y*20,snake[i].x+1*20,snake[i].y+1*20;pDC-SelectObjectDrawBrush;}uoid CSNAKEUiew::oninit;CDC«pDC-GetDCCBrush DrawBrushsRGB100,100,100;CBrush»Drawbrush«pDC-SelectOb ject6!rawBrush;forint i=0;i=Snake
[0].len-1;i+*pDC-RectangleSnake[i].x«20Snake[i].9»20Snake[i].x*1*20,Snake[i].y*1*2099pDC-SelectObjectDravBrush;代码说明:利用给我们供应的类来进行画图,我们首先用一个指向类的指针去Windows CDCCDC接受与该窗口相关联的句柄,然后用定义画刷一个对象,并且用DC DrawBrush来给画刷初始化颜色并且用函数把对象画刷RGB100,100,100SelectObjectDrawBrush;选入到设备描述表中,用循环依次把贪吃蛇的个节点画出来for3void farrectanglefint left,int top,int right,int bottom;这个函数的的功能依据函数功能:该函数画一个矩形,用当前的画笔画矩形轮廓,用当前画刷进行填充.控件添加代码Step5void CSNAKEView::OnStart//TODO:Add yourcommand handlercode hereSetTimer1,3000,NULL;秒后起先嬉戏!;AfxMessageBox3void CSNAKEView::OnPause//TODO:Add yourcommand handlercode hereKillTimerl;暂停嬉戏;AfxMessageBoxvoid CSNAKEView::OnExit//TODO:Add yourcommand handlercode here退出嬉戏...;AfxMessageBoxexit0;}void CSNAKEView::OnContinue//TODO:Add yourcommand handlercode hereSetTimerf1,10,NULL;uoid CSNAKEUiew::0nStart//TODO:Add yourcommand handlercode hereSetTimer13OO0NULL;99「秒后开始游戏广;AfxMes$ageBox3uoid CSNAKEUievi::0nPause//TODO:Add yourcommand handlercode hereKillTimerl;,游戏暂停;—essageBox••■”uoid CSNAKEUiew::OnExit,游戏结束...;//TODO:Add yourcommand handlercode hereAfxMessageBox exit0;uoid CSNAKEUiev/::OnContinue//TODO:Add yourcommand handlercode hereSetliner1,10NULL;9代码说明由于之前我们设定了消息,我们能运用计时器功能WM.TIMER用来设置定时器WM_TIMER先请看这个函数的原型SetTimer APIUINT_PTR SetTimer窗口句柄HWND hWnd,//定时器多个定时器时,可以通过该UINT.PTR nIDEvent,//ID,推断是哪个定时器ID时间间隔,单位为毫秒UINT uElapse,//回调函数TIMERPROC IpTimerFunc//);」,//一个秒触发一次的定时器SetTimerm_hWnd1000,NULL;1在程序中被封装在类中,调用就不用指定窗口句柄了所以我们这里可MFC SetTimerCWnd以只去后个参数写成3SetTimer,10,NULL;为秒10001关于的探讨在本博客中有写有,这里就不在赘述afxMessageBox对的添加代码Step6OnDraw函数众所周知视图类中的输出.视图类的输出基本上都是在视图类的函数中处理OnDrawOnDraw的,系统会打算好入参,然后调用函数本人也没有过多的去探讨过次函数,仅知道一些皮毛OnDraw不过这里有个学问点那便是与的区分,派生于类,响应OnPaint OnDraw OnPaintCWnd消息是类的成员函数,并且没有消息响应功能,这就是为什么视图WM_PAINT OnDrawCView类没有只有而没有OnDrawOnPaint的缘由维护视图客户区例如通过试表在视图中画图,而维护窗口的客OnDrawO OnPaint户区voidCSNAKEView::OnDrawCDC*pDCCSNAKEDoc*pDoc=GetDocumentQ;ASSERT_VALIDpDoc;//TODO:add drawcode fornative datahereCBrush backBrushRGB100,100,0;CBrush*pOldBrush=pDC-SelectObjectbackBrush;CRect rect;pDC-GetClipBoxrect;pDC-PatBltrect.left,rect.top,rect.Width,rect.Height PATCOPY;,pDC-SelectObjectpOldBrush;pDC-Rectangle19,19,501,501;oninit;代码说明:此处是用画刷画一个背景,并且画出个矩形区域3函数原型int GetClipBoxHDChdc,LPRECT Iprc;该函数得到一个能够完包含当前可见区域的最小矩形的大小函数原型int nYLeft,int nWidth,int nHeight,DWORD dwRop;该函数运用当前选入指定设备环境中的刷子绘制给定的矩形区域对的添加代不Step7OnTimeO voidCSNAKEView::OnTimerUINT nIDEvent//TODO:Add yourmessage handlercodehereand/or calldefaultCDC*pDC=GetDC;CString soure;if Snake
[0].len==2SetTimer1,370,NULL;if Snake
[0].len==3SetTimer1,270,NULL;ifSnake
[0].len==6SetTimerl,200,NULL;ifSnake
[0].len==9SetTimer1,100,NULL;得分:%soure.Format1!”,Snake
[0].len-3*10;〃撞界推断ifSnake
[0].x*20=371|Snake
[0].y*20=371|Snake
[0].x*20=462||Snake
[0].y*20=462KillTimerl;AfxMessageBoxsoure;//s=0;〃蛇身相撞推断if Snake
[0].len3forfint sn=Snake
[0].len-1;sn0;sn—if Snake
[0].x*20==Snake[sn].x*20Snake
[0].y*20==Snake[sn].y*20KUlTimerl;AfxMessageBoxsoure;//s=0;///////////////////////////////////////////////////////////////////////////pDC-SelectStockObjectWHITE_PEN;pDC-RectangleSnake[Snake[O]Jen-1].x*20,Snake[Snake
[0].len-1].y*20,Snake[Snake[O].len-l].x+l*20,Snake[Snake
[0].len-l].y+1*20;forfint i=Snake
[0].len-1;i0;i—Snake[i].x=Snake[i-1].x;Snake[i].y=Snake[i-1].y;〃行走方向推断ifSnake
[0].direct==lSnake
[0].y—;ifSnake
[0].direct==2Snake
[0].y++;if SnakefO].direct==3Snake
[0].x-;ifSnake
[0].direct==4Snake
[0].x++;pDC-SelectStockObjectBLACK_PEN;CBrush DrawBrush=RGB100,100,100;CBrush*Drawbrush=pDC-SelectObjectDrawBrush;pDC-RectangleSnake
[0].x*20,Snake
[0].y*20,Snake
[0].x+1*20,Snake
[0].y+1*20;pDC-SelectObjectDrawBrush;〃推断吃豆的条件,撞到就吃ifSnake
[0].x*20==Food.x*20Snake
[0].y*20==Food.y*20Snake
[0].len++;Fooddsfood=l;Snake[Snake
[0].len-1].x=Snake[Snake
[0].len-2].x;Snake[Snake
[0].len-1].y=Snake[Snake
[0].len-2].y;〃假如食物被吃了就生成ifFood.isfood==1srandunsignedtimeNULL;do forfintisfo=Snake
[0].len-1;isfo=0;isfo ifSnake
[0].x*20==Snake[isfo].x*20Snake
[0].y*20==Snake[isfo].y*20本次贪吃蛇基本流程与大体思想定义蛇类和食物类,初始化贪吃蛇各项成员变量,包括图像的出现在屏幕的初始位置,长度,以与蛇1的行走方向食物类的定义包括出现的初始位置,以与食物是否被吃掉的推断Food.x=rand%;Food.y=rand%;}whileFood.x*2070||Food,y*2070||Food.x*20430||Food.y*20430;;pDC-RectangleFood.x*20,Food.y*20,Food.x+l*20Food.y+1*20,Food.isfood=0;CView::OnTimernIDEvent;uoidCSNAKEUiew::OnTimerUIHT nIDEuent//TODO:Add yourmessage handlercodehereand/or calldefault CDC*pDC»GetDC;CString soure;・・加速“iaSgke[G]/en2SetTi.eX1,370,NULL;/“ifSnake
[0].len»-3SetTiner1,270,NULL;iFSnake
[0].len==6SetTiRer1200NULL;f fifSnake
[0].len=«9SetTiner1,100,NULL;,•你得到了soure.Format:%df,Snake
[0].len-3»10;〃撞界判断ifSnake
[0].x«2O»37||Snake
[0].y*20»37||Snake
[0].x«20»462||Snake
[0].y«20«462KillTinerl;AFxHessageBoxsoure;〃蛇身相撞判断iFSnake
[0].len3forint5nSnake
[0].len-1;sn0;sn--ifSnake
[0].x*2Ba=-Snake[sn].x«206Snake
[0].y»2fl-»Snake[sn].y*20KillTimerl;AFxMessageBoxsoure;///////////////////////////////////////////////////////////////////////////pDC-SelectStockObjectWHI TERPEN;pDC-RectangleSnake[Snake
[8].len-1].x*20,Snake[Snake
[8].len-1].y*20,Snake[Snake
[0].len-1].x*1Snake[Snake
[0].len-1].y*1»20;pDC-SelectStockObjectWHI TERPEN;pDC-RectangleSnakeSnake
[0].len-1].x*20SnakeSnake
[0].len-1]•i*20t wSnake[Snake
[0].len-1].x*1»20,Snake[Snake
[0].len-1].y*1»20;Forint i=Snale
[0].len-1;i0;i-Snake[i].x=Snake[i-1].x;Snake[i].y»Snake[i-1|.y;}〃行走方向判断if Snake
[0].direct-1Snake
[0].y-;If Snake
[9].directu2Snake
[0]・y♦+;iFSnake
[0].direct-3Snake
[0].x—;ifSnake
[0].direct==4Snake
[0].x**;pDC-SelectStockObjectBLACK PEN;CBrush DrawBrush«RGB1O01O0100;t tCBrush»DraiArush=pDC^Select0bject6DrauBrush;pDC-RectangleSnake
[0].x»2O Snake
[0]•y«20Snake
[0].x*1*20,Snake
[0]*20;09pDC-SelectObjectDrawBrush;〃判断吃豆的条件,撞到就吃iFSnake
[8].x*ZO^-Food.x*206bSnake
[0].y»20--Food.y«
20.Snakef0].len**;Food.is^ood^l;Snake[Snake
[0].len-1]•x«Snake[Snake
[0].len-2].x;Snake[Snake
[0].len-1]ysSnake[Snake[S].Len-2].y;e〃文睬食物祓吃了就生成ifFood.isfood»»1srandunsignedtineNULL;do II..二All classmembers]j*|♦OnTimer◊CSM^jvj Pvoid CSMAKEViewlOnTimer UINTnIDEvent〃如果食物被吃了就生成iftFood.isfood-1srandunsignedtimeHULL;do forint isfo«Snake
[0].len-1;isfo-0;isfo--ifSnake
[8].x*20^«Snake[isfo]«x»20Snake
[0].y*20=«Snake[isfo].y20Food.x=randX25;Food.y-rand^25;whileFood.x»2070||Food4*2070||Food.x»20i3fl||Food.y*20H3O;pDC-RectangleFood.x*20Food.y»28,Food.x*1«20,Food.y*1*20;Food.isfood«0;wCUiew::OnTinernIDEuent;/////////////////////////////////下面由我来具体分析代码ifSnake
[0].len==2SetTimerl370NULL;,,ifSnake
[0].len==3SetTimerl,270,NULL;ifSnake
[0].len==6SetTimerl200NULL;,if Snake
[0].len==9SetTimer1,100,NULL;此段代码的作用是依据蛇的长度来进行函数的定义,可以依据长度来进行嬉戏难度的设定,SetTimer如上代码分别进行一次新的移动370ms270ms200ms100ms//撞界推断wifSnake
[0].x*20=37||Snake
[0].y*20=37||Snake
[0].x20=462||Snake
[0].y*20=462KillTimerl;AfxMessageBoxsoure;}这里为什么要乘以呢?由于我们初始化的时候是20Snake
[0].x=10;Snake
[0].y=10;Snake[l].x=l1;Snake[l].y=10;Snake
[2].x=12;Snake
[2].y=10;所以只是把贪吃蛇的起始位置“搬移”到倍的位置当然可以等价于20Snake
[0].x=10*20;Snake
[0].y=10*20;Snake[l].x=l1*20;Snake
[1].y=10*20;Snake
[2].x=12*20;Snake
[2].y=10*20;蛇的一节身体为一个矩形块,这样表示每个矩形块只需起点坐标和X y身体是不断增长的,所以用数组存放每一节的坐标//蛇身相撞推断if Snake
[0].len3forint sn=Snake
[0].len-1;sn0;snif Snake
[0].x*20==Snake[sn].x*208Snake
[0].y*20==Snake[sn].y*20KillTimerl;AfxMessageBoxsoure;//s=0;}}这段是最好理解的了,由于推断蛇自己是否咬到了自己,依据蛇长进行次次循环sn,sn forsn-1并且和进行比较之所以进行次那确定是不包括蛇头而且蛇的长度也必需大于才Snake[O].x sn-13会发生自己咬自己的状况是停止计时器;和之前的对应而已KiHTimerl;SetTime这里不深究,总之就是输出一个原样输出内容AfxMessageBoxsoure;把白色的选入设备进行画图pDC-SelectStockObjectWHITE_PEN;//“PEN”pDC-RectangleSnake[Snake[O].len-1].x*20,Snake[Snake
[0].len-l].y*20,/让它去画最终一Snake[Snake[O].len-1].x+1*20,Snake[Snake[O].len-1].y+1*20;/个节点贪吃蛇的蛇身移动forint i=Snake
[0].len-l;i0;i--//]Snake[i].x=Snake[i-1].x;Snake[i].y=Snake[i-1].y;这段的学问点要严峻的说明一下为什么要特地用白笔画最终一个呢?因为我们的嬉戏界面是用白色的,贪吃蛇移动的时候,确定是蛇1头向前走一单位,而尾部确定要“擦除”掉一个单位,那怎么擦除呢?我们只能用和背景色一样的画笔原来蛇的位置和新蛇的位置差一个单位,所以看起来蛇会多一节身体,所以将蛇的最终一节用背景色覆盖让它起到“消SelectStockObjectWHITE_PEN逝”最终一个节点的功能让我们以为蛇是向前走了如假设现在贪吃蛇有个单位40123Snake[Snake
[0].len-1].x*20=Snake[Snake
[0].4-1].x*20=Snake
[3].x*20数组恰好是最终一个节点的下标,别忘了数组是从起先算的3请细致领悟2forinti=Snake
[0].len-1;i0;i—Snake[i].x=Snake[i-1].x;Snake[i].y=Snake[i-1].y;}进行次数为“长度-次的循环1为什么要进行长度次呢?我这里要说明一下,这里是不包括蛇头的进行的平移,用数组赋值的方法,把前一节点保存在后一个结点,然后头结点向前移动//方向推断ifSnake[O].direct==lSnake[O].y—;ifSnake
[0].direct==2Snake
[0].y++;ifSnake
[0].direct==3Snake
[0].x—;ifSnake
[0].direct==4Snake
[0].x++;pDC-SelectStockObjectBLACK_PEN;CBrush DrawBrush=RGB100,100,100;CBrush*Drawbrush=pDC-SelectObjectDrawBrush;pDC-RectangleSnake
[0].x*20,Snake
[0].y*20,Snake
[0].x+1*20,Snake
[0].y+1*20;pDC-SelectObjectDrawBrush;本别代表“上下左右”进行移动,然后用选定画刷画“1234”x++,y++出一个新节点的矩形作为头结点//食物推断ifFood.isfood==0srandunsignedtimeNULL;doforint isfo=Snake
[0].len-1;isfo=0;isfo ifSnake[O].x*20==Snake[isfo].x*20Snake
[0].y*20==Snake[isfo].y*20Food.x=rand%;Food.y=rand%;}}whileFood.x*2070||Food.y*2070||Food.x*20430||Food.y*20430;;pDC-RectangleFood.x*20Food.y*20,Food.x+l*20,Food.y+1*20,Food.isfood=l;}这里关于srandunsignedtimeNULL;rand的用法在本博客有探讨帖这里不再赘述用数组初始化长度为的贪吃蛇,并且默认食物未出现在类上运用供应的233CView MFCWindows消息中消息,运用函数让系统供应一个时钟节拍,更新嬉戏WM_TIMER OnTimer具体嬉戏实现,包括蛇撞到自己和围墙都将使嬉戏结束,推断吃豆等,其中还包括依据蛇的长度来进4行嬉戏难度的变更具体键盘嬉戏操作运用到消息响应中的5Windows WM.KEYDOWN,用来响应玩家的实际操作OnKeyDown///////////////////////////////////////////////////////////////////////第一部分首先在已有工程下的中右键类添加以下“ClassView”CView Windows信息1WM_KEYDOWN2WM_RBUTTONDOWN3WM_TIMER再右键类选择选CView“ADD VirtualFunciton OnlnitialUpdate当食物被吃了指定食物的地方出现的地方在小于和大于的矩形70430区域内并且把食物属性更改为“存在”/////////////////////////////////////////////////////mini mm以上就是版步骤已经具体之至了,通过此次贪吃蛇我发觉不难,不过花了我整整一个国庆MFC MFC的时间,茶饭不思夜不能寐觎遨,类的强大我是第一次看到,以后我要多加关注类的学CView CView问点,写出这个文档的意义我觉得能让我的思路更加清楚,终归能和他人说明代码并且让别人能理解那是一件很开心的事情WM-原DR0PFILE8IndicatesSNAKE classeswhena fileis dropped新建消息/零件已存在的消息而件句柄♦F CAboutDIgWindowsIN]:(D确定■;♦WM.CANCELMODECMainFrame WMKEYDOWNWM_CAPTURECHANGED WMRBUHONDOWN取消♦■;n楚i mCSNAKEAppWM_CHAR WM_CONTEXTMENU FWMJMER♦,CSNAKEDoc可■耐香WMCOPYDATA WMCREATEWM1Add HandlerDESTROY♦■CSNAKtyiew」♦Globals Addand EditWMDROPHLESWM ERASEBKGNDWMEdit ExistingHELPINFOWM_HSCROLL的功能如下:OnlnitialUpdateWM_KEYUPWM_KILLFOCUSWM__LBUTTONDBLCLKWMJ.BUTTONDOWNWMLBUTTONUP V/M视图窗口完全建立后第一个被框架调用Class orobject tohandleMOUSEMOVE WM的函数框架在第一次调用MOUSEWHEEL WMMOVE CSNAKEViewWMPAINT IDAPPABOUTID APPEXIT ID*EDITCOPY IDEDIT CUTaw owWMRBUTTONDBLCLK前会调用OnDraw WM_RBUTTONUP Filterfor messagesavailable toWM_SETCURSOR WMVChild WindowSETFOCUS因此OnlnitialUpdate,是设置滚动视图的逻辑尺寸和映射模式的最OnlnitialUpdate合适的地方时间上,两者先后依次不同,构造函数生成本类的对象,但没有产生窗口,OnCreate后窗口产生,然后才是视图的一般在这里对视图的显示做初始化OnlnitialUpDate,简洁点,就是只是产生的基本结构和变量而在ONCREATE VIEW中,主要初始化视图中控件等对各个变量进行初始化操作OnlnitialUpDate所以我们要用这个函数来进行贪吃蛇的初始化工作再者还要添加一个成员函数oninit进行贪吃蛇外观的初始化控件的设计再者是设计嬉戏的一些控件来限制“嬉戏起先”“嬉戏结束”和“嬉戏暂停”我们可以点击“工作空间”的进行控件的具体设计,ResourceView这里我们在文件夹中把中默认的控件全部Menu“IDR_MAINFRAME”删除EG—3Pnis由ogoa t当,门山Q)IM(I)邑文件0和查播入工程的蛆建电斯助®公志出日属士嫉皿二3Q SNAKEWin32Debug(M)俯助一-USNAKE resources」♦Accelerntor」♦Dialog♦_J Icon♦J Menu翁IDR-MAJNFRAMC♦_J SiringTable」♦Toolbar右键其中的标题栏,点击属性,会得到一个菜单栏标题,我们分别建立1♦_Version个菜单栏标题这里我们分别建“嬉戏”▼、▼;Q_S—kc TJI|AII classtncfni|:AssertValld画百密」吗阖省0x JM赵(文芹9卿力8a心)左祠看⑺T独电入曲C图D I80L)俎建⑴IRd)窗口如祜物QP三令四S2D4jDQ.SfB.ke—|WM2Debug J;游戏‘招购®关于他次设计;-----------.:面代开的那港帕停新战世多游潴推出-3DQ Snsktiresources♦.J Accelerator•_J Bitmap♦_j Dialog」♦Icon日i-Menu金IDRMAJNFRAMf:.」♦String Table♦.J Toolbar点击并且在已有控件中的列表中点击属性,进行“菜单项目属性”的设置我们本别建立的属性“标明”与对应的有嬉戏起先嬉戏暂停ID IDM_STARTIDM_PAUSE嬉戏接着嬉戏退出IDM_CONTINUE IDM.EXIT此处控件的设计是“可见即可得”的控件操作游戏帮助国)关于此次设计:胜利设置之后我们分别右键各项属性进行消息响应处理函数的生成ID具体方法操作例子如下右键“嬉戏起先”点击”类向导建立”12在页面,在要进行消息响应的控件列表中上选择对应的这3Message MapsID Object IDs ID,里我们选择具体实现的环境是IDM_START,类,所以我们必需把的默认改CView Classname”“CMainFrame”为类”,并且在类型设置中,用设置为其为吩咐消息其余“CView“Messages”“COMMAND”各项也依据同理进行设置Message MapsMember Variables|Automation ActiveXEvents|ClassInfo|Project[DOSnakeClass nameAddClass...▼D:\MFC\DQ Snake\DQ SnakeView.h,D CDQSnakeViewObjectIDsDelete FunctionMessagesIDFILE SAVEID COMMANDEditCodeNEXT PANEID UPDATECOMMAND UIPREVPANEIDM^CONTINUEIDM EXITIDMPAUSE\...\DQ_SnakeView.cppIDM STARTMember functionsWOnKeyOown ONWMKEYDOWNW OnPauseONJDM^PAUSE COMMANDVOnPreparePrinting WOnRButtonDown ONWMRBUTTONDOWN23OnStart ONJOM_START:COMMAND DescriptionHandleacommandfrommenu.acceL cmdbutton]确定取消。
个人认证
优秀文档
获得点赞 0