c++俄羅斯方塊課程設(shè)計_第1頁
已閱讀1頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p>  華科學院計算機科學與技術(shù)系</p><p>  《軟件工程課程設(shè)計》報告</p><p>  ----俄羅斯方塊游戲</p><p>  (2011/2012學年 第一學期)</p><p>  學生姓名: </p><p>  專業(yè)班級: 信息管理1

2、02202H</p><p>  學生學號: </p><p>  指導(dǎo)教師: </p><p>  2011年 12 月 30 日</p><p><b>  目錄</b></p><p><b>  第一章 系統(tǒng)概

3、述</b></p><p>  1 . 1 課程設(shè)計的目的和要求------------------------------------------1</p><p>  1 . 2 課程設(shè)計任務(wù)內(nèi)容----------------------------------------------1</p><p>  1 . 3 關(guān)于編譯軟件-----

4、---------------------------------------------1</p><p>  第二章 詳細設(shè)計說明--------------------------------------------------2</p><p>  2 . 1 程序設(shè)計-------------------------------------------------------2&

5、lt;/p><p>  2 .1 .1 主要功能設(shè)計-------------------------------------------2</p><p>  2 .1 .2 程序流程圖---------------------------------------------2</p><p>  2 . 2 參數(shù)說明-------------------------

6、------------------------------3</p><p>  2 .2 .1 類設(shè)計聲明(view類)----------------------------------3</p><p>  2 .2 .2 類設(shè)計聲明(squar類)---------------------------------4</p><p>  2 . 3 函數(shù)功

7、能說明---------------------------------------------------5</p><p>  2 .3 .1 游戲界面-----------------------------------------------5</p><p>  2 .3 .2 生成方塊-----------------------------------------------

8、5</p><p>  2 .3 .3 方塊變形-----------------------------------------------6</p><p>  2 .3 .4 方塊顯示-----------------------------------------------6</p><p>  2 .3 .5 障礙判斷------------------

9、-----------------------------7</p><p>  2 .3 .6 消行計分-----------------------------------------------7</p><p>  2 .3 .7 暫停退出-----------------------------------------------7</p><p>  2

10、 . 4 程序調(diào)試-------------------------------------------------------9</p><p>  2 . 5 軟件使用說明---------------------------------------------------9</p><p>  第三章 心得與體會------------------------------------

11、----------------10</p><p>  附錄1---------------------------------------------------------------11</p><p>  附錄2---------------------------------------------------------------11</p><p>

12、;<b>  第一章 系統(tǒng)概述</b></p><p>  1.1課程設(shè)計的目的和要求</p><p>  俄羅斯是家喻戶曉的益智小游戲,選擇這個題目一是為了將自己的所學知識加以運用,二是俄羅斯方塊是我第一個接觸到的游戲,它的實現(xiàn)方法也吸引著我。我希望通過探索實踐去實現(xiàn)它,在這次學習中從實踐和實際的項目中提高自己的編程能力。因此我選定了這個題目。</p>

13、<p>  C++課程所學的概念、理論和方法,按照C++程序設(shè)計的基本步驟,設(shè)計出一個適當規(guī)模的程序來實現(xiàn)設(shè)計課程內(nèi)容中的全部功能;設(shè)計主控模塊程序.對給出的程序源代碼要給出各部分的詳細注釋.自己根據(jù)能力及需要添加相應(yīng)功能模塊,增強模擬系統(tǒng)功能。</p><p>  1.2課程設(shè)計任務(wù)內(nèi)容</p><p>  利用Microsoft Visual C++編寫一個文本窗口下的俄羅

14、斯方塊游戲。</p><p><b>  要求:</b></p><p> ?。?)利用類和多文件編寫。</p><p> ?。?)能夠記錄游戲得分和等級。</p><p> ?。?)可暫停/繼續(xù)游戲,使玩家在不愿游戲時退出。</p><p> ?。?)信息提示時顯示顏色變化。</p>

15、<p><b>  1.3關(guān)于編譯軟件</b></p><p>  本程序采用Microsoft Visual C++6.0的英文版本進行編譯。VisualC++6.0是Microsoft公司推出的基于Windows操作系統(tǒng)的可視化C++編程工具,盡管Microsoft公司推出了.NET平臺的集成開發(fā)環(huán)境,但由于其良好的界面和可操作性,加上支持標準C/C++規(guī)范,但仍有相當多的

16、編程人員使用VisualC++6.0進行應(yīng)用系統(tǒng)的開發(fā)。</p><p>  關(guān)于穩(wěn)定性,經(jīng)測試,本程序可以在windows操作系統(tǒng)中穩(wěn)定運行,較為穩(wěn)定。</p><p>  第二章 詳細設(shè)計說明</p><p><b>  2.1程序設(shè)計</b></p><p>  2.1.1主要功能設(shè)計</p><

17、;p>  根據(jù)分析,俄羅斯方塊這個程序一共要實現(xiàn)如下幾個功能,開始游戲、游戲的暫停\繼續(xù)、游戲控制和退出游戲。其中游戲控制最為主要和重要,它控制著整個游戲的畫面和有關(guān)數(shù)據(jù)的操作,是游戲的核心部分。暫停和退出功能做成一體,在退出的提示下不做任何操作即可實現(xiàn)暫停的功能。程序結(jié)構(gòu)如圖2.1所示。 </p><p><b>  圖2.1 </b></p><p>  

18、2.1.2 程序流程圖</p><p>  根據(jù)分析后的程序結(jié)構(gòu)圖設(shè)計出相應(yīng)的流程圖。俄羅斯方塊的內(nèi)容主要包括游戲開始,畫背景和邊框,顯示分數(shù)等級和下一個方塊的預(yù)覽圖;根據(jù)速度沒隔一定時間方塊自動下落,當有按鍵操作時,根據(jù)相應(yīng)按鍵執(zhí)行動作,每次動作前要判斷是否動作可以執(zhí)行。下落方塊滿一行時,消去該行,根據(jù)消去行數(shù)得到相應(yīng)分數(shù)。分數(shù)達到一定程度,等級提升,速度加快。同時可以響應(yīng)Esc按鍵,提示是否退出程序。如圖2.

19、2所示。</p><p><b>  圖2.2 </b></p><p><b>  2.2參數(shù)說明</b></p><p>  根據(jù)程序的結(jié)構(gòu),將俄羅斯方塊需要實現(xiàn)的功能細化為相應(yīng)的類成員函數(shù)。程序有兩個類,一個view類,用于背景相關(guān)操作。一個squar類,用于方塊相關(guān)操作。</p><p> 

20、 2.2.1類設(shè)計聲明(view類)</p><p>  class view</p><p><b>  {</b></p><p><b>  public:</b></p><p>  view();//類的缺省構(gòu)造函數(shù)</p><p>  int ge

21、tbgdata(int,int);//取得數(shù)組x,y點的數(shù)據(jù)值</p><p>  void scoreadd(int);//得分增加,根據(jù)消去行數(shù)</p><p>  void scorereset();//得分清零,用于升級后</p><p>  void levelup();//等級提升,當分數(shù)達到規(guī)定值后執(zhí)行&

22、lt;/p><p>  int gameover();//游戲結(jié)束</p><p>  void rowdelete();//消除滿行</p><p>  void previewset(int (*p)[4]);//設(shè)置預(yù)覽方塊的形狀數(shù)據(jù)</p><p>  void previewreset();//

23、預(yù)覽方塊數(shù)據(jù)清零</p><p>  void setdata(int (*)[2]);//設(shè)置主游戲區(qū)數(shù)據(jù)值</p><p>  void datareset();//主游戲區(qū)數(shù)據(jù)清零</p><p>  void drawpreview();//顯示預(yù)覽方塊</p><p><b>  priva

24、te:</b></p><p>  int data[25][26];//主游戲區(qū)數(shù)組</p><p>  int preview[4][4];//預(yù)覽方塊數(shù)組</p><p>  int rowsdelete;//每次消除行數(shù)變量</p><p>  int score;//

25、得分變量</p><p>  int scorelevel;//升級規(guī)定值變量</p><p>  int level;//等級變量</p><p>  bool overflag;//結(jié)束標記變量</p><p>  void scorelevelup();//升級規(guī)定值提升</p

26、><p><b>  };</b></p><p>  2.2.2類設(shè)計聲明(squar類)</p><p>  class view;//先向引用聲明</p><p>  class squar</p><p><b>  {</b></p>&l

27、t;p><b>  public:</b></p><p>  squar();//類的缺省構(gòu)造函數(shù)</p><p>  squar(squar &);//拷貝構(gòu)造函數(shù)</p><p>  friend void cursor(int,int);//友元函數(shù) 控制光標位置</p>

28、<p>  void getcursor(int &,int &);//取得位置記錄坐標</p><p>  void make();//隨機產(chǎn)生一個方塊</p><p>  void getmake(int (*p)[4]);//取得方塊數(shù)據(jù)值</p><p>  void draw();//顯

29、示主方塊</p><p>  void drop(view &);//方塊下落</p><p>  void change();//方塊變形</p><p>  int meet(int);//判斷方塊周圍是否有障礙</p><p>  void torecord(int (*)[2]);

30、//傳送需要記錄的數(shù)據(jù)</p><p>  void reset();//方塊數(shù)組清零</p><p>  int moveflag;//方塊運動標記變量</p><p><b>  private:</b></p><p>  void move();//方塊運動</

31、p><p>  int shape[4][4];//方塊形狀數(shù)據(jù)</p><p>  int x,y;//坐標</p><p>  int shapeindex;//方塊形狀序號</p><p>  int changeindex;//變形序號變量</p><p>  i

32、nt speed;//下落速度變量</p><p><b>  };</b></p><p><b>  2.3函數(shù)功能說明</b></p><p><b>  2.3.1游戲界面</b></p><p>  俄羅斯方塊的游戲界面包括游戲區(qū)域邊框、下落方塊繪制、

33、右部計分和預(yù)覽圖顯示等。</p><p>  游戲區(qū)域邊框的繪制比較簡單,循環(huán)中確定光標的位置輸出特定字符,即可完成邊框繪制。游戲區(qū)方塊的繪制,循環(huán)從數(shù)據(jù)數(shù)組中依次讀出數(shù)據(jù),根據(jù)讀到的數(shù)據(jù)顯示“□”,最后組成方塊的形狀,完成方塊的繪制。計分和預(yù)覽圖部分先畫出一個矩形區(qū)域,然后控制光標在其中顯示分數(shù)、等級、預(yù)覽圖和提示信息。</p><p><b>  2.3.2生成方塊</

34、b></p><p>  本程序中生成的方塊有六種形狀,每一種方塊以shapeindex標記,在程序運行生成方塊時,調(diào)用shapeindex=rand()%5+1;語句,確定當前要顯示的是哪一個方塊形狀。而在實際運行中,第一次需要調(diào)用兩次生成方塊函數(shù)make(),將先產(chǎn)生的賦給游戲當前方塊,第二個賦給預(yù)覽圖方塊。以后每次產(chǎn)生一個方塊,把預(yù)覽方塊賦給當前方塊,把新產(chǎn)生的賦給預(yù)覽方塊。具體如圖2.3所示。<

35、;/p><p><b>  圖2.3</b></p><p><b>  2.3.3方塊變形</b></p><p>  俄羅斯方塊的特點就在于通過方塊的變形拼滿整行來消去該行方塊從而使游戲可以繼續(xù)下去,很難想象不能變形的俄羅斯方塊是什么樣子。而變形的過程就是根據(jù)當前方塊形狀改變方塊的相對位置,這樣就可以改變方塊的形狀了。在程

36、序中每當按下Up鍵,程序判斷可以變形后,根據(jù)當前方塊的形狀序號shapeindex和變化形狀序號changeindex調(diào)用相應(yīng)的方塊數(shù)值賦給draw()函數(shù),通過刷新重畫就可以顯示變化后的方塊了。具體形狀變化如圖2.4所示。</p><p><b>  2.3.4方塊顯示</b></p><p>  以上方塊的操作都是數(shù)據(jù)層面的操作,而真正要在游戲窗口中看到數(shù)據(jù)的變化

37、,還必須把方塊不斷的繪制出來。這就是draw()函數(shù)的作用。把當前運動的方塊對應(yīng)節(jié)點存儲在一個4*4數(shù)組里,變形和生成方塊的過程就是更新該數(shù)組數(shù)據(jù)的過程。然后在draw()函數(shù)里檢測數(shù)組的各個值,并控制光標跳到一定位置,畫出“□”組成方塊。具體方塊對應(yīng)數(shù)組數(shù)值關(guān)系如圖2.5所示。</p><p><b>  圖2.4</b></p><p><b>  2.

38、3.5障礙判斷</b></p><p>  障礙判斷,就是在方塊運動中或者變形中判斷周圍是否有障礙阻礙下落、移位、變形。當方塊下落遇到下面有方塊或者到達下邊界則應(yīng)停止下落并記錄數(shù)據(jù),存入背景數(shù)據(jù)數(shù)組。變形時應(yīng)判斷這個變形是否可以進行,如果有障礙則不能變形。例如當方塊達到右邊界,而若變形則會越過邊界,那么這個變形的命令是不應(yīng)執(zhí)行的。所有這些判斷都由meet()函數(shù)進行,根據(jù)是否有障礙返回1或0,再由其他

39、函數(shù)接收執(zhí)行相應(yīng)操作。</p><p><b>  2.3.6消行計分</b></p><p>  游戲玩家拼滿一行后,程序消去滿行,并計分。中當一個方塊下落停止后,程序檢查方塊是否充滿了游戲區(qū)域,如果是結(jié)束游戲。不是,則判斷是否構(gòu)成消行條件,從下落方塊的最低點依次向上檢查是否可以消行,根據(jù)消去行數(shù)分數(shù)增加。分數(shù)達到一定程度,等級提升,速度加快。如圖2.6所示。<

40、;/p><p><b>  2.3.7暫停退出</b></p><p>  游戲的友好性在于能考慮用戶的需要,隨時可以暫停/繼續(xù)游戲,在不愿繼續(xù)游戲時退出游戲。本程序可以在用戶需要的時候響應(yīng)Esc按鍵,提示是否退出游戲,如果不做選擇即可暫停游戲,等待選擇。界面如圖2.7所示。</p><p><b>  圖2.5</b><

41、;/p><p><b>  圖2.6</b></p><p><b>  圖2.7</b></p><p><b>  2.4 程序調(diào)試</b></p><p>  經(jīng)過調(diào)試和修改,程序完全實現(xiàn)設(shè)計要求,成功模擬了俄羅斯方塊的運行過程和游戲效果,只是界面略微簡陋,但已從程序?qū)用嫔蠈?/p>

42、現(xiàn)了游戲,達到了這次實訓(xùn)的要求和目的。程序正常生成方塊,根據(jù)速度值每隔一定時間自動下落,如有操作按鍵按下,根據(jù)按鍵實現(xiàn)位移和變形。當方塊滿一行后,可以消除該行,同時記錄分數(shù)和等級。按下Esc鍵紅色提示信息正常顯示,可以響應(yīng)Y,N鍵決定是否退出游戲。</p><p>  2.5 軟件使用說明</p><p>  打開俄羅斯方塊游戲后,通過控制方向區(qū)域的“上”、“下”、“左”、“右”來控制,“

43、上”鍵代表變形轉(zhuǎn)換,“下”、“左”、“右”均代表方向鍵,而“空格”代表“沉底”,</p><p>  也可以通過“W”、“S”、“A”、“D”來控制方向;“esc”代表退出游戲鍵。若想暫停游戲,也可通過“esc”鍵,當初來詢問框是,可不做選擇,則可達到暫停的效果。</p><p><b>  第三章 總結(jié)與體會</b></p><p>  通過

44、這次課程設(shè)計,我收獲了很多。首先把所學知識加以利用和鞏固,其次在實踐中遇到問題去探索和學習,更增加了新知識。在程序設(shè)計編寫過程中兩個類的數(shù)據(jù)交換是個比較麻煩的過程,這個類的定義過程中要用到另一個類做參數(shù)類型,而在后一個類中亦需要第一個類做參數(shù)類型,出現(xiàn)了互相調(diào)用的情況。</p><p>  編譯提示未定義,只好在兩個類外定義函數(shù)負責兩個類函數(shù)的數(shù)據(jù)交換。實踐證明達到了預(yù)期的目的,積累了經(jīng)驗。由于程序是用文本窗口模

45、擬的圖形,界面比較簡陋,如果使用MFC用C++來實現(xiàn),那么界面將會非常好,只是由于所學知識有限,只有下一步去探索了。</p><p>  通過這次的學習設(shè)計,我發(fā)現(xiàn)我還有許許多多的不足的地方,比如c++的程序設(shè)計,源代碼的書寫等等,剛開始我發(fā)現(xiàn)我的問題后,十分緊張,感覺很絕望,沒有別人的幫助,自己動手設(shè)計曾經(jīng)自己想都沒想過的東西,雖然很興奮,但想想自己無從下手,原來的興奮勁一下子都沒了,很忙然。但是,通過與王老師

46、的交流,經(jīng)過老師的耐心講解,我慢慢感到希望又重生了,于是我通過上網(wǎng)查找資料,進圖書館查找書籍等,終于知道了俄羅斯方塊游戲的設(shè)計概念,終于知道了設(shè)計的方法,于是,漸漸地我的游戲設(shè)計理念誕生了。</p><p>  通過幾個禮拜的設(shè)計,我的游戲漸漸初見成效了,當我把回車鍵摁下的一剎那,我十分激動,眼前的既熟悉又陌生的游戲出現(xiàn)在了我的面前,看著自己設(shè)計的童年時代經(jīng)常玩的游戲,我感慨萬千。通過這次設(shè)計,我學會了很多東西,

47、例如通過網(wǎng)絡(luò)資料來尋求幫助,自己改正錯誤,加強了我自己的自己動手能力,對今后的學習和生活有很大的幫助,有助于以后的課程設(shè)計順利完成。</p><p><b>  附錄1 參考文獻</b></p><p> ?。?]段鋼 編著 加密與解密(第三版).電子工業(yè)出版社.2009年8月</p><p>  [2]趙樹升 趙韶平.Windows信息安全原

48、理與實現(xiàn).北京:清華大學出版社.2004年</p><p>  [3]楊永國.Visual C++ 6.0實用教程.北京:清華大學出版社.2004年</p><p> ?。?]唐俊明.Visual C++ 6.0 編程實例與技巧.北京:高等教育出版,2002年</p><p> ?。?]潘錦平.軟件系統(tǒng)開發(fā)技術(shù).西安:西安電子科技大學出版社, 1997年 </

49、p><p><b>  附錄2 源程序代碼</b></p><p>  #include <graphics.h></p><p>  #include <conio.h></p><p>  #include <time.h></p><p>  ////////

50、/////////////////////////////////////</p><p>  // 定義常量、枚舉量、結(jié)構(gòu)體、全局變量</p><p>  /////////////////////////////////////////////</p><p>  #define WIDTH 10 // 游戲區(qū)寬度</p><p>  

51、#define HEIGHT 22 // 游戲區(qū)高度</p><p>  #define SIZE 20 // 每個游戲區(qū)單位的實際像素</p><p><b>  // 定義操作類型</b></p><p><b>  enum CMD</b></p><p><b>  {&l

52、t;/b></p><p>  CMD_ROTATE, // 方塊旋轉(zhuǎn)</p><p>  CMD_LEFT, CMD_RIGHT, CMD_DOWN, // 方塊左、右、下移動</p><p>  CMD_SINK, // 方塊沉底</p><p>  CMD_QUIT // 退出游戲</p>

53、;<p><b>  };</b></p><p>  // 定義繪制方塊的方法</p><p><b>  enum DRAW</b></p><p><b>  {</b></p><p>  SHOW, // 顯示方塊</p><p>

54、;  HIDE, // 隱藏方塊</p><p>  FIX // 固定方塊</p><p><b>  };</b></p><p>  // 定義七種俄羅斯方塊</p><p>  struct BLOCK</p><p><b>  {</b></p>

55、<p>  WORD dir[4]; // 方塊的四個旋轉(zhuǎn)狀態(tài)</p><p>  COLORREF color; // 方塊的顏色</p><p>  } g_Blocks[7] = { {0x0F00, 0x4444, 0x0F00, 0x4444, RED}, // I</p><p>  {0x0660, 0x0660, 0x0660

56、, 0x0660, BLUE}, // 口</p><p>  {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, // L</p><p>  {0x2260, 0x0E20, 0x0644, 0x0470, YELLOW}, // 反L</p><p>  {0x0C60, 0x2640, 0x0C60, 0x2640

57、, CYAN}, // Z</p><p>  {0x0360, 0x4620, 0x0360, 0x4620, GREEN}, // 反Z</p><p>  {0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN}}; // T</p><p>  // 定義當前方塊、下一個方塊的信息</p><p>  s

58、truct BLOCKINFO</p><p><b>  {</b></p><p>  byte id; // 方塊 ID</p><p>  char x, y; // 方塊在游戲區(qū)中的坐標</p><p>  byte dir:2; // 方向</p><p>  } g_Cu

59、rBlock, g_NextBlock;</p><p><b>  // 定義游戲區(qū)</b></p><p>  BYTE g_World[WIDTH][HEIGHT] = {0};</p><p>  /////////////////////////////////////////////</p><p><

60、b>  // 函數(shù)聲明</b></p><p>  /////////////////////////////////////////////</p><p>  void Init(); // 初始化游戲</p><p>  void Quit(); // 退出游戲</p><p

61、>  void NewGame(); // 開始新游戲</p><p>  void GameOver(); // 結(jié)束游戲</p><p>  CMD GetCmd(); // 獲取控制命令</p><p>  void DispatchCmd(CMD _cmd); // 分發(fā)

62、控制命令</p><p>  void NewBlock(); // 生成新的方塊</p><p>  bool CheckBlock(BLOCKINFO _block); // 檢測指定方塊是否可以放下</p><p>  void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW);

63、// 畫方塊</p><p>  void OnRotate(); // 旋轉(zhuǎn)方塊</p><p>  void OnLeft(); // 左移方塊</p><p>  void OnRight(); // 右移方塊</p><p>  void OnDown();

64、 // 下移方塊</p><p>  void OnSink(); // 沉底方塊</p><p>  /////////////////////////////////////////////</p><p><b>  // 函數(shù)定義</b></p><p>  ///////////////

65、//////////////////////////////</p><p><b>  // 主函數(shù)</b></p><p>  void main()</p><p><b>  {</b></p><p><b>  Init();</b></p><

66、p><b>  CMD c;</b></p><p>  while(true)</p><p><b>  {</b></p><p>  c = GetCmd();</p><p>  DispatchCmd(c);</p><p>  // 按退出時,顯示對話框咨

67、詢用戶是否退出</p><p>  if (c == CMD_QUIT)</p><p><b>  {</b></p><p>  HWND wnd = GetHWnd();</p><p>  if (MessageBox(wnd, _T("您要退出游戲嗎?"), _T("提醒"

68、;), MB_OKCANCEL | MB_ICONQUESTION) == IDOK)</p><p><b>  Quit();</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b>

69、;</p><p><b>  // 初始化游戲</b></p><p>  void Init()</p><p><b>  {</b></p><p>  initgraph(640, 480);</p><p>  srand((unsigned)time(NULL)

70、);</p><p><b>  // 顯示操作說明</b></p><p>  setfont(14, 0, _T("宋體"));</p><p>  outtextxy(20, 330, _T("操作說明"));</p><p>  outtextxy(20, 350, _T(

71、"上:旋轉(zhuǎn)"));</p><p>  outtextxy(20, 370, _T("左:左移"));</p><p>  outtextxy(20, 390, _T("右:右移"));</p><p>  outtextxy(20, 410, _T("下:下移"));</p>

72、;<p>  outtextxy(20, 430, _T("空格:沉底"));</p><p>  outtextxy(20, 450, _T("ESC:退出"));</p><p><b>  // 設(shè)置坐標原點</b></p><p>  setorigin(220, 20);</

73、p><p>  // 繪制游戲區(qū)邊界</p><p>  rectangle(-1, -1, WIDTH * SIZE, HEIGHT * SIZE);</p><p>  rectangle((WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE);</p><p><b> 

74、 // 開始新游戲</b></p><p>  NewGame();</p><p><b>  }</b></p><p><b>  // 退出游戲</b></p><p>  void Quit()</p><p><b>  {</b>

75、;</p><p>  closegraph();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  // 開始新游戲</b></p><p>  void NewGame()<

76、;/p><p><b>  {</b></p><p><b>  // 清空游戲區(qū)</b></p><p>  setfillstyle(BLACK);</p><p>  bar(0, 0, WIDTH * SIZE - 1, HEIGHT * SIZE - 1);</p><p

77、>  ZeroMemory(g_World, WIDTH * HEIGHT);</p><p><b>  / 生成下一個方塊</b></p><p>  g_NextBlock.id = rand() % 7;</p><p>  g_NextBlock.dir = rand() % 4;</p><p>  g

78、_NextBlock.x = WIDTH + 1;</p><p>  g_NextBlock.y = HEIGHT - 1;</p><p><b>  // 獲取新方塊</b></p><p>  NewBlock();</p><p><b>  }</b></p><p&

79、gt;<b>  // 結(jié)束游戲</b></p><p>  void GameOver()</p><p><b>  {</b></p><p>  HWND wnd = GetHWnd();</p><p>  if (MessageBox(wnd, _T("游戲結(jié)束。\n您想重新來

80、一局嗎?"), _T("游戲結(jié)束"), MB_YESNO | MB_ICONQUESTION) == IDYES)</p><p>  NewGame();</p><p><b>  else</b></p><p><b>  Quit();</b></p><p>

81、;<b>  }</b></p><p><b>  // 獲取控制命令</b></p><p>  DWORD m_oldtime;</p><p>  CMD GetCmd()</p><p><b>  {</b></p><p><b>

82、;  // 獲取控制值</b></p><p>  while(true)</p><p><b>  {</b></p><p>  // 如果超時,自動下落一格</p><p>  DWORD newtime = GetTickCount();</p><p>  if (newt

83、ime - m_oldtime >= 500)</p><p><b>  {</b></p><p>  m_oldtime = newtime;</p><p>  return CMD_DOWN;</p><p><b>  }</b></p><p>  //

84、如果有按鍵,返回按鍵對應(yīng)的功能</p><p>  if (kbhit())</p><p><b>  {</b></p><p>  switch(getch())</p><p><b>  {</b></p><p><b>  case 'w

85、9;:</b></p><p>  case 'W': return CMD_ROTATE;</p><p><b>  case 'a':</b></p><p>  case 'A': return CMD_LEFT;</p><p><b>  

86、case 'd':</b></p><p>  case 'D': return CMD_RIGHT;</p><p><b>  case 's':</b></p><p>  case 'S': return CMD_DOWN;</p><p&g

87、t;  case 27: return CMD_QUIT;</p><p>  case ' ': return CMD_SINK;</p><p><b>  case 0:</b></p><p>  case 0xE0:</p><p>  switch(getch())</p>&l

88、t;p><b>  {</b></p><p>  case 72: return CMD_ROTATE;</p><p>  case 75: return CMD_LEFT;</p><p>  case 77: return CMD_RIGHT;</p><p>  case 80: return CMD_D

89、OWN;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  // 延時 (降低 CPU 占用率)</p><p>  Sleep(20);</p>&

90、lt;p><b>  }</b></p><p><b>  }</b></p><p><b>  // 分發(fā)控制命令</b></p><p>  void DispatchCmd(CMD _cmd)</p><p><b>  {</b><

91、/p><p>  switch(_cmd)</p><p><b>  {</b></p><p>  case CMD_ROTATE: OnRotate(); break;</p><p>  case CMD_LEFT: OnLeft(); break;</p><p>  case C

92、MD_RIGHT: OnRight(); break;</p><p>  case CMD_DOWN: OnDown(); break;</p><p>  case CMD_SINK: OnSink(); break;</p><p>  case CMD_QUIT: break;</p><p><b>  }&

93、lt;/b></p><p><b>  }</b></p><p><b>  // 生成新的方塊</b></p><p>  void NewBlock()</p><p><b>  {</b></p><p>  g_CurBlock.id

94、 = g_NextBlock.id, g_NextBlock.id = rand() % 7;</p><p>  g_CurBlock.dir = g_NextBlock.dir, g_NextBlock.dir = rand() % 4;</p><p>  g_CurBlock.x = (WIDTH - 4) / 2;</p><p>  g_CurBl

95、ock.y = HEIGHT + 2;</p><p>  // 下移新方塊直到有局部顯示</p><p>  WORD c = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];</p><p>  while((c & 0xF) == 0)</p><p><b>  {</b

96、></p><p>  g_CurBlock.y--;</p><p><b>  c >>= 4;</b></p><p><b>  }</b></p><p><b>  // 繪制新方塊</b></p><p>  DrawBl

97、ock(g_CurBlock);</p><p>  // 繪制下一個方塊</p><p>  setfillstyle(BLACK);</p><p>  bar((WIDTH + 1) * SIZE, 0, (WIDTH + 5) * SIZE - 1, 4 * SIZE - 1);</p><p>  DrawBlock(g_NextB

98、lock);</p><p>  // 設(shè)置計時器,用于判斷自動下落</p><p>  m_oldtime = GetTickCount();</p><p><b>  }</b></p><p><b>  // 畫方塊</b></p><p>  void DrawB

99、lock(BLOCKINFO _block, DRAW _draw)</p><p><b>  {</b></p><p>  WORD b = g_Blocks[_block.id].dir[_block.dir];</p><p><b>  int x, y;</b></p><p>  i

100、nt color = BLACK;</p><p>  switch(_draw)</p><p><b>  {</b></p><p>  case SHOW: color = g_Blocks[_block.id].color; break;</p><p>  case HIDE: color = BLACK;

101、break;</p><p>  case FIX: color = g_Blocks[_block.id].color / 3; break;</p><p><b>  }</b></p><p>  setfillstyle(color);</p><p>  for(int i=0; i<16; i++)&

102、lt;/p><p><b>  {</b></p><p>  if (b & 0x8000)</p><p><b>  {</b></p><p>  x = _block.x + i % 4;</p><p>  y = _block.y - i / 4;</

103、p><p>  if (y < HEIGHT)</p><p><b>  {</b></p><p>  if (_draw != HIDE)</p><p>  bar3d(x * SIZE + 2, (HEIGHT - y - 1) * SIZE + 2, (x + 1) * SIZE - 4, (HEIGHT

104、- y) * SIZE - 4, 3, true);</p><p><b>  else</b></p><p>  bar(x * SIZE, (HEIGHT - y - 1) * SIZE, (x + 1) * SIZE - 1, (HEIGHT - y) * SIZE - 1);</p><p><b>  }</b&g

105、t;</p><p><b>  }</b></p><p><b>  b <<= 1;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  // 檢測指定方塊是

106、否可以放下</p><p>  bool CheckBlock(BLOCKINFO _block)</p><p><b>  {</b></p><p>  WORD b = g_Blocks[_block.id].dir[_block.dir];</p><p><b>  int x, y;</b&

107、gt;</p><p>  for(int i=0; i<16; i++)</p><p><b>  {</b></p><p>  if (b & 0x8000)</p><p><b>  {</b></p><p>  x = _block.x + i

108、% 4;</p><p>  y = _block.y - i / 4;</p><p>  if ((x < 0) || (x >= WIDTH) || (y < 0))</p><p>  return false;</p><p>  if ((y < HEIGHT) && (g_World[x]

109、[y]))</p><p>  return false;</p><p><b>  }</b></p><p><b>  b <<= 1;</b></p><p><b>  }</b></p><p>  return true;&l

110、t;/p><p><b>  }</b></p><p><b>  // 旋轉(zhuǎn)方塊</b></p><p>  void OnRotate()</p><p><b>  {</b></p><p>  // 獲取可以旋轉(zhuǎn)的 x 偏移量</p>

111、<p><b>  int dx;</b></p><p>  BLOCKINFO tmp = g_CurBlock;</p><p>  tmp.dir++; if (CheckBlock(tmp)) { dx = 0; goto rotate; }</p><p>  tmp.x = g_CurBlock

112、.x - 1; if (CheckBlock(tmp)) { dx = -1; goto rotate; }</p><p>  tmp.x = g_CurBlock.x + 1; if (CheckBlock(tmp)) { dx = 1; goto rotate; }</p><p>  tmp.x = g_CurBlock.x - 2; if (C

113、heckBlock(tmp)) { dx = -2; goto rotate; }</p><p>  tmp.x = g_CurBlock.x + 2; if (CheckBlock(tmp)) { dx = 2; goto rotate; }</p><p><b>  return;</b></p><p>&

114、lt;b>  rotate:</b></p><p><b>  // 旋轉(zhuǎn)</b></p><p>  DrawBlock(g_CurBlock, HIDE);</p><p>  g_CurBlock.dir++;</p><p>  g_CurBlock.x += dx;</p>&

115、lt;p>  DrawBlock(g_CurBlock);</p><p><b>  }</b></p><p><b>  // 左移方塊</b></p><p>  void OnLeft()</p><p><b>  {</b></p><p

116、>  BLOCKINFO tmp = g_CurBlock;</p><p><b>  tmp.x--;</b></p><p>  if (CheckBlock(tmp))</p><p><b>  {</b></p><p>  DrawBlock(g_CurBlock, HIDE);

117、</p><p>  g_CurBlock.x--;</p><p>  DrawBlock(g_CurBlock);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  // 右移方塊</b>&l

118、t;/p><p>  void OnRight()</p><p><b>  {</b></p><p>  BLOCKINFO tmp = g_CurBlock;</p><p><b>  tmp.x++;</b></p><p>  if (CheckBlock(tmp)

119、)</p><p><b>  {</b></p><p>  DrawBlock(g_CurBlock, HIDE);</p><p>  g_CurBlock.x++;</p><p>  DrawBlock(g_CurBlock);</p><p><b>  }</b>

120、;</p><p><b>  }</b></p><p><b>  // 下移方塊</b></p><p>  void OnDown()</p><p><b>  {</b></p><p>  BLOCKINFO tmp = g_CurBloc

121、k;</p><p><b>  tmp.y--;</b></p><p>  if (CheckBlock(tmp))</p><p><b>  {</b></p><p>  DrawBlock(g_CurBlock, HIDE);</p><p>  g_CurBlo

122、ck.y--;</p><p>  DrawBlock(g_CurBlock);</p><p><b>  }</b></p><p><b>  else</b></p><p>  OnSink(); // 不可下移時,執(zhí)行“沉底方塊”操作</p><p><b&

123、gt;  }</b></p><p><b>  // 沉底方塊</b></p><p>  void OnSink()</p><p><b>  {</b></p><p>  int i, x, y;</p><p><b>  // 連續(xù)下移方塊

124、</b></p><p>  DrawBlock(g_CurBlock, HIDE);</p><p>  BLOCKINFO tmp = g_CurBlock;</p><p><b>  tmp.y--;</b></p><p>  while (CheckBlock(tmp))</p>&

125、lt;p><b>  {</b></p><p>  g_CurBlock.y--;</p><p><b>  tmp.y--;</b></p><p><b>  }</b></p><p>  DrawBlock(g_CurBlock, FIX);</p>

126、;<p>  // 固定方塊在游戲區(qū)</p><p>  WORD b = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];</p><p>  for(i = 0; i < 16; i++)</p><p><b>  {</b></p><p>  if (

127、b & 0x8000)</p><p><b>  {</b></p><p>  if (g_CurBlock.y - i / 4 >= HEIGHT)</p><p>  { // 如果方塊的固定位置超出高度,結(jié)束游戲</p><p>  GameOver();</p><p&g

128、t;<b>  return;</b></p><p><b>  }</b></p><p><b>  else</b></p><p>  g_World[g_CurBlock.x + i % 4][g_CurBlock.y - i / 4] = 1;</p><p>&

129、lt;b>  }</b></p><p><b>  b <<= 1;</b></p><p><b>  }</b></p><p>  // 檢查是否需要消掉行,并標記</p><p>  int row[4] = {0};</p><p>

130、  bool bRow = false;</p><p>  for(y = g_CurBlock.y; y >= max(g_CurBlock.y - 3, 0); y--)</p><p><b>  {</b></p><p><b>  i = 0;</b></p><p>  for

131、(x = 0; x < WIDTH; x++)</p><p>  if (g_World[x][y] == 1)</p><p><b>  i++;</b></p><p>  if (i == WIDTH)</p><p><b>  {</b></p><p>

132、  bRow = true;</p><p>  row[g_CurBlock.y - y] = 1;</p><p>  setfillstyle(WHITE, DIAGCROSS2_FILL);</p><p>  bar(0, (HEIGHT - y - 1) * SIZE + SIZE / 2 - 2, WIDTH * SIZE - 1, (HEIGHT -

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論