版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、<p> 用C++實現(xiàn)的俄羅斯方塊程序設(shè)計</p><p><b> 需求分析。</b></p><p><b> 1.1、游戲需求</b></p><p> 隨機給出不同的形狀(長條形、Z字形、反Z形、田字形、7字形、反7形、T字型)下落填充給定的區(qū)域,若填滿一條便消掉,記分,當達到一定的分數(shù)時,過關(guān),
2、設(shè)置四關(guān),各關(guān)下落速度不同,若在游戲中各形狀填滿了給定區(qū)域,為輸者,彈出相應提示。</p><p> 1.2、游戲界面需求</p><p> 良好的用戶界面,有關(guān)信息顯示(如操作方法、等級等)和分數(shù)顯示。讓方塊在一定的區(qū)域內(nèi)運動和變形,該區(qū)域用一種顏色表明,即用一種顏色作為背景,本游戲的背景設(shè)為黑色。還需用另一種顏色把黑色圍起來,寬度適中,要實現(xiàn)美感。而不同的方塊用不同的著色表示,使游
3、戲界面更加清晰、有條理。消層時采用一定的時間延遲,增加視覺消行的感官效果。</p><p> 1.3、游戲方塊需求</p><p> 良好的方塊形狀設(shè)計,繪制七種常見的基本圖形(長條形、Z字形、反Z形、田字形、L字形、反L形、T字型)以及另外本程序另外加入的點形方塊,各個方塊要能實現(xiàn)它的變形,可設(shè)為順時針或逆 時針變形,一般為逆時針。為體現(xiàn)游戲的趣味性和擴展性,本游戲象征性的增加了點形
4、方塊,其他更多形狀的方塊可用類似方法增加。</p><p> 1.4、游戲控制的需求</p><p> 游戲控分為多個方面,包括畫面繪制,控制命令的獲取,控制命令的分配、控制命令的處理,方塊的繪制,方塊的移動,方塊的旋轉(zhuǎn),方塊下落和消層以及計分等。對各個命令的合理處理和綜合控制十分重要,一旦出錯可能導致整個程序的崩潰,因此需要小心設(shè)計。</p><p><
5、b> 系統(tǒng)設(shè)計。</b></p><p> 2.1、程序流程圖:</p><p> 2.2、游戲設(shè)計概述</p><p> 從整體上而言,在該游戲可設(shè)計一個方塊類,其中包括對方塊的信息描述(如:ID)、方塊的操作(如:旋轉(zhuǎn)、下沉)。再設(shè)計一個控制類,實現(xiàn)各種控制(如:獲取控制信號,分發(fā)控制信號)。另定義一個游戲區(qū)類,用以處理游戲區(qū)繪制等內(nèi)容
6、??驁D如下:</p><p> 在主函數(shù)中(按照2.1中框圖),先通過控制類初始化游戲,再通過隨機時間函數(shù)獲得一個隨機數(shù),該隨機數(shù)確定一個方塊,即用該隨機數(shù)產(chǎn)生一個ID從而確定產(chǎn)生的為方塊。然后從鍵盤取得各種操作信號,通過控類函數(shù)對操作信號進行分發(fā)、處理,進而控制方塊的行為改變。與此同時,監(jiān)控游戲區(qū)中已有方塊的狀態(tài),一旦滿足消行即進行消行控制,同時進行計分和等級劃分,而如果游戲區(qū)已滿則游戲結(jié)束,彈出提示。而對界
7、面和方塊的展現(xiàn)主要通過第三方軟件EasyX實現(xiàn),通過其畫圖位置的改變與時間的結(jié)合達到方塊視覺移動的效果。</p><p> 2.3、定義方塊的數(shù)據(jù)結(jié)構(gòu)</p><p> 方塊是本游戲的基本要素,對于方塊的設(shè)計,本游戲用4*4的矩陣畫出來,在相應的位置置為‘1’和‘0’以實現(xiàn)各種方塊的形狀,以“立L形”為例如下:</p><p> 而在程序設(shè)計中則賦予各種基本方
8、塊一個不同的十六進制ID即可表示該方塊,如“立7形”其ID為[0x4460],再與其其他變形組合和著色分配即可得到各種L形ID的集合{0x4460, 0x02E0, 0x0622, 0x0740,MAGENTA};其他各種方塊類似設(shè)計。具體清單如下:</p><p> {0x0F00, 0x4444, 0x0F00, 0x4444, RED},// I</p><p> {0x06
9、60, 0x0660, 0x0660, 0x0660, BLUE},// 口</p><p> {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA},// L</p><p> ?。?x2260, 0x0E20, 0x0644, 0x0470, YELLOW},// 反L</p><p> {0x0C60, 0x2640,
10、0x0C60, 0x2640, CYAN},// Z</p><p> {0x0360, 0x4620, 0x0360, 0x4620, GREEN},// 反Z</p><p> {0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN},// T</p><p> {0x0400,0x0800,0x0400,0x0800,RED
11、}}; //.</p><p><b> 2.4、方塊的變形</b></p><p> 方塊要實現(xiàn)變形,其實就是通過EasyX畫出不同的圖形來實現(xiàn)的,當然亂畫是不行的,而為了控制其變形的情況,必須設(shè)定相應的圖形描述,本程序使用的是不同圖形的不同ID碼表示的方法來實在方塊的描述的。能過鍵盤接收變形指令(即W鍵或向上鍵),將所得信號傳遞給信號接收函數(shù),
12、再通過信號處理函數(shù)改變當前方塊的ID值,最后根據(jù)新的ID值畫出新的圖形,此時即實在了方塊的變形。</p><p> 2.5、定時處理機制</p><p> 為了提高游戲的易控性和自動性,定時機制是很有必要的。</p><p> 經(jīng)過定時器的設(shè)置后,這里通過利用控制程序跳到定時器的時間的處理函數(shù)去實現(xiàn),當固定時間片間隔到達后,先檢測當前下墜物是否已經(jīng)到達了底部,
13、不是則進行下墜物向下移動一個單位的操作,是則到底后產(chǎn)生一個新的“下一個下墜物”,并代替舊的,將原先舊的“下一個下墜物”用作當前激活狀態(tài)下正在使用的下墜物,并對使用后的一些狀態(tài)進行檢測:是否馬上到達底部,使則進行銷行操作;是否在到達底部的同時到達游戲區(qū)域的頂部,從而判定游戲是否因違規(guī)而結(jié)束,彈出相應對話框供用戶選擇是否繼續(xù)重新開始。</p><p> 圖 3.2.2裝載方塊</p><p>
14、; 視圖類通過不同十六進制ID來記錄下墜物的類型,共有七種形狀,并從7種方塊中隨機抽取圖形。而ID除了記錄下墜物的類型外,還需記錄其當前的變形狀態(tài)。</p><p> 在產(chǎn)生新的下一個下墜物前,需要先將當前狀態(tài)物的記錄和舊的下一個下墜物保存下來,然后用隨機函數(shù)Random()產(chǎn)生一個最大值不大于指定值的隨機正整數(shù),將這個新生成的正整數(shù)用作新的“下一個下墜物”的形狀值。</p><p>
15、<b> 2.5、功能的擴展</b></p><p> 為了增加游戲的可玩性和趣味性,本程序增加了計分和等級提升的的功能。每消去相應的行數(shù)可獲得不同的分值,達到一定分值后等級提升,同時方塊下落速度加快。具體得分和等級情況如下(實際程序因為演示時間的限制而與下表存在區(qū)別):</p><p> 為實現(xiàn)該功能需設(shè)置相應的計數(shù)器和等級控制器,并隨時監(jiān)測游戲的情況來進行相
16、應的正確的處理。實現(xiàn)框圖如下:</p><p><b> 三、關(guān)鍵代碼描述。</b></p><p> // 編譯環(huán)境:Visual C++ 6.0 / 2010,EasyX 2011驚蟄版</p><p> // 程序編寫:krissi <zhaoh1987@qq.com></p><p> //
17、最后更新:20103-1-1</p><p> ////////////////////////////////////////////</p><p> #include <graphics.h></p><p> #include <conio.h></p><p> #include <time.h
18、></p><p> #include <iostream></p><p> #include<stdlib.h></p><p> using namespace std;</p><p> /////////////////////////////////////////////</p>
19、<p> // 定義常量、枚舉量、結(jié)構(gòu)體、全局變量 //</p><p> /////////////////////////////////////////////</p><p> #define WIDTH 10// 游戲區(qū)寬度</p><p> #define HEIGHT 22// 游戲區(qū)高度</
20、p><p> #define SIZE 20 // 每個游戲區(qū)單位的實際像素</p><p> #define M 8//俄羅斯方塊形狀的數(shù)目</p><p> int count = 0;//分數(shù)清零</p><p> int control_time = 500;//控制下落快慢</p><
21、p> int level = 0;//等級清零</p><p> int deltline=0;//消行清零</p><p> int line_num=0;//統(tǒng)計消的行數(shù)</p><p> char s[50]={'0'};</p><p> char array_c[50]={'0'};&
22、lt;/p><p> char Level_ch[50]={'0'};</p><p><b> // 定義操作類型</b></p><p><b> enum CTRL</b></p><p><b> {</b></p><p>
23、 CTRL_ROTATE,// 方塊旋轉(zhuǎn)</p><p> CTRL_LEFT, CTRL_RIGHT, CTRL_DOWN,// 方塊左、右、下移動</p><p> CTRL_SINK,// 方塊沉底</p><p> CTRL_QUIT,// 退出游戲</p><p><b>
24、 };</b></p><p> // 定義繪制方塊的方法</p><p><b> enum DRAW</b></p><p><b> {</b></p><p> SHOW,// 顯示方塊</p><p> HIDE,// 隱藏方塊</
25、p><p> FIX// 固定方塊</p><p><b> };</b></p><p> // 定義俄羅斯方塊</p><p> struct BLOCK</p><p><b> {</b></p><p> WORD dir[4];
26、// 方塊的四個旋轉(zhuǎn)狀態(tài)</p><p> COLORREF color;// 方塊的顏色</p><p> }g_Blocks[M] = {{0x0F00, 0x4444, 0x0F00, 0x4444, RED},// I</p><p> {0x0660, 0x0660, 0x0660, 0x0660, BLUE},// 口</p&
27、gt;<p> {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA},// L</p><p> {0x2260, 0x0E20, 0x0644, 0x0470, YELLOW},// 反L</p><p> {0x0C60, 0x2640, 0x0C60, 0x2640, CYAN},// Z</p><p&g
28、t; {0x0360, 0x4620, 0x0360, 0x4620, GREEN},// 反Z</p><p> {0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN},// T</p><p> {0x0400,0x0800,0x0400,0x0800,RED}};//點</p><p> // 定義當前方塊、下一個方塊的信息
29、</p><p> struct BLOCKINFO</p><p><b> {</b></p><p> byte id;// 方塊 ID</p><p> int x, y;// 方塊在游戲區(qū)中的坐標</p><p> byte dir:2;// 方向</p>
30、<p><b> };</b></p><p><b> // 定義游戲區(qū)類</b></p><p> BYTE g_World[WIDTH][HEIGHT] = {0};</p><p> class CGAME;</p><p> class Window</p>
31、<p><b> {</b></p><p><b> public:</b></p><p> void InitWindow();</p><p><b> };</b></p><p> //對方塊進行操作的類</p><p&g
32、t; class GAME_BLOCK </p><p><b> {</b></p><p><b> private:</b></p><p> BLOCKINFO g_CurBlock;</p>
33、<p> BLOCKINFO g_NextBlock;</p><p><b> public:</b></p><p> GAME_BLOCK (){}</p><p> ~GAME_BLOCK (){}</p><p> void NewBlock();// 生成新的方塊</p>&
34、lt;p> bool CheckBlock(BLOCKINFO _block);// 檢測指定方塊是否可以放下</p><p> void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW);// 畫方塊</p><p> void OnRotate();// 旋轉(zhuǎn)方塊</p><p> void
35、OnLeft();// 左移方塊</p><p> void OnRight();// 右移方塊</p><p> void OnDown();// 下移方塊</p><p> void OnSink(CGAME &);// 沉底方塊</p><p> BLOCKINFO &CurBlock();</p>
36、<p> BLOCKINFO &NextBlock();</p><p><b> };</b></p><p> BLOCKINFO& GAME_BLOCK::CurBlock()</p><p><b> {</b></p><p> return g_Cu
37、rBlock;</p><p><b> }</b></p><p> BLOCKINFO& GAME_BLOCK::NextBlock()</p><p><b> {</b></p><p> return g_NextBlock;</p><p><
38、;b> }</b></p><p><b> //游戲控制類</b></p><p> class CGAME :Window,GAME_BLOCK </p><p><b> {</b></p><p><b> private:</b>
39、;</p><p> void DispatchControl(CTRL);</p><p><b> public:</b></p><p> void InitGame();</p><p> void Start_Game();</p><p> void Game_Over();
40、</p><p> void NewGame();</p><p> void Quit_Game();</p><p> CTRL GetControl(bool _onlyresettimer = false);</p><p><b> };</b></p><p> void C
41、GAME::InitGame()</p><p><b> {</b></p><p> InitWindow();</p><p> NewGame();</p><p><b> }</b></p><p> CGAME G_block;</p>
42、<p> //類成員函數(shù)的描述</p><p> void CGAME::Start_Game()</p><p><b> {</b></p><p> CTRL c; //枚舉型變量,控制旋轉(zhuǎn),下沉,向左,向右等等</p><p> while(true)&
43、lt;/p><p><b> {</b></p><p> c = G_block.GetControl(); </p><p> G_block.DispatchControl(c); </p><p> // 按退出時,顯示對話框咨詢用戶是否退出 </p><p> if (c
44、 == CTRL_QUIT) </p><p><b> {</b></p><p> HWND wnd = GetHWnd();</p><p> if (MessageBox(wnd, _T("您要退出游戲嗎?"), _T("提醒"), MB_OKCANCEL | MB_ICONQUESTIO
45、N) == IDOK)</p><p> G_block.Quit_Game();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> // 初
46、始化游戲</b></p><p> void Window::InitWindow()</p><p><b> {</b></p><p> initgraph(640, 480);</p><p> srand((unsigned)time(NULL));</p><p>
47、<b> // 顯示操作說明</b></p><p> setfont(14, 0, _T("宋體"));</p><p> outtextxy(20, 330, _T("操作說明"));</p><p> outtextxy(20, 350, _T("上:旋轉(zhuǎn)"));<
48、/p><p> outtextxy(20, 370, _T("左:左移"));</p><p> outtextxy(20, 390, _T("右:右移"));</p><p> outtextxy(20, 410, _T("下:下移"));</p><p> outtextxy
49、(20, 430, _T("空格:沉底"));</p><p> outtextxy(20, 450, _T("ESC:退出"));</p><p> outtextxy(20, 310, _T("分數(shù):"));</p><p> outtextxy(80, 310, _T("0"
50、));</p><p> outtextxy(20, 290, _T("等級: "));</p><p> outtextxy(80, 290, _T("0"));</p><p> outtextxy(20, 270, _T("消行: "));</p><p> outte
51、xtxy(80, 270, _T("0"));</p><p><b> // 設(shè)置坐標原點</b></p><p> setorigin(220, 20);</p><p> // 繪制游戲區(qū)邊界</p><p> rectangle(-1, -1, WIDTH * SIZE, HEIGHT
52、 * SIZE);</p><p> rectangle((WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE);</p><p><b> }</b></p><p><b> // 開始新游戲</b></p><p> stat
53、ic int OldTime;</p><p> void CGAME::NewGame()</p><p><b> {</b></p><p> control_time = OldTime;</p><p> setorigin(0, 0);</p><p> outtextxy(
54、80, 310, _T("0 "));</p><p> outtextxy(80, 290, _T("0 "));</p><p> setorigin(220, 20);</p><p><b> // 清空游戲區(qū)</b></p><p> setfil
55、lstyle(BLACK);</p><p> bar(0, 0, WIDTH * SIZE - 1, HEIGHT * SIZE - 1);</p><p> ZeroMemory(g_World, WIDTH * HEIGHT); //用0來填充內(nèi)存區(qū)域</p><p> // 生成下一個方塊</p><p
56、> NextBlock().id = rand() % M;</p><p> NextBlock().dir = rand() % 4;</p><p> NextBlock().x = WIDTH + 1;</p><p> NextBlock().y = HEIGHT - 1;</p><p><b> //
57、獲取新方塊</b></p><p> NewBlock();</p><p><b> }</b></p><p><b> // 生成新的方塊</b></p><p> void GAME_BLOCK::NewBlock()</p><p><b&
58、gt; {</b></p><p> CurBlock().id = NextBlock().id,NextBlock().id = rand() % M;</p><p> CurBlock().dir = NextBlock().dir,NextBlock().dir = rand() % 4;</p><p> CurBlock().
59、x = (WIDTH - 4) / 2;</p><p> CurBlock().y = HEIGHT + 2;</p><p> // 下移新方塊直到有局部顯示</p><p> WORD c = g_Blocks[CurBlock().id].dir[CurBlock().dir];</p><p> while((c &
60、 0xF) == 0)</p><p><b> {</b></p><p> CurBlock().y--;</p><p><b> c >>= 4;</b></p><p><b> }</b></p><p><b>
61、; // 繪制新方塊</b></p><p> DrawBlock(CurBlock());</p><p> // 繪制下一個方塊</p><p> setfillstyle(BLACK);</p><p> bar((WIDTH + 1) * SIZE, 0, (WIDTH + 5) * SIZE - 1, 4 *
62、SIZE - 1);</p><p> DrawBlock(NextBlock());</p><p><b> }</b></p><p><b> // 畫方塊</b></p><p> void GAME_BLOCK::DrawBlock(BLOCKINFO _block, DRAW
63、_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> int color = BLACK;</p>
64、<p> switch(_draw)</p><p><b> {</b></p><p> case SHOW: color = g_Blocks[_block.id].color; break;</p><p> case HIDE: color = BLACK;break;</p><p>
65、 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++)</p><p><b>
66、; {</b></p><p> if (b & 0x8000)</p><p><b> {</b></p><p> x = _block.x + i % 4;</p><p> y = _block.y - i / 4;</p><p> if (y <
67、 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 - y) * SIZE - 4, 3, true);&l
68、t;/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></p><p><b
69、> }</b></p><p><b> b <<= 1;</b></p><p><b> }</b></p><p><b> }</b></p><p><b> // 獲取控制命令</b></p>
70、<p> CTRL CGAME::GetControl(bool _onlyresettimer)</p><p><b> {</b></p><p> static DWORD oldtime = GetTickCount();</p><p><b> // 重置計時器</b></p>
71、;<p> if (_onlyresettimer)</p><p><b> {</b></p><p> oldtime = GetTickCount();</p><p> return CTRL_DOWN; // 僅僅為了重置計時器,隨便返回一個值</p><p><b> }&
72、lt;/b></p><p><b> // 獲取控制值</b></p><p> while(true)</p><p><b> {</b></p><p> // 如果超時,自動下落一格</p><p> switch(level)//設(shè)置游戲等級快慢&
73、lt;/p><p><b> {</b></p><p> case 0:control_time=500;break;</p><p> case 1:control_time=350;break;</p><p> case 2:control_time=200;break;</p><p&g
74、t; case 3:control_time=100;break;</p><p> case 4:control_time=50;break;</p><p><b> }</b></p><p> DWORD newtime = GetTickCount();</p><p> if (newtime -
75、oldtime >= control_time)</p><p><b> {</b></p><p> oldtime = newtime;</p><p> return CTRL_DOWN;</p><p><b> }</b></p><p> //
76、如果有按鍵,返回按鍵對應的功能</p><p> if (kbhit())</p><p><b> {</b></p><p> switch(getch())</p><p><b> {</b></p><p><b> case 'w
77、9;:</b></p><p> case 'W':return CTRL_ROTATE;</p><p><b> case 'a':</b></p><p> case 'A':return CTRL_LEFT;</p><p><b>
78、 case 'd':</b></p><p> case 'D':return CTRL_RIGHT;</p><p><b> case 's':</b></p><p> case 'S':return CTRL_DOWN;</p><
79、;p> case 27:return CTRL_QUIT;</p><p> case ' ':return CTRL_SINK;</p><p><b> case 0:</b></p><p> case 0xE0:</p><p> switch(getch())</p&g
80、t;<p><b> {</b></p><p> case 72:return CTRL_ROTATE;</p><p> case 75:return CTRL_LEFT;</p><p> case 77:return CTRL_RIGHT;</p><p> case 80:ret
81、urn CTRL_DOWN;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }&
82、lt;/b></p><p><b> // 分發(fā)控制命令</b></p><p> void CGAME::DispatchControl(CTRL _ctrl)</p><p><b> {</b></p><p> switch(_ctrl)</p><p&g
83、t;<b> {</b></p><p> case CTRL_ROTATE: OnRotate(); break;</p><p> case CTRL_LEFT:OnLeft(); break;</p><p> case CTRL_RIGHT: OnRight(); break;</p>
84、<p> case CTRL_DOWN:OnDown(); break;</p><p> case CTRL_SINK:OnSink(G_block); break;</p><p> case CTRL_QUIT:break;</p><p><b> }</b></p>&l
85、t;p><b> }</b></p><p><b> // 旋轉(zhuǎn)方塊</b></p><p> void GAME_BLOCK::OnRotate()</p><p><b> {</b></p><p> // 獲取可以旋轉(zhuǎn)的 x 偏移量</p>
86、<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.x - 1
87、;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 (CheckBlock(tmp)){dx =
88、-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><b> rotate:</b></p>
89、;<p><b> // 旋轉(zhuǎn)</b></p><p> DrawBlock(g_CurBlock, HIDE);</p><p> g_CurBlock.dir++;</p><p> g_CurBlock.x += dx;</p><p> DrawBlock(g_CurBlock);<
90、/p><p><b> }</b></p><p> bool GAME_BLOCK::CheckBlock(BLOCKINFO _block)</p><p><b> {</b></p><p> WORD b = g_Blocks[_block.id].dir[_block.dir];&l
91、t;/p><p><b> int x, y;</b></p><p> for(int i=0; i<16; i++)</p><p><b> {</b></p><p> if (b & 0x8000)</p><p><b> {<
92、/b></p><p> x = _block.x + i % 4;</p><p> y = _block.y - i / 4;</p><p> if ((x < 0) || (x >= WIDTH) || (y < 0))</p><p> return false;</p><p&g
93、t; if ((y < HEIGHT) && (g_World[x][y]))</p><p> return false;</p><p><b> }</b></p><p><b> b <<= 1;</b></p><p><b> }&
94、lt;/b></p><p> return true;</p><p><b> }</b></p><p><b> // 左移方塊</b></p><p> void GAME_BLOCK::OnLeft()</p><p><b> {<
95、;/b></p><p> BLOCKINFO tmp = g_CurBlock;</p><p><b> tmp.x--;</b></p><p> if (CheckBlock(tmp))</p><p><b> {</b></p><p> Draw
96、Block(g_CurBlock, HIDE);</p><p> g_CurBlock.x--;</p><p> DrawBlock(g_CurBlock);</p><p><b> }</b></p><p><b> }</b></p><p><b&
97、gt; // 右移方塊</b></p><p> void GAME_BLOCK::OnRight()</p><p><b> {</b></p><p> BLOCKINFO tmp = g_CurBlock;</p><p><b> tmp.x++;</b></p
98、><p> if (CheckBlock(tmp))</p><p><b> {</b></p><p> DrawBlock(g_CurBlock, HIDE);</p><p> g_CurBlock.x++;</p><p> DrawBlock(g_CurBlock);</p
99、><p><b> }</b></p><p><b> }</b></p><p><b> // 下移方塊</b></p><p> void GAME_BLOCK::OnDown()</p><p><b> {</b>
100、</p><p> BLOCKINFO tmp = g_CurBlock;</p><p><b> tmp.y--;</b></p><p> if (CheckBlock(tmp))</p><p><b> {</b></p><p> DrawBlock(g
101、_CurBlock, HIDE);</p><p> g_CurBlock.y--;</p><p> DrawBlock(g_CurBlock);</p><p><b> }</b></p><p><b> else</b></p><p> OnSink(G
102、_block);// 不可下移時,執(zhí)行“沉底方塊”操作</p><p><b> }</b></p><p><b> // 沉底方塊</b></p><p> void GAME_BLOCK::OnSink(CGAME &G_block)</p><p><b> {&
103、lt;/b></p><p> int i, x, y;</p><p><b> // 連續(xù)下移方塊</b></p><p> DrawBlock(CurBlock(), HIDE);</p><p> BLOCKINFO tmp = CurBlock();</p><p><
104、;b> tmp.y--;</b></p><p> while (CheckBlock(tmp))</p><p><b> {</b></p><p> CurBlock().y--;</p><p><b> tmp.y--;</b></p><p
105、><b> }</b></p><p> DrawBlock(CurBlock(), FIX);</p><p> // 固定方塊在游戲區(qū)</p><p> WORD b = g_Blocks[CurBlock().id].dir[CurBlock().dir];</p><p> for(i = 0;
106、i < 16; i++)</p><p><b> {</b></p><p> if (b & 0x8000)</p><p><b> {</b></p><p> if (CurBlock().y - i / 4 >= HEIGHT)</p><
107、p> {// 如果方塊的固定位置超出高度,結(jié)束游戲</p><p> G_block.Game_Over();</p><p><b> return;</b></p><p><b> }</b></p><p><b> else</b></p>
108、;<p> g_World[CurBlock().x + i % 4][CurBlock().y - i / 4] = 1;</p><p><b> }</b></p><p><b> b <<= 1;</b></p><p><b> }</b></p&g
109、t;<p> int line_num=0;</p><p> // 檢查是否需要消掉行,并標記</p><p> int row[4] = {0};</p><p> bool bRow = false;</p><p> for(y = CurBlock().y; y >= max(CurBlock().y
110、- 3, 0); y--)</p><p><b> {</b></p><p> int flag = 0;</p><p><b> i = 0;</b></p><p> for(x = 0; x < WIDTH; x++)</p><p> if (g
111、_World[x][y] == 1)</p><p><b> i++;</b></p><p> if (i == WIDTH)</p><p><b> {</b></p><p><b> flag++;</b></p><p> bRo
112、w = true;</p><p> deltline++;</p><p> row[CurBlock().y - y] = 1;</p><p> setfillstyle(WHITE, DIAGCROSS2_FILL);</p><p> bar(0, (HEIGHT - y - 1) * SIZE + SIZE / 2 - 2
113、, WIDTH * SIZE - 1, (HEIGHT - y - 1) * SIZE + SIZE / 2 + 2);</p><p> line_num++;</p><p> //sndPlaySound(".\\456.wav",SND_ASYNC);</p><p><b> }</b></p>
114、<p><b> }</b></p><p> switch(line_num)</p><p><b> {</b></p><p> case 1: count +=10; break;</p><p> case 2: count +=20; break;</p&g
115、t;<p> case 3: count +=40; break;</p><p> case 4: count +=60; break;</p><p><b> }</b></p><p><b> {</b></p><p> setorigin(0,0);</p
116、><p> sprintf(s, "%d", count);</p><p> outtextxy(80,310,s);</p><p> sprintf(array_c, "%d", deltline);</p><p> outtextxy(80,270,array_c);</p>
117、<p><b> }</b></p><p> if(count<50)</p><p><b> level=0;</b></p><p> else if(count<100)</p><p><b> level=1;</b></p
118、><p> else if(count<200)</p><p><b> level=2;</b></p><p> else if(count<300)</p><p><b> level=3;</b></p><p><b> else&l
119、t;/b></p><p><b> level=4;</b></p><p> sprintf(Level_ch,"%d",level);</p><p> outtextxy(80, 290, Level_ch);</p><p> setorigin(220, 20);</p
120、><p><b> if (bRow)</b></p><p><b> {</b></p><p> // 延時 200 毫秒</p><p> Sleep(200);</p><p> // 擦掉剛才標記的行</p><p> IMAGE
121、img;</p><p> for(i = 0; i < 4; i++)</p><p><b> {</b></p><p> if (row[i])</p><p><b> {</b></p><p> for(y = CurBlock().y - i
122、+ 1; y < HEIGHT; y++)</p><p> for(x = 0; x < WIDTH; x++)</p><p><b> {</b></p><p> g_World[x][y - 1] = g_World[x][y];</p><p> g_World[x][y] = 0;<
123、;/p><p><b> }</b></p><p> getimage(&img, 0, 0, WIDTH * SIZE, (HEIGHT - (CurBlock().y - i + 1)) * SIZE);</p><p> putimage(0, SIZE, &img);</p><p><
124、b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> // 產(chǎn)生新方塊</b></p><p> NewBlock();</p><p><b>
125、// 重新計算延時</b></p><p> G_block.GetControl(true);</p><p><b> }</b></p><p><b> // 結(jié)束游戲</b></p><p> void CGAME::Game_Over()</p><
126、;p><b> {</b></p><p> HWND wnd = GetHWnd();</p><p> if (MessageBox(wnd, _T("游戲結(jié)束。\n您想重新來一局嗎?"), _T("游戲結(jié)束"), MB_YESNO | MB_ICONQUESTION) == IDYES)</p>
127、<p> NewGame();</p><p><b> else</b></p><p><b> {</b></p><p> Quit_Game();</p><p><b> }</b></p><p><b>
128、}</b></p><p> void CGAME::Quit_Game()</p><p><b> {</b></p><p> closegraph();</p><p><b> exit(0);</b></p><p><b> }
129、</b></p><p> void main()</p><p><b> {</b></p><p> G_block.InitGame();</p><p> G_block.Start_Game();</p><p> G_block.Quit_Game();<
130、/p><p><b> }</b></p><p><b> 四、測試結(jié)果。</b></p><p> 程序完成后運行如下,達到預期結(jié)果,運行效果良好。</p><p> 成功地完成了方塊的顯示、旋轉(zhuǎn)、消行、計分、等級、加速等一系列功能,游戲可玩性強,且具有封裝性、通用性、容錯性。</p&
131、gt;<p><b> 五、實驗總結(jié)。</b></p><p> 本次C++課程設(shè)計前后將近兩周的時間。前期準備階段,設(shè)想一些構(gòu)想和主要任務;后期則是具體功能的實現(xiàn),比如說在原有功能的基礎(chǔ)上增加了分數(shù)的積累和游戲等級的提升,還有顯示所消掉的行數(shù)等,最重要的工作則是對代碼中的類進行封裝,實現(xiàn)類的繼承和多態(tài)等問題。</p><p> 這次實驗中我們遇到
132、了不少困難,本來設(shè)想實現(xiàn)雙人版對戰(zhàn)和增加背景音樂等功能,可是由于時間的短促,最終沒能實現(xiàn),心里不免有些遺憾,在實現(xiàn)類的封裝和類的繼承和多態(tài)性時,也遇到了不少問題,但是我們相信我們不會被困難難住,通過大家的一起探討和分析,問題最終一個個迎刃而解,系統(tǒng)開發(fā)基本完畢。</p><p> 通過這次課程設(shè)計,使我懂得了不少東西。我們在日常的學習中應該注意對所學知識的實踐運用,在學習時,應該深入的了解,體會知識,這對我們今
133、后的學習和工作會有很大的幫助。通過此次的實踐,我們小組體會到學以致用額樂趣,同時,也增長了我們課堂外多方面的知識。</p><p><b> 六、參考文獻</b></p><p> C++語言程序設(shè)計 李春葆 陶紅艷 金晶 編著 清華大學出版社</p><p> 唐俊明. Visual C++ 6.0 編程實例與技巧. 高等教育出版.20
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《c++俄羅斯方塊》課程設(shè)計--俄羅斯方塊
- c++俄羅斯方塊課程設(shè)計
- c++俄羅斯方塊課程設(shè)計
- 俄羅斯方塊c++課程設(shè)計報告
- c課程設(shè)計--俄羅斯方塊
- 課程設(shè)計---俄羅斯方塊
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- 俄羅斯方塊課程設(shè)計
- c#俄羅斯方塊課程設(shè)計
- c_課程設(shè)計-俄羅斯方塊
- 課程設(shè)計--用vc++實現(xiàn)俄羅斯方塊的程序設(shè)計
- 課程設(shè)計---用vc++實現(xiàn)俄羅斯方塊的程序設(shè)計
- c++俄羅斯方塊課程設(shè)計報告書
- 俄羅斯方塊課程設(shè)計報告
- c++課程設(shè)計報告---俄羅斯方塊的設(shè)計與實現(xiàn)
評論
0/150
提交評論