C課程設(shè)計報告(貪吃蛇游戲)_第1頁
C課程設(shè)計報告(貪吃蛇游戲)_第2頁
C課程設(shè)計報告(貪吃蛇游戲)_第3頁
C課程設(shè)計報告(貪吃蛇游戲)_第4頁
C課程設(shè)計報告(貪吃蛇游戲)_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、東南大學(xué)土木工程學(xué)院 C+ 課程設(shè)計 2011年9月12日C+程序課程設(shè)計 貪吃蛇游戲姓名:張凡學(xué)號:05110532指導(dǎo)教師:陸金鈺提交日期:2011-09-16目錄C+程序課程設(shè)計1第一章課題介紹31.1選題背景31.2關(guān)于編譯軟件41.3關(guān)于兼容性4第二章設(shè)計概要42.1程序功能簡介42.2程序流程5第三章游戲?qū)崿F(xiàn)53.1創(chuàng)建工程63.2游戲界面控制73.2.1墻、框體的繪制73.2.2蛇身的繪制83.2.3食物的繪制93.3游戲控制113.3.1蛇的移動113.3.2蛇死亡的判斷133.3.3消息窗口的彈出開始消息框關(guān)卡消息框結(jié)束消

2、息框153.3.4游戲音效16第四章 結(jié)果與討論174.1程序運行174.2對源程序的改進184.3錯誤調(diào)試與分析184.3.1關(guān)于窗口的重畫問題184.3.2關(guān)于雙音軌的問題184.3.3程序的穩(wěn)定性194.4課程設(shè)計心得與體會19附錄21第一章 課題介紹1.1選題背景蛇-傳說中的圣靈之物,仰頭為神、俯首為魔。蛇是月亮國膜拜的神,月亮國的子民們都認為蛇是萬能的主宰派來保護他們的守護者。蛇在這個島嶼就像空氣一樣自然的出現(xiàn)在各個角落,有些還成為居民的寵物, 陪伴孩子長大, 和年輕人一起去探險,守護著散步的老人。在善良的女娟神保佑下,人們的生活安寧平靜。為了答謝女娟的庇佑,每年月亮國的國民都會舉辦

3、一個守護蛇大賽,大家都會拿出自己最強、最炫、最快、最稀有的蛇來參加比賽, 獲得第一名的人將得到國王的特別嘉獎。所以國民一生都在不斷的培養(yǎng)更有威力、更長、更壯的蛇。" 貪吃蛇" 是一個產(chǎn)生于1970 年代中后期的計算機游戲,也叫蛇吃豆。該游戲在1990 年代由于一些手機將其引入而一時間再度流行起來。在游戲中,玩家操控一條細長的蛇爬行于一個帶邊界的平面之上,一路拾起觸碰到之事物或其它類似的物件, 并要避免觸碰到自身或者包圍著游戲區(qū)的"墻"。每次貪吃蛇吃掉一件食物, 它的身體便增長一些,這讓游戲的難度漸漸變大。操控貪吃蛇時,玩家操控貪吃蛇的頭部的朝向(向上、向

4、下、向左或向右)控制貪吃蛇的進行方向,貪吃蛇的身體將跟隨著其頭部行進。另外, 玩家不可在游戲中途停止貪吃蛇的進行。隨著貪吃蛇的成功移植到手機系統(tǒng),貪吃蛇的操作按鍵要求與手機按鍵的完美匹配,使貪吃蛇游戲風(fēng)靡起來。貪吃蛇是家喻戶曉的益智類小游戲,選擇這個題目一是為了將自己的所學(xué)知識加以運用,二是一直以來貪吃蛇這個游戲就深深地吸引著我,它的制作方法對于以前的我而言都是很神秘的。我希望通過自己的所學(xué)知識把它剖析開來,真正的了解它的本質(zhì)和精髓。雖然我的編程能力不是很強,但是我有信心,在這次學(xué)習(xí)中我將從實踐和實際的項目中提高自己的編程能力。因此我選定了這個題目。1.2關(guān)于編譯軟件本程序采用Microsof

5、t Visual C+6.0的中文版本進行編譯。Visual C+6.0是Microsoft公司推出的基于Windows操作系統(tǒng)的可視化C+編程工具,盡管Microsoft公司推出了.NET平臺的集成開發(fā)環(huán)境,但由于其良好的界面和可操作性,加上支持標準C/C+規(guī)范,但仍有相當(dāng)多的編程人員使用Visual C+6.0進行應(yīng)用系統(tǒng)的開發(fā)。1.3關(guān)于兼容性本程序經(jīng)過調(diào)試,可以在XP系統(tǒng)下編譯運行,也可以在Vista/Win 7下運行,界面稍有不同,但不影響運行結(jié)果。第二章 設(shè)計概要2.1程序功能簡介據(jù)分析,貪吃蛇游戲一共要實現(xiàn)如下幾個功能:Ø 開始運行Ø 蛇在上下左右鍵的操作下運

6、動Ø 闖關(guān)設(shè)置Ø 游戲音效Ø 游戲說明2.2程序流程根據(jù)分析后的貪吃蛇結(jié)構(gòu)設(shè)計出相應(yīng)的貪吃蛇流程(圖1)。貪吃蛇的內(nèi)容主要包括: 開始游戲,隨機出現(xiàn)食物,控制蛇的運動,吃食物,關(guān)卡處的消息詢問,游戲音效的播放,分數(shù)的輸出,游戲幫助的輸出等等。開始游戲出現(xiàn)食物蛇向右運動控制蛇的運動方向否是否否是是是是蛇身增長退出游戲蛇死亡判斷蛇頭與食物坐標是否重合開始下一關(guān)消息響應(yīng)判斷蛇頭和蛇身以及墻坐標是否重合判斷分數(shù)是否達到下一關(guān)圖1.流程圖第三章 游戲?qū)崿F(xiàn)3.1創(chuàng)建工程本程序使用Win32 Application工程,編輯在Windows窗口中打開的應(yīng)用程序。由于之前沒有接觸

7、過這類工程,所以我在短短幾天內(nèi)籠統(tǒng)的學(xué)習(xí)了一些相關(guān)的基本知識。在程序的編寫過程中,遇到了很多問題,通過查閱資料和請教別人,解決了很多問題,但是仍然有遺留的未解決的問題,所以本程序雖然實現(xiàn)了大部分功能,但不是很完善,需要在將來的學(xué)習(xí)過程中逐漸改進。 圖2.創(chuàng)建Win32 Application工程Win32 Application工程與Win32 Console Application工程有很大的不同(圖2)。其主函數(shù)是WinMain()函數(shù)。創(chuàng)建一個經(jīng)典的”Hello,World!”工程,就會有已經(jīng)寫好的WinMain()函數(shù)。WinMain()函數(shù)是整個程序的入口,雖然區(qū)區(qū)幾行。不需要改動什

8、么,但確實最主要的函數(shù)。函數(shù)定義如下:int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)在創(chuàng)建好的工程中,還有注冊窗口函數(shù)和窗口過程函數(shù)。ATOM MyRegisterClass(HINSTANCE hInstance)注冊窗口函數(shù) LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)窗口過程函數(shù)實現(xiàn)貪吃蛇游戲的算法就寫在窗口過程函數(shù)中。3.2游戲界面控

9、制貪吃蛇游戲的游戲界面包括墻的繪制、蛇身體的繪制、蛇移動范圍的繪制、食物的繪制、分數(shù)框和注釋的繪制等等。其中貪吃蛇的身體的繪制,是本程序中的核心算法。3.2.1墻、框體的繪制在win32 application工程中,有很多繪制圖形的函數(shù)。這里最多使用到的是Rectangle()函數(shù)繪制矩形。通過坐標控制矩形的兩對角點來確定矩形的長、寬、高,通過在窗口中添加畫筆和畫刷,使用不同的線條顏色和樣式,畫出所需的圖框。如下是墻的繪制:hpen=CreatePen(PS_SOLID,1,RGB(255,255,255);/創(chuàng)建無色的畫筆hbru=CreateSolidBrush(RGB(255,255,

10、255);/創(chuàng)建無色的畫刷hpenold=(HPEN)SelectObject(hdc,hpen);hbruold=(HBRUSH)SelectObject(hdc,hbru);Rectangle(hdc,rt.left,rt.top,rt.right,rt.bottom);/繪制背景SelectObject(hdc,hpenold);/恢復(fù)筆SelectObject(hdc,hbruold);/恢復(fù)畫刷hpen=CreatePen(PS_SOLID,1,RGB(255,100,0);/創(chuàng)建一支磚紅色的筆hpenold=(HPEN)SelectObject(hdc,hpen);/把磚紅色的筆選

11、進畫板Rectangle(hdc,45,35,615,465);hbru=CreateSolidBrush(RGB(255,100,0);/創(chuàng)建一支磚紅色的畫刷hbruold=(HBRUSH)SelectObject(hdc,hbru);/把磚紅色的畫刷選進畫板hbruold=(HBRUSH)SelectObject(hdc,hbru);/把磚紅色的畫刷選進畫板for(i=50;i<=600;i+=10)/畫圍墻Rectangle(hdc,i,40,i+10,49);/上邊Rectangle(hdc,i,451,i+10,460);/下邊f(xié)or(i=40;i<=450;i+=10)

12、Rectangle(hdc,50,i,59,i+10);/左邊Rectangle(hdc,601,i,610,i+10);/右邊SelectObject(hdc,hbruold);SelectObject(hdc,hpenold);程序代碼中,各種函數(shù)的功能已經(jīng)備注的很詳細,這里不再贅述。在寫程序的初期,圍墻是用小方格圍成的(圖3),后來在此基礎(chǔ)上做了改動(圖4),最后生成的效果,改變一下畫筆,完全可用幾句代碼來代替,如下:hpen=CreatePen(PS_SOLID,10,RGB(255,100,0);/創(chuàng)建一支磚紅色的筆,只是在畫刷的粗/細上做了改動hpenold=(HPEN)Selec

13、tObject(hdc,hpen);/把磚紅色的筆選進畫板Rectangle(hdc,50,40,610,460);/畫圍墻圖4圖3分數(shù)框和注釋框是用RoundRect()倒角矩形函數(shù)繪制的,和前面的矩形函數(shù)用法相同。3.2.2蛇身的繪制貪吃蛇的身體的繪制,是程序中的核心算法。包括蛇身的移動、吃食物后增長、顏色的改變。首先我們創(chuàng)建了蛇的類,蛇的位置是由坐標控制的,蛇的每一節(jié)是10×10的小方格,xi,yi表示蛇每一節(jié)的坐標,node表示蛇的節(jié)數(shù),direction表示蛇的方向,life為蛇的生命(0存活1死亡)。開始游戲時,蛇身為兩節(jié),在固定的位置出現(xiàn),然后控制時間移動。蛇的移動放發(fā)

14、就是在原先的蛇頭前加一節(jié),在用無色的畫刷繪制此時的蛇尾,用來“擦出”最后一節(jié),這樣便形成了蛇的移動。old_pos_x=snake.xsnake.node-1;/保存移動前蛇尾x的坐標old_pos_y=snake.ysnake.node-1;/保存移動前蛇尾y的坐標hpen=CreatePen(PS_SOLID,1,RGB(255,255,255);/創(chuàng)建一支無色的筆hbru=CreateSolidBrush(RGB(255,255,255);/創(chuàng)建一支無色的畫刷hpenold=(HPEN)SelectObject(hdc,hpen);/把無色的筆選進畫板hbruold=(HBRUSH)Se

15、lectObject(hdc,hbru);/把無色的畫刷選進畫板Rectangle(hdc,old_pos_x,old_pos_y,old_pos_x+10,old_pos_y-10);/用無色的筆繪制蛇尾Rectangle(hdc,old_pos_x,old_pos_y,old_pos_x+10,old_pos_y-10);/用了無色的畫刷繪制背景SelectObject(hdc,hpenold);/恢復(fù)有色的筆SelectObject(hdc,hbruold);/恢復(fù)畫刷for(i=snake.node-1;i>0;i-)/蛇的每個環(huán)節(jié)往前移動snake.xi=snake.xi-1;

16、snake.yi=snake.yi-1;當(dāng)蛇頭的坐標和食物的坐標重合,就表明蛇吃到食物了,此時蛇要增長,將原來的食物用無色的筆“擦除”,node+1。如下:if(snake.x0=food.x&&snake.y0=food.y)/吃到食物后hpen=CreatePen(PS_SOLID,1,RGB(255,255,255);/創(chuàng)建一支無色的筆hpenold=(HPEN)SelectObject(hdc,hpen);/把無色的筆選進畫板Rectangle(hdc,food.x,food.y,food.x+10,food.y-10);/用無色的筆繪制食物以取消 /被吃掉的食物Sel

17、ectObject(hdc,hpenold);/恢復(fù)有色筆在程序完成之后,我又添加了闖關(guān)模式的功能,其中每過一關(guān),蛇的顏色就會改變,這是使用switch-case語句,每一關(guān)都改變繪制蛇的畫筆和畫刷來實現(xiàn)的。3.2.3食物的繪制確定用坐標繪制貪吃蛇蛇身以后,貪吃蛇的食物如何達到隨機出現(xiàn),蛇吃完食物后再次出現(xiàn)的食物不與蛇身相重合,并且能夠按照網(wǎng)格式與蛇頭無偏差相接就是一個亟待解決的問題。隨機出現(xiàn)應(yīng)采用rand()函數(shù)來實現(xiàn),使食物隨機出現(xiàn)在蛇可以運動的范圍內(nèi);使用語句“food.x=rand()%400+60;food.y=rand()%350+60;”,讓食物的坐標產(chǎn)生在墻內(nèi)來;而食物與蛇頭無

18、偏差相接則用if語句判斷生成的坐標是否可用最小網(wǎng)格的間距整除處理。使隨機出現(xiàn)的點能夠整除最小網(wǎng)格,也就是使食物與蛇頭無偏差相接。for(i=2;i<snake.node;i+)food.x=rand()%400+60;food.y=rand()%350+60;if(food.x!=snake.xi)break;在游戲運行的過程中,經(jīng)常會出現(xiàn)新出現(xiàn)的食物與蛇身重疊的情況,讓玩家看不清食物到底在哪。經(jīng)過認真的考慮,解決這個問題的辦法就是,每次隨機出現(xiàn)食物坐標時,用循環(huán)語句判斷要出現(xiàn)的食物坐標是否與蛇身某一節(jié)的坐標重合,若是重合,重新生成一組隨機數(shù),再次判斷,直到不重合時在畫面上顯示新食物。代

19、碼如下:再由食物坐標(food.x,food.y)與蛇頭坐標是否相同判斷蛇是否“吃”到了食物,設(shè)置判斷標簽food.yes,如果吃到了,food.yes為0,則再出現(xiàn)下一個食物,反之,如果沒吃到,則不出現(xiàn)食物直到標簽為0為止。代碼如下:srand(unsigned)time(NULL);/隨機數(shù)發(fā)生器food.yes=1;/食物標記:1表示需要出現(xiàn)新食物,0表示已存在食物if(food.yes=1)/需要出現(xiàn)新食物food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)/食物隨機出現(xiàn)后必須讓食物能在整格內(nèi),這樣才能讓蛇吃到foo

20、d.x+;while(food.y%10!=0)food.y+;food.yes=0;/畫面上有食物了hpen=CreatePen(PS_SOLID,1,RGB(255,255,255);/創(chuàng)建一只無色的筆hbru=CreateSolidBrush(RGB(0,0,0);/創(chuàng)建一支黑色的畫刷hpenold=(HPEN)SelectObject(hdc,hpen);/把無色的筆選進畫板hbruold=(HBRUSH)SelectObject(hdc,hbru);/把黑色的畫刷選進畫板if(food.yes=0)/畫面上有食物就顯示Rectangle(hdc,food.x,food.y,food.

21、x+10,food.y-10);3.3游戲控制3.3.1蛇的移動開始游戲后的重點是如何用鍵盤來控制蛇的移動并傳遞到時間控制器中去判斷蛇是否死亡。首先說明鍵盤與蛇的響應(yīng),設(shè)置一個方向控制變量snake.direction,設(shè)置其值為1、2、3、4分別表示左、右、前、后,在窗口控制過程的WM_KEYDOWN中實現(xiàn)鍵盤消息的傳遞,按下不同的鍵盤按鍵,snake.direction會相應(yīng)的改變,再利用if語句對坐標進行相應(yīng)改變即可。如下:case WM_KEYDOWN:key=int(wParam);/接受按鍵if(key=VK_UP&&snake.direction!=4)/判斷是否

22、往相反的方向移動snake.direction=3;else if(key=VK_RIGHT&&snake.direction!=2)snake.direction=1;else if(key=VK_LEFT&&snake.direction!=1)snake.direction=2;else if(key=VK_DOWN&&snake.direction!=3)snake.direction=4;在這里,需要注意的是,蛇在轉(zhuǎn)向的時候,不可能轉(zhuǎn)到前進方向的反方向,即向右運動時,蛇不可能轉(zhuǎn)到屏幕的左邊前進,需要用if語句進行篩選判斷處理。蛇的移動速

23、度是用SetTimer()函數(shù)和KillTimer()函數(shù)打開和關(guān)閉計時器來控制的。其中,SetTimer()函數(shù)中的參數(shù)控制蛇的速度,例如剛開始時為“SetTimer(hWnd,1,500,NULL);”,表示每500毫秒蛇向前移動一格,此時的速度很慢,玩家可以很方便的控制其位置。為了增加游戲難度,我使用switch-case語句,改變每一關(guān)蛇的速度,越到后面速度越快,增加游戲的刺激性和趣味性,以激起玩家的興趣。后來,為了完善游戲,我又在WM_KEYDOWN和WM_KEYUP中增添了模塊,使玩家覺的蛇的運行速度過慢而不耐煩時,長按前進方向的方向鍵,就可以加快蛇的速度。當(dāng)計算機接受到長按方向鍵

24、的響應(yīng)后,改變計時器的參數(shù),加快蛇的移動速度,當(dāng)長按鍵釋放后,計算機接受釋放按鍵的響應(yīng),恢復(fù)蛇原來的速度。case WM_KEYDOWN:if(Checkpoint<4)/前三關(guān)可以通過長按鍵改變蛇的速度if(key=VK_LEFT&&snake.direction=2)SetTimer(hWnd,1,200,NULL);else if(key=VK_RIGHT&&snake.direction=1)SetTimer(hWnd,1,200,NULL);else if(key=VK_UP&&snake.direction=3)SetTimer

25、(hWnd,1,200,NULL);else if(key=VK_DOWN&&snake.direction=4)SetTimer(hWnd,1,200,NULL);break;case WM_KEYUP:key=int(wParam);switch(Checkpoint)/按鍵釋放恢復(fù)蛇的速度/這里的代碼省略模塊代碼如下:while(GetMessage(&msg, NULL, 0, 0) TranslateMessage(&msg); if(msg.message = WM_KEYDOWN && !hold) hold = true; Dis

26、patchMessage(&msg); else if(msg.message = WM_KEYDOWN) ; / 忽略多余的按鍵 else if(msg.message = WM_KEYUP) hold = false; DispatchMessage(&msg); else DispatchMessage(&msg); 但是添加此模塊運行時,長按鍵后蛇停止不動了,釋放按鍵后蛇又開始以原來的速度運動,好像變成了所需功能的相反功能了。后來查閱資料才明白,計時器的優(yōu)先級是很低的,當(dāng)長按方向鍵時,計算機只是接受了按鍵的響應(yīng),而無暇繼續(xù)計時器的執(zhí)行,導(dǎo)致蛇的運動停止,需要在W

27、inMain函數(shù)中做一些改動,改變消息機制的處理,當(dāng)長按鍵時,忽略之后多余的按鍵,是計時器響應(yīng),這樣便很好的解決了這個問題。代碼改變?nèi)缦拢簑hile (GetMessage(&msg, NULL, 0, 0) if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg) TranslateMessage(&msg);DispatchMessage(&msg);3.3.2蛇死亡的判斷其次來解釋一下如何判斷蛇的死亡,由于蛇的身體是由點坐標數(shù)組構(gòu)成的,因此判斷蛇是否死亡其本質(zhì)就是判斷蛇頭的坐標是否與游戲邊框相同或者蛇頭坐

28、標是否與蛇自己的身體相同。該過程也在WM_TIMER中寫入即可,設(shè)置一個判斷死亡變量snake.life,如果snake.life為1,則說明蛇已經(jīng)死亡,應(yīng)當(dāng)彈出對話框提示死亡,輸出得分,結(jié)束游戲。在蛇死亡后,要使用無色的畫刷將死亡的蛇身和畫面中的食物“擦除”,獲取蛇與食物的最終坐標利用循環(huán)結(jié)構(gòu)便可做到。代碼如下:if(snake.life=1)KillTimer(hWnd,1);/游戲結(jié)束,蛇和食物消失hpen=CreatePen(PS_SOLID,1,RGB(255,255,255);hbru=CreateSolidBrush(RGB(255,255,255);hpenold=(HPEN)

29、SelectObject(hdc,hpen);hbruold=(HBRUSH)SelectObject(hdc,hbru);for(i=0;i<snake.node;i+)/擦除蛇身Rectangle(hdc,snake.xi,snake.yi,snake.xi+10,snake.yi-10);Rectangle(hdc,food.x,food.y,food.x+10,food.y-10);/擦除食物SelectObject(hdc,hpenold);SelectObject(hdc,hbruold); 3.3.3消息窗口的彈出貪吃蛇游戲是一個計算機與用戶交互的游戲,當(dāng)然也就少不了稍息框

30、的彈出設(shè)置了。這一部分需要考慮到消息框在什么時候彈出,彈出后根據(jù)不同的用戶的選擇,程序該怎么運行等問題。圖開始消息框當(dāng)用戶進入游戲后,便彈出該消息框(圖5),選擇“確定”按鈕后,游戲開始,食物出現(xiàn),蛇通過Sleep()函數(shù)延遲1秒后開始運動。代碼如下:if(score=0)MessageBox(hWnd," 開始游戲!","貪吃蛇",MB_ICONINFORMATION);SetTimer(hWnd,1,500,NULL);Sleep(1000);關(guān)卡消息框圖6為了增加游戲的趣味性和游戲難度,我給程序添加了關(guān)卡模塊。每一關(guān)中

31、需要吃的食物,蛇的顏色和蛇移動的速度都會不同。當(dāng)玩家的分數(shù)到達下一關(guān)卡的標準時,彈出消息框供玩家選擇是否開始下一關(guān)(圖6)。當(dāng)玩家選擇“是”時,開始下一關(guān),蛇變顏色,速度加快。當(dāng)玩家選擇“否”時,退出游戲。代碼如下:if(score%50=0&&score/50=1)KillTimer(hWnd,1);if(IDYES=MessageBox(hWnd," 開始第二關(guān)!","貪吃蛇",MB_YESNO|MB_ICONINFORMATION) )SetTimer(hWnd,1,400,NULL);Sleep(1000);elseRelease

32、DC(hWnd,hdc);SendMessageW(hWnd,WM_DESTROY,NULL,NULL);結(jié)束消息框當(dāng)蛇碰到自身或者墻壁時,蛇死亡,snake.life=1,此時彈出消息框(圖7),詢問是否退出游戲,用戶選擇“是”,退出程序,用戶選擇“否”,則在畫面上顯示用戶的最終得分,需要用戶關(guān)閉窗口。圖7代碼如下:if(snake.life=1)KillTimer(hWnd,1);if(IDYES=MessageBox(hWnd," 你要退出游戲嗎?","貪吃蛇",MB_YESNO|MB_ICONINFORMATION)ReleaseD

33、C(hWnd,hdc);SendMessageW(hWnd,WM_DESTROY,NULL,NULL);elsehpen=CreatePen(PS_SOLID,1,RGB(255,255,255);/創(chuàng)建一只無色的筆hpenold=(HPEN)SelectObject(hdc,hpen);/把無色的筆選進畫板hbru=CreateSolidBrush(RGB(255,255,255);/創(chuàng)建一支無色的畫刷hbruold=(HBRUSH)SelectObject(hdc,hbru);/把無色的畫刷選進畫板for(i=1;i<snake.node;i+)Rectangle(hdc,snake

34、.xi,snake.yi,snake.xi+10,snake.yi-10);/用無色的筆繪制蛇Rectangle(hdc,food.x,food.y,food.x+10,food.y-10);/用無色的筆繪制食物SelectObject(hdc,hpenold);SelectObject(hdc,hbruold);char chover20;sprintf(chover,"您的分數(shù)是:%d",score);SetBkColor(hdc,RGB(255,255,255);TextOut(hdc,290,230,chover,strlen(chover);3.3.4游戲音效當(dāng)開

35、始游戲時,程序會自動播放進入游戲的歡迎音樂,當(dāng)蛇吃到食物是,會發(fā)出吞咽的聲音,當(dāng)一關(guān)結(jié)束時,播放鼓掌祝賀的聲音,當(dāng)下一關(guān)開始時,播放歡呼的聲音,當(dāng)蛇死亡時,播放蛇死亡嗚咽的聲音。#include "mmsystem.h"/導(dǎo)入聲音頭文件#pragma comment(lib,"winmm.lib")/導(dǎo)入聲音頭文件庫PlaySound("start.wav",NULL,SND_FILENAME|SND_ASYNC);/開始音效if(snake.x0=food.x&&snake.y0=food.y)PlaySound(&

36、quot;eat.wav",NULL,SND_FILENAME|SND_ASYNC);/吃到食物后的音效if(score%50=0&&score/50=1)PlaySound("zhangsheng.wav",NULL,SND_FILENAME|SND_ASYNC);/掌聲音效KillTimer(hWnd,1);if(IDYES=MessageBox(hWnd," 開始第二關(guān)!","貪吃蛇",MB_YESNO|MB_ICONINFORMATION) )SetTimer(hWnd,1,400,NULL);Pla

37、ySound("koushao.wav",NULL,SND_FILENAME|SND_ASYNC);/歡呼音效Sleep(1000);這些聲音的播放都是在合適的位置,使用包含在頭文件mmsystem.h中的PlaySound函數(shù)。只要在合適的位置設(shè)定判斷語句添加該函數(shù),就能在需要的時刻播放需要的音效。代碼如下:if(snake.x0<60|snake.x0>590|snake.y0<60|snake.y0>450)/蛇碰到墻壁snake.life=1;/蛇死亡PlaySound("dead.wav",NULL,SND_FILENA

38、ME|SND_ASYNC);/蛇死亡音效for(i=3;i<snake.node;i+)/從蛇的第四節(jié)開始判斷蛇是否撞到自己了if(snake.xi=snake.x0&&snake.yi=snake.y0)snake.life=1;PlaySound("dead.wav",NULL,SND_FILENAME|SND_ASYNC);/蛇死亡音效第四章 結(jié)果與討論4.1程序運行程序開始運行后會進入游戲界面,彈出開始消息框,玩家點擊確定后,游戲開始。開始游戲了,小蛇在玩家的控制下運動,蛇每吃一個食物,出現(xiàn)音效,蛇身增長一節(jié),分數(shù)相應(yīng)的加10分,在右上角的分數(shù)

39、框中顯示得分。當(dāng)分數(shù)達到下一關(guān)要求時,播放掌聲,彈出下一關(guān)的消息框,玩家選擇“是”后,播放歡呼聲,蛇身和食物的顏色改變,蛇運動延遲一秒,然后開始運動,在得分的下面一行顯示當(dāng)前的關(guān)數(shù)。顏色的改變預(yù)示著游戲的難度加大。當(dāng)貪吃蛇由于“貪吃”而死亡是,播放死亡音效,彈出退出游戲的消息框,玩家選擇“是”則直接退出游戲界面,選擇“否”則在窗口中間顯示玩家的最終得分。如果不太會玩貪吃蛇這款游戲,那么可以參考窗口右下方的操作說明。4.2對源程序的改進ü 優(yōu)化了界面的圖像,使蛇身,墻面等更形象ü 加強了消息的處理,便于用戶的操作ü 增加了闖關(guān)功能,使游戲更具有趣味性ü 增

40、添了游戲音效,試游戲更富有動感4.3錯誤調(diào)試與分析4.3.1關(guān)于窗口的重畫問題在測試的過程中,我發(fā)現(xiàn),在游戲運行時彈出消息框被移動后,原來的蛇消失,繼續(xù)彈出很多開始消息框,游戲便重新開始,或者是當(dāng)屏幕有其他除蛇,食物,分數(shù)和關(guān)卡以外的變動時,也會出現(xiàn)上述現(xiàn)象。我百思不得其解,費勁了功夫?qū)ふ移湓?,通過查閱了無數(shù)的資料,才知道了窗口中圖案的改變其實是頻率很高的窗口重畫。我編寫的程序,當(dāng)非程序編寫的窗口圖像變化時,窗口便不能重畫,于是出現(xiàn)了上面的原因。但是因為沒有系統(tǒng)的學(xué)習(xí)過Windows程序設(shè)計,而且只有一周的時間去完成這個程序,我沒有能有效的解決這個錯誤。但幸運的是,只要不去挪動窗口和消息框,

41、屏幕也不會閃現(xiàn)其他的內(nèi)容,那么游戲就可以在用戶的操作下順利的進行。4.3.2關(guān)于雙音軌的問題在設(shè)計之初,我的想法是給游戲加上背景音樂,給玩家在玩游戲的過程中帶來一些聽覺上的享受,再加之以游戲的其他音效。但是若用PlaySound()函數(shù),當(dāng)其他音效播放的時候,背景音樂就會停止。我也嘗試了用其他的方法來實現(xiàn)這個功能,但都以失敗告終。資料和教程中說可以用雙線程或者是使用一些控件來實現(xiàn)這個功能,但同樣因為時間關(guān)系和我的編程能力有限,最終放棄了這一想法。4.3.3程序的穩(wěn)定性若是除過第一個問題,總的來說,游戲還是穩(wěn)定的,沒有再出現(xiàn)什么意外情況。經(jīng)過多次的測試,我都可以順利的通過所有關(guān)卡,這一點還是振奮

42、人心的,畢竟花了這么多天的心血,能制作出一款兒時經(jīng)常玩的游戲也讓我心潮澎湃。4.4課程設(shè)計心得與體會通過理論與實踐的完美結(jié)合,我的貪吃蛇游戲終于編制完成了,本次C+課程設(shè)計也可以畫上句號了。像貪吃蛇這樣的簡單的游戲,就自然成了我們程序設(shè)計課程的首選。因為其界面簡單,操作、玩法一目了然,所以編寫起來就不會非常困難。雖然美中不足,程序有很多漏洞,但是值得驕傲的是,整個游戲的編寫是通過大量的閱讀資料,自己親手,并且依靠自己的智慧獨立完成的。在編寫游戲過程中,遇到了許多難題,例如,蛇的頭部與食物的檢測問題, 蛇的移動與顯示問題,蛇的轉(zhuǎn)向問題,食物的隨機生成問題,關(guān)卡的設(shè)置問題等等,這些個難題擺在面前,

43、讓人實在有些招架不住。經(jīng)過查閱大量的文獻資料,閱讀相關(guān)的書籍,最后就決定了采用分治算法的思想來對擺在面前的問題一一擊破。在解決的是蛇的移動與顯示問題的時候,通過大量的研究、實驗與調(diào)試,試驗過多種移動與顯示的方式,最后選定了一種簡單易用的算法。程序中會遇到使用之前沒有遇見過功能的函數(shù),我便使用強大的網(wǎng)絡(luò),并且通過查詢微軟的MSDN幫助文件,解決了不少問題。仿佛是撥了一層云,又見一層云,但是日光也越來越閃耀了,最終看到了太陽,取得了成功。雖然通過自己的努力,解決了很多從前沒有遇到的問題,但依舊有無數(shù)的難題擺在我面前,重重疊疊的大山阻礙著我前進的道路。山高人為峰,我一定不會懼怕擺在前面的困難,不斷努

44、力奮斗,爭取看到更多的陽光。這次的課程設(shè)計,讓我受益匪淺。不僅為自己揭開了游戲程序神秘的面紗,而且在實際的程序編寫與調(diào)試過程中,成長了不少,實戰(zhàn)的能力提高了很多,也讓我明白了自己還有很大的提高空間。雖然以后不再學(xué)習(xí)程序設(shè)計這門課了,但這次課程設(shè)計確實激發(fā)了我編程的興趣,我以后一定還會努力鉆研,爭取往更深更透的方向發(fā)展。萬丈高樓平地起,能夠編寫復(fù)雜的程序都是在編寫過簡單的程序的基礎(chǔ)上演變過來的能力。目前的程序漏洞確實還是很多,但編成之后的成就感還是會油然而生,成為我向程序設(shè)計之路成功邁出的第一步,同時,對于我的VC+的應(yīng)用水平也有很大的提高,用起來會更加嫻熟、得心應(yīng)手。從易到難這是一個準則,總之

45、,貪吃蛇小游戲的研究會對增長程序閱讀能力、程序編寫能力等起到了意想不到的作用。在以后漫漫的研究學(xué)習(xí)道路上,我還有很遠的路要走,迎接我的是又一個嚴峻的挑戰(zhàn)!附錄#include "stdafx.h"#include "resource.h"#include "time.h"#include "stdio.h"#include "windows.h"#include "mmsystem.h"/導(dǎo)入聲音頭文件#pragma comment(lib,"winmm.lib&q

46、uot;)/導(dǎo)入聲音頭文件庫#define MAX_LOADSTRING 100#define N 200class Foodpublic:int x;/食物的橫坐標int y;/食物的縱坐標int yes;/判斷是否要出現(xiàn)食物的變量food;/食物的類class Snakepublic:int xN;int yN;int node;/蛇的節(jié)數(shù)int direction;/蛇的方向int life;/蛇的生命,0活著,1死亡snake;/蛇的類/ Global Variables:HINSTANCE hInst;/ current instanceTCHAR szTitleMAX_LOADST

47、RING;/ The title bar textTCHAR szWindowClassMAX_LOADSTRING;/ The title bar text/ Foward declarations of functions included in this code module:ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACKAbout(HWND, UIN

48、T, WPARAM, LPARAM);LRESULT CALLBACKHero(HWND, UINT, WPARAM, LPARAM);/程序的入口int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) / TODO: Place code here.MSG msg;/消息結(jié)構(gòu)bool hold = false;HACCEL hAccelTable;/ Initialize global stringsLoadString(hInstance, IDS_A

49、PP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_WINSNAKE, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);/ Perform application initialization:if (!InitInstance (hInstance, nCmdShow) return FALSE;hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINSNAKE);/ Main message l

50、oop:while(GetMessage(&msg, NULL, 0, 0) TranslateMessage(&msg); if(msg.message = WM_KEYDOWN && !hold) hold = true; DispatchMessage(&msg); else if(msg.message = WM_KEYDOWN) ;/ 忽略多余的按鍵 else if(msg.message = WM_KEYUP) hold = false; DispatchMessage(&msg); else DispatchMessage(&

51、;msg); return msg.wParam;ATOM MyRegisterClass(HINSTANCE hInstance)WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX); wcex.style= CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc= (WNDPROC)WndProc;wcex.cbClsExtra= 0;wcex.cbWndExtra= 0;wcex.hInstance= hInstance;/當(dāng)前進程對象實例句柄wcex.hIcon= LoadIcon(hInstance, (LPCTSTR)IDI

溫馨提示

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

最新文檔

評論

0/150

提交評論