[精選]vc可視化課程設計mfc貪吃蛇--資料_第1頁
[精選]vc可視化課程設計mfc貪吃蛇--資料_第2頁
[精選]vc可視化課程設計mfc貪吃蛇--資料_第3頁
[精選]vc可視化課程設計mfc貪吃蛇--資料_第4頁
[精選]vc可視化課程設計mfc貪吃蛇--資料_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、課程名稱 可視化編程(VC) 學院計算機科學與技術學院 專業(yè)軟件工程專業(yè) 班 級 姓 名 指導教師 2012 2013學年 第2學期 目錄 1、 課程設計要求2 2、 系統(tǒng)功能實現與操作 2 3、系統(tǒng)設計概述 2 3.1添加結構體說明2 3.2模塊說明3 3.3主要功能函數代碼及注釋 3 4、調試過程11 4.1添加功能說明11 4.2錯誤及解決方案11 5、程序運行結果12 附:主要類 Cview的成員函數代碼 15 1、課程設計要求 題目: 基于MFC的貪吃蛇游戲設計與實現。 要求: 1. 游戲界面設計 2. 食物的初始化 3. 游戲開始以及具體實現 2、系統(tǒng)功能實現與操作 本系統(tǒng)運用AP

2、I函數的相關功能進行界面設計和功能實現。通過Rectangle ()函數繪制操作區(qū)域及障礙物。通過連續(xù)的小矩形實現蛇身的繪制。通過 srand0函數和 rand()函數生成隨機數,完成生成食物功能的實現。綜合運用多種if條件判斷和 for循環(huán)的嵌套使用的算法完成各種條件判斷。 該系統(tǒng)功能簡單,操作簡易。打開程序后,點擊菜單欄的游戲按鈕,點擊 開始游戲,系統(tǒng)彈出對話框,提示還有3秒開始。游戲開始后,貪吃蛇開始移動, 通過操作鍵盤上的上下左右方向鍵控制蛇的移動,躲避障礙物并吃掉食物。當吃 掉的食物累計到達一定數量后,蛇行速度加快。直至撞到邊界或障礙物或撞到自 身,游戲結束。此時彈出對話框,提示所得

3、分數。游戲中途可通過暫停和繼續(xù)按 鈕執(zhí)行相應操作。 3、系統(tǒng)設計概述 3.1添加結構體說明 struct Sn ake int x,y; int len; int direct; S nake50; struct Food int x; int y; int food; Food; Snake結構體數組用于存放貪吃蛇的相關數據,其中 x,y存放當前節(jié)點矩 形左上角的坐標,(Snake0為蛇頭),len存放當前蛇身的長度,direct存放蛇的 行進方向,可在14取值。 Food結構體用于存放食物的位置信息。其中 x, y存放食物小矩形左上角左 標,food存放食物存在的布爾判斷值。 3.2模塊說

4、明 系統(tǒng)代碼部分主要分為三個模塊,界面控制模塊、初始化模塊和功能模塊。 界面控制模塊包括函數:OnStart(),OnPause() OnContinue(),OnExit() 初始化模塊包括函數:OnlnitialUpdate(),OnDraw(), oninit() 功能模塊包括函數:OnKeyDown(),OnTimer() 3.3主要功能函數代碼及注釋 OnStart() void CSn akeView: On Start() / TODO: Add your comma nd han dler code here SetTimer(1,3000,NULL); AfxMessageB

5、ox(還有 3 秒開始 !); 點擊開始游戲觸發(fā),設置定時器控制三秒后開始游戲。 OnPause() void CSn akeView:O nPause() / TODO: Add your comma nd han dler code here KillTimer(1); AfxMessageBox(不要讓人家等太久); 關閉定時器,暫停游戲 OnContinue() void CSn akeView: OnContin ue() / TODO: Add your comma nd han dler code here SetTimer(1,10,NULL); 重啟定時器,恢復游戲 OnEx

6、it() void CSn akeView:O nExit() / TODO: Add your comma nd han dler code here AfxMessageBox(歡迎下次再來!); exit(0); 彈出對話框提示退出。 OnlnitialUpdate() void CSn akeView: Onln itialUpdate() CView:O nln itialUpdate(); / TODO: Add your specialized code here an d/or call the base class Sn ake0.x=10; Sn ake0.y=10; Sn

7、 ake1.x=10; Sn ake1.y=10; Sn ake2.x=10; Sn ake2.y=10; Sn ake0.direct=2; Sn ake0.le n=3; Food.food=1;初始化蛇的長度和位置 用這個函數進行蛇的初始化工作。初始化貪吃蛇起初有3個節(jié)點,長度為3, 起始坐標存入數組,食物為1無0有。 OnDraw() void CSn akeView: On Draw(CDC* pDC) CSn akeDoc* pDoc = GetDocume nt(); ASSERT_VALID(pDoc); / TODO: add draw code for n ative da

8、ta here CBrush backBrush(RGB(111,111,111); CBrush* pOldBrush = pDC-SelectObject( CRect rect; pDC-GetClipBox( pDC-PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY); pDC-SelectObject(pOldBrush); pDC-Recta ngle(9,9,401,401); CBrush zaBrush(RGB(111,111,111); pDC-SelectObject(zaBrush); for

9、(i nt m=0;mRecta ngle(150,(100+m*10),160,(110+m*10); for(i nt n=0 ;* 10; n+) pDC-Recta ngle(250+n*10),200,(260+n*10),210); onini t(); 窗口創(chuàng)建時架構調用的函數,通過此函數完成界面初始化。創(chuàng)建灰色畫刷選 入設備環(huán)境,通過繪圖函數繪制用戶區(qū)。用兩個 for循環(huán)逐次繪制矩形的算法繪 制出場景中的障礙物。 oninit() void CSn akeView:o nin it() CDC *pDC=GetDC(); CBrush DrawBrush=(RGB(255,0,

10、0); CBrush *Drawbrush=pDC-SelectObject( for(i nt i=0;iRecta ngle(S nakei.x*10,S nakei.y*10,(S nakei.x+1)*10,(S nakei.y+1) *10); pDC-SelectObject(DrawBrush); /利用 for循環(huán)繪制起始的蛇身 該函數為自己添加的成員函數,用于繪制開始時的蛇身(長度為3)。 OnKeyDown() void CSn akeView: On KeyDow n( UINT nChar, UINT nRepC nt, UINT n Flags) / TODO: Ad

11、d your message han dler code here an d/or call default switch( nChar) case VK_UP:if(S nake0.direct!=2) Sn ake0.direct=1;break; case VK_DOWN:if(S nake0.direct!=1) Sn ake0.direct=2;break; case VK_LEFT:if(S nake0.direct!=4) Sn ake0.direct=3;break; case VK_RIGHT:if(S nake0.direct!=3) Sn ake0.direct=4;br

12、eak; _ 通過鍵盤設置轉頭方向 CView:O nKeyDow n(n Char, nRepC nt,n Flags); CView:O nKeyDow n(n Char, nRepC nt,n Flags); 該函數為鍵盤消息的接收函數。從鍵盤得到的上下左右的不同按鍵,會根據 switch判斷語句的case改變Snaka direct的值,從而改變蛇的行進方向。 OnTimer() void CSn akeView: On Timer(UINT nIDEve nt) / TODO: Add your message han dler code here an d/or call defa

13、ult CDC *pDC=GetDC(); CStri ng soure; int j=0; if(Sn ake0.le n=3)SetTimer(1,170,NULL); if(Sn ake0.le n=9)SetTimer(1,130,NULL); if(Sn ake0.le n=14)SetTimer(1,95,NULL); if(Sn ake0.le n=18)SetTimer(1,60,NULL); 根據蛇的長度進行速度的設定 soure.Format(得分:%d!,(S nake0.le n-3)*10); / 設置每個食物 100 分 撞墻判斷 if(S nake0.direct

14、=3)用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); 分四種情況撞障礙判斷,k為循環(huán)控制標識 if(Sn ake0.direct=3) for(i nt k=0;k20;k+) if(Sn ake0.x*10=160用來控制直接結束當前函數 KillTimer(l); AfxMessageBox(soure); if(Sn ake0.x*10=350用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); / if(Sn ake0.direct=2) for(i nt k=0;k10;k+) if(Sn

15、ake0.x*10=(250+k*10)用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); if(Sn ake0.x*10=150用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); / if(Sn ake0.direct=1) for(i nt k=0;k10;k+) if(Sn ake0.x*10=(250+k*10)用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); if(Sn ake0.x*10=150用來控制直接結束當前函數 KillTimer(1)

16、; AfxMessageBox(soure); / if(Sn ake0.direct=4) for(i nt k=0;k3) for(i nt sn=Sn ake0.le n-1;s n 0;s n-) if(Sn ake0.x*10=S nakes n.x*10 KillTimer(1); AfxMessageBox(soure); /對尾節(jié)點用白筆涂掉 if(j!=1) pDC-SelectStockObject(WHITE_PEN); pDC-Recta ngle(S nakeS nakeO.le n-1.x*10,S nakeS nakeO.le n-1.y*10,(S nak eS

17、 nake0.le n-1.x+1)*10,(S nakeS nake0.le n-1.y+1)*10); for(i nt i=S nake0.le n-1;i0;i-) Sn akei.x=S nakei-1.x; Sn akei.y=S nakei-1.y; 行走方向判斷 if(Sn ake0.direct=1)S nake0.y-; if(Sn ake0.direct=2)S nake0.y+; if(Sn ake0.direct=3)S nake0.x-; if(Sn ake0.direct=4)S nake0.x+; pDC-SelectStockObject(BLACK_PEN)

18、; CBrush DrawBrush=(RGB(255,0,0); CBrush *Drawbrush=pDC-SelectObject( if(j!=1) pDC-Recta ngle(S nake0.x*10,S nake0.y*10,(S nake0.x+1)*10,(S nake0.y+1)*1 0); pDC-SelectObject(DrawBrush); 判斷吃食物的條件 if(Sn ake0.x*10=Food.x*10 Food.food=1; Sn akeS nake0.le n-1.x=S nakeS nake0.le n-2.x; Sn akeS nake0.le n-

19、1.y=S nakeS nake0.le n-2.y; 生成食物 in t o=1;控制生成食物成功時跳出循環(huán) if(Food.food=1) sran d( un sig ned)time(NULL); do Food.x=ra nd()%40; Food.y=ra nd()%40; if(Food.x!=0p20;p+) if(Food.x*10!=15 0 if(o!=1) for(i nt q=0;qRecta ngle(Food.x*10,Food.y*10,(Food.x+1)*10,(Food.y+1)*10); Food.food=0; CView:O nTimer( nIDE

20、ve nt); 主要功能函數,響應于定時器消息,用于實時改變游戲界面,是游戲功能實 現的主要函數。下面依次解釋其中功能模塊: 1、用四個if判斷語句對蛇身長度進行判斷,然后設置定時器間隔控制蛇行速度。 2、對撞墻進行判斷,當蛇頭的坐標企圖越過系統(tǒng)邊界并且其行進方向是沖著墻 的方向時,判定撞墻,關閉定時器并且置程序結束標志j=1 o 3、撞障礙物判斷,同撞墻判斷,對蛇的行進方向分上下左右四種情況進行判斷, 然后判斷蛇頭坐標是否企圖越過障礙物。若撞屆則同樣置程序結束標志j=1 o 4、撞蛇身判斷,此算法是if嵌套for循環(huán)嵌套if判斷,對蛇頭的坐標和舍身每 一點的坐標進行一次比較,看是否有蛇頭的坐

21、標與蛇身坐標重合。 若有則判定自 撞,置程序結束標志j=1 o 5、蛇行進的實現。蛇行進主要的算法是,每一次 Timer消息,將蛇的蛇頭的下 一位置添加一個矩形,并且將蛇尾的小矩形用與背景相同顏色的矩形填充掉,完 成刪除。通過一個for循環(huán)來實現。 6行走方向判斷,通過對 Snake.direct進行判斷,控制蛇頭坐標在 x,y方向上 自加或自減,完成方向的設定。 7、判斷吃食物的條件,若蛇頭坐標與食物坐標重合,則吃食物。置食物標識為 1表示沒有食物。 8、生成食物方法。通過rand()函數產生隨機數,通過計算得到相應食物的坐標。 對該坐標的可行性進行判斷,若坐標在操作區(qū)外或在障礙物中,則舍棄

22、,循環(huán)執(zhí) 行這一步知道得到可行坐標,繪制食物矩形 4、調試過程 4.1添加功能說明 在此軟件完成后,僅能實現定速度的無障礙的貪吃蛇游戲。經過改進,添加 了初始化的相應代碼,修改了 Timer()函數的相關功能代碼,實現了速度根據食 物個數可變,添加了障礙物。 4.2錯誤及解決方案 在編寫程序的過程中遇到了諸多錯誤, 除書寫錯誤外,其他錯誤通過探討和 查閱資料的方式得到解決。具體問題有以下幾個: 之前對MFC圖形的相關類了解的比較少,仔細看書后學習了CDC類的相關 知識,了解了在NFC編程中圖形函數的使用方法。 在遍寫程序之前,不清楚在單文檔 MFC程序中,架構對各個類的功能函數的 調用次序,所

23、以不知道應該將初始化的相關內容寫在哪一個函數中,經查閱資料 得知,OnlnitialUpdate是視圖窗口完全建立后第一個被框架調用的函數??蚣茉?第一次調用 On Draw前會調用Onln itialUpdate,因此Onln itialUpdate是設置滾動 視圖的邏輯尺寸和映射模式的最合適的地方。在時間上,兩者先后順序不同,構 造函數生成本類的對象,但沒有產生窗口,On Create后窗口產生,然后才是視圖 的OnlnitialUpDate,般在這里對視圖的顯示做初始化。 在運行程序后,出現 BUG,當蛇行至靠近障礙物或墻壁那一列時就判定了撞 墻,導致蛇沒有辦法沿著游戲區(qū)域的邊界行走,吃

24、不到邊上的食物。仔細研究代 碼后,在撞界判斷中對蛇頭坐標的基礎上加入了對蛇行方向的判斷,解決了這一 問題。 在撞界結束游戲后,蛇仍然會向前走一步,走到邊界的外面。仔細研究代碼后 沒有發(fā)現錯誤,和同學探討后發(fā)現,在OnTimer()函數中,撞界后則彈出對話框, 終止計時器,但程序還會將此函數執(zhí)行完,所以蛇還會向前走一步。于是在撞界 判斷中加入了程序結束標志,在撞界后立即結束程序不再執(zhí)行任何語句。 解決了 這一問題。 在添加了障礙物之后食物生成在“墻”里。于是在生成隨機數的判定中,加入 了對生成坐標在墻內的判斷,解決了這一問題。 在程序完成后,我還想完成脫機運行的功能,即在沒有VC的計算機上也能夠

25、 運行這個程序。上網查閱了相關資料,了解到:在編寫MFC程序時,對基類的 連接有靜態(tài)和動態(tài)兩種。當選擇靜態(tài)連接時,系統(tǒng)會在編譯組建時將用到的類圭寸 裝在程序中,就能夠離開編程環(huán)境運行了。也就是MFC的EXE可執(zhí)行文件分為 Debug版和Release版。于是這個問題也得到了解決。 最終,在不懈的努力下,程序終于得以完美運行了 5、程序運行結果 n , y 無歷邀-sna 附:主要類Cview的成員函數代碼 / sn akeView.cpp : impleme ntati on of the CSn akeView class / #i nclude stdafx.h #in clude sn

26、ake.h #in clude sn akeDoc.h #in clude sn akeView.h #ifdef _DEBUG #defi ne new DEBUG_NEW #un def THIS_FILE static char THIS_FILE = _FILE_; #en dif struct Sn ake int x,y; int len; int direct; Sn ake50; struct Food int兀 int y; int food; Food; / / CSn akeView IMPLEMENT_DYNCREATE(CS nakeView, CView) BEGI

27、N_MESSAGE_MAP(CS nakeView, CView) AFX_MSG_MAP(CS nakeView) ON_WM_KEYDOWN() ON_WM_TIMER() ON_COMMAND(ID_START, On Start) ON_COMMAND(ID_PAUSE, On Pause) ON_COMMAND(ID_EXIT, On Exit) ON_COMMAND(ID_CONTINUE, OnContin ue) AFX_MSG_MAP / Stan dard prin ti ng comma nds ON_COMMAND(ID_FILE_PRINT, CView:O nFil

28、ePri nt) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:O nF ilePri nt) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:O nFilePri ntPreview) END_MESSAGE_MAP() / / CSn akeView con structio n/destructio n CSn akeView:CS nakeView() / TODO: add con struct ion code here CSn akeView:CS nakeView() BOOL CSn akeView:PreCre

29、ateWi ndow(CREATESTRUCT / / CSn akeView draw ing void CSn akeView: On Draw(CDC* pDC) CSn akeDoc* pDoc = GetDocume nt(); ASSERT_VALID(pDoc); / TODO: add draw code for n ative data here CBrush backBrush(RGB(111,111,111); CBrush* pOldBrush = pDC-SelectObject( CRect rect; pDC-GetClipBox( pDC-PatBlt(rect

30、.left, rect.top, rect.Width(), rect.Height(),PATCOPY); pDC-SelectObject(pOldBrush); pDC-Recta ngle(9,9,401,401); CBrush zaBrush(RGB(111,111,111); pDC-SelectObject(zaBrush); /繪制障礙物 for(i nt m=0;mRecta ngle(150,(100+m*10),160,(110+m*10); for(i nt n=0 ;* 10; n+) pDC-Recta ngle(250+n*10),200,(260+n*10),

31、210); onin it(); / / CSn akeView printing BOOL CSn akeView:O nPreparePri nti ng(CPri ntlnfo* pI nfo) / default preparati on return DoPreparePri nti ng(pl nfo); void CSn akeView:O nBegi nPrintin g(CDC* /*pDC*/, CPrintlnfo* /*pI nfo*/) / TODO: add extra in itializati on before printing void CSn akeVie

32、w:O nEn dPri ntin g(CDC* /*pDC*/, CPrintlnfo* /*pI nfo*/) / TODO: add clea nup after printing / / CSn akeView diag no sties #ifdef _DEBUG void CSn akeView:AssertValid() const CView:AssertValid(); void CSn akeView:Dump(CDumpC on text CSn akeDoc* CSn akeView:GetDocume nt() / non-debug vers ion is inli

33、ne ASSERT(m_pDocume nt-lsKi ndOf(RUNTIME_CLASS(CS nakeDoc); return (CS nakeDoc*)m_pDocume nt; #endif /_DEBUG / / CSn akeView message han dlers void CSn akeView:O nKeyDow n(UINT n Char, UINT n RepC nt, UINT n Flags) / TODO: Add your message han dler code here an d/or call default switch( nChar) case

34、VK_UP:if(S nake0.direct!=2) Sn ake0.direct=1;break; case VK_DOWN:if(S nake0.direct!=1) Sn ake0.direct=2;break; case VK_LEFT:if(S nake0.direct!=4) Sn ake0.direct=3;break; case VK_RIGHT:if(S nake0.direct!=3) Sn ake0.direct=4;break; /通過鍵盤設置轉頭方向 CView:O nKeyDow n(n Char, nRepC nt, nF lags); CView:O nKey

35、Dow n(n Char, nRepC nt, nF lags); void CSn akeView:O nTimer(UINT nIDEve nt) / TODO: Add your message han dler code here an d/or call default CDC *pDC=GetDC(); CStri ng soure; int j=0; if(Sn ake0.le n=3)SetTimer(1,170,NULL); if(Sn ake0.le n=9)SetTimer(1,130,NULL); if(Sn ake0.le n=14)SetTimer(1,95,NUL

36、L); if(Sn ake0.le n=18)SetTimer(1,60,NULL); /根據蛇的長度進行速度的設定 soure.Format(”得分:d!,(Snake0.len-3)*10); / 設置每個食物 100 分 /撞墻判斷 if(S nake0.direct=3)/用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); 分四種情況撞障礙判斷,k為循環(huán)控制標識 if(Sn ake0.direct=3) for(int k=0;k20;k+) if(Sn ake0.x*10=160/用來控制直接結束當前函數 KillTimer(1); Af

37、xMessageBox(soure); if(Sn ake0.x*10=350/用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); / if(Sn ake0.direct=2) for(i nt k=0;k10;k+) if(Sn ake0.x*10=(250+k*10)用來控制直接結束當前函數 KillTimer(l); AfxMessageBox(soure); if(Sn ake0.x*10=150用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); / if(Sn ake0.direct=1) f

38、or(i nt k=0;k10;k+) if(Sn ake0.x*10=(250+k*10)用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); if(Sn ake0.x*10=150用來控制直接結束當前函數 KillTimer(1); AfxMessageBox(soure); / if(Sn ake0.direct=4) for(int k=0;k3) for(i nt sn=Sn ake0.le n-1;s n 0;s n-) if(Sn ake0.x*10=S nakes n.x*10 KillTimer(1); AfxMessageBox(

39、soure); /對尾節(jié)點用白筆涂掉 if(j!=1) pDC-SelectStockObject(WHITE_PEN); pDC-Recta ngle(S nakeS nake0.le n-1.x*10,S nakeS nake0.le n-1.y*10,(S nakeS nake0.l en-1.x+1)*10,(S nakeS nake0.le n-1.y+1)*10); for(i nt i=S nake0.le n-1;i0;i-) Sn akei.x=S nakei-1. x; Sn akei.y=S nakei-1.y; 行走方向判斷 if(Sn ake0.direct=1)S

40、nake0.y-; if(Sn ake0.direct=2)S nake0.y+; if(Sn ake0.direct=3)S nakeO.x-; if(Sn ake0.direct=4)S nakeO.x+; pDC-SelectStockObject(BLACK_PEN); CBrush DrawBrush=(RGB(255,0,0); CBrush *Drawbrush=pDC-SelectObject ( if(j!=1) pDC-Recta ngle(S nake0.x*10,S nake0.y*10,(S nake0.x+1)*10,(S nake0.y+1)*10); pDC-SelectObject(DrawBrush); /判斷吃食物的條件 if(Sn ake0.x*10=Food.x*10 Food

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論