C語言課程設(shè)計(jì)俄羅斯方塊源代碼.doc
1、 新建“.h”頭文件,將“頭文件”代碼粘貼至其中,2、 新建“.c”源文件,將“源代碼”代碼粘貼到其中。3、 新建空白工程,將頭文件和源代碼添加進(jìn)去,調(diào)試使用。/頭文件/1.自定義枚舉類型,定義7種形態(tài)的游戲方塊typedef enum tetris_shapeZShape=0,SShape,LineShape,TShape,SquareShape,LShape,MirroredLShapeshape;/2.函數(shù)聲明/(1)操作方塊函數(shù)int maxX();/取得當(dāng)前方塊的最大x坐標(biāo)int minX();/取得當(dāng)前方塊的最小x坐標(biāo)void turn_left();/當(dāng)前方塊逆時(shí)針旋轉(zhuǎn)90度void turn_right();int out_of_table();void transform();int leftable();int rightable();int downable();void move_left();void move_right();/(2)操作游戲桌面的函數(shù)int add_to_table();void remove_full();/(3)控制游戲函數(shù)void new_game();void run_game();void next_shape();int random(int seed);/(4)繪圖函數(shù)void paint();void draw_table();/(5)其他功能函數(shù)void key_down(WPARAM wParam);void resize();void initialize();void finalize();/(6)回調(diào)函數(shù),用來處理Windows消息LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);/源代碼/1.文件包含#include<windows.h>#include<time.h>#include<stdio.h>#include"tetris.h"/2.常量定義#define APP_NAME "TETRIS"#define APP_TITLE "Tetris Game"#define GAMEOVER "GAME OVER"#define SHAPE_COUNT 7#define BLOCK_COUNT 4#define MAX_SPEED 5#define COLUMS 10#define ROWS 20#define RED RGB(255,0,0)#define YELLOW RGB(255,255,0)#define GRAY RGB(128,128,128)#define BLACK RGB(0,0,0)#define WHITE RGB(255,255,255)#define STONE RGB(192,192,192)#define CHARS_IN_LINE 14#define SCORE "SCORE %4d"/3.全局變量定義/(1)char score_charCHARS_IN_LINE=0;/(2)char* press_enter="Press Enter key."/(3)幫助提示信息char *help="press space or up key to transform shape.","Press left or right key to mover shape.","Press down key to speed up.","Press enter key to pause game.","Enjoy it.:-)",0;/(4)枚舉游戲的狀態(tài)enum game_stategame_start,game_run,game_pause,game_over,state=game_start;/(5)定義方塊的顏色COLORREF shape_color=RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),RGB(255,255,0),RGB(0,255,255),RGB(255,0,255),RGB(255,255,255);/(6)方塊的7中類型int shape_coordinateSHAPE_COUNTBLOCK_COUNT2=0,1,0,0,-1,0,-1,1,0,-1,0,0,1,0,1,1,0,-1,0,0,0,1,0,2,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,1,1,-1,-1,0,-1,0,0,0,1,1,-1,0,-1,0,0,0,1;/(7)得分int score=0;/(8)下一個(gè)方塊shape next=0;/(9)當(dāng)前方塊shape current=0;/(10)當(dāng)前方塊的每一部分坐標(biāo)int current_coordinate42=0;/(11)游戲桌面int tableROWSCOLUMS=0;/(12)當(dāng)前方塊的x坐標(biāo)int shapex=0;/(13)當(dāng)前方塊的y坐標(biāo)int shapey=0;/(14)方塊下移速度int speed=0;/(15)每一幀開始時(shí)間clock_t start=0;/(16)每一幀結(jié)束時(shí)間clock_t finish=0;/(17)windows繪圖用變量HWND gameWND;HBITMAP memBM;HBITMAP memBMOld;HDC memDC;RECT clientRC;HBRUSH blackBrush;HBRUSH stoneBrush;HBRUSH shapeBrushSHAPE_COUNT;HPEN grayPen;HFONT bigFont;HFONT smallFont;/4.主要處理函數(shù)/(1)取最大坐標(biāo)int maxX()int i=0;int x=current_coordinatei0;int m=x;for(i=1;i<BLOCK_COUNT;i+)x=current_coordinatei0;if(m<x)m=x;return m;/(2)取最小坐標(biāo)int minX()int i=0;int x=current_coordinatei0;int m=x;for(i=1;i<BLOCK_COUNT;i+)x=current_coordinatei0;if(m>x)m=x;return m;/(3)逆時(shí)針轉(zhuǎn)動(dòng)方塊void turn_left()int i=0;int x,y;for(i=0;i<4;i+)x=current_coordinatei0;y=current_coordinatei1;current_coordinatei0=y;current_coordinatei1=-x;/(4)順時(shí)針旋轉(zhuǎn)方塊void turn_right()int i=0;int x,y;for(i=0;i<4;i+)x=current_coordinatei0;y=current_coordinatei1;current_coordinatei0=-y;current_coordinatei1=x;/(5)檢查方塊是否越界int out_of_table()int i=0;int x,y;for(i=0;i<4;i+)x=shapex+current_coordinatei0;y=shapey+current_coordinatei1;if(x<0|x>(COLUMS-1)|y>(ROWS-1)return 1;if(tableyx)return 1;return 0;/(6)旋轉(zhuǎn)方塊void transform()if(current=SquareShape)return ;turn_right();if(out_of_table()turn_left();/(7)判斷方塊是否向左移動(dòng)int leftable()int i=0;int x,y;for(i=0;i<4;i+)x=shapex+current_coordinatei0;y=shapey+current_coordinatei1;if(x<=0|tableyx-1=1)return 0;return 1;/(8)判斷方塊是否向右移動(dòng)int rightable()int i=0;int x,y;for(i=0;i<4;i+)x=shapex+current_coordinatei0;y=shapey+current_coordinatei1;if(x>=(COLUMS-1)|tableyx+1=1)return 0;return 1;/(9)判斷方塊是否向下移動(dòng)int downable()int i=0;int x,y;for(i=0;i<4;i+)x=shapex+current_coordinatei0;y=shapey+current_coordinatei1;if(y>=(ROWS-1)|tabley+1x=1)return 0;return 1;/(10)向左移動(dòng)當(dāng)前方塊void move_left()if(leftable()shapex-;/(11)向右移動(dòng)當(dāng)前方塊void move_right()if(rightable()shapex+;/(12)向下移動(dòng)當(dāng)前方塊void move_down()if(downable()shapey+;elseif(add_to_table()remove_full();next_shape();elsestate=game_over;/(13)將當(dāng)前方塊固定到桌面上int add_to_table()int i=0;int x,y;for(i=0;i<4;i+)x=shapex+current_coordinatei0;y=shapey+current_coordinatei1;if(y<0|tableyx=1)return 0;tableyx=1;return 1;/(14)刪除填滿的行void remove_full()int c=0;int i,j;for(i=ROWS-1;i>0;i-)c=0;for(j=0;j<COLUMS;j+)c+=tableij;if(c=COLUMS)memmove(table1,table0,sizeof(int)*COLUMS*i);memset(table0,0,sizeof(int)*COLUMS);score+;speed=(score/100)%MAX_SPEED;i+;else if(c=0)break;/(15)創(chuàng)建新游戲void new_game()memset(table,0,sizeof(int)*COLUMS*ROWS);start=clock();next=random(SHAPE_COUNT);score=0;speed=0;/(16)運(yùn)行游戲void run_game()finish=clock();if(finish-start)>(MAX_SPEED-speed)*100)move_down();start=clock();InvalidateRect(gameWND,NULL,TRUE);/(17)操作當(dāng)前方塊void next_shape()current=next;memcpy(current_coordinate,shape_coordinatenext,sizeof(int)*BLOCK_COUNT*2);shapex=(COLUMS-(maxX(current)-minX(current)/2;shapey=0;next=random(SHAPE_COUNT);/(18)取隨機(jī)數(shù) int random(int seed) if(seed=0) return 0; srand(unsigned)time(NULL); return (rand()%seed); /(19)繪圖 void paint() PAINTSTRUCT ps; HDC hdc; draw_table(); hdc=BeginPaint(gameWND,&ps); BitBlt(hdc,clientRC.left,clientRC.top,clientRC.right,clientRC.bottom,memDC,0,0,SRCCOPY); EndPaint(gameWND,&ps); /(20)繪制游戲桌面 void draw_table() HBRUSH hBrushOld; HPEN hPenOld; HFONT hFontOld; RECT rc; int x0,y0,w; int x,y,i,j; char* str; w=clientRC.bottom/(ROWS+2); x0=y0=w; FillRect(memDC,&clientRC,blackBrush); / 如果游戲是開始或結(jié)束狀態(tài) if(state=game_start|state=game_over) memcpy(&rc,&clientRC,sizeof(RECT); rc.bottom=rc.bottom/2; hFontOld=SelectObject(memDC,bigFont); SetBkColor(memDC,BLACK); /如果游戲是開始狀態(tài),用黃色字顯示游戲開始畫面 if(state=game_start) str=APP_TITLE; SetTextColor(memDC,YELLOW); /如果游戲是結(jié)束狀態(tài),用紅色字顯示GAME OVER else str=GAMEOVER; SetTextColor(memDC,RED); DrawText(memDC,str,strlen(str),&rc,DT_SINGLELINE|DT_CENTER|DT_BOTTOM); SelectObject(memDC,hFontOld); hFontOld=SelectObject(memDC,smallFont); rc.top=rc.bottom; rc.bottom=rc.bottom*2; if(state=game_over) SetTextColor(memDC,YELLOW); sprintf(score_char,SCORE,score); DrawText(memDC,score_char,strlen(score_char),&rc,DT_SINGLELINE|DT_CENTER|DT_TOP); SetTextColor(memDC,STONE); DrawText(memDC,press_enter,strlen(press_enter),&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER); SelectObject(memDC,hFontOld); return; /桌面上殘留的方塊 hBrushOld=SelectObject(memDC,stoneBrush); for(i=0;i<ROWS;i+) for(j=0;j<COLUMS;j+) if(tableij=1) x=x0+j*w; y=y0+i*w; Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /畫當(dāng)前的方塊 hBrushOld=SelectObject(memDC,shapeBrushcurrent); for(i=0;i<4;i+) x=x0+(current_coordinatei0+shapex)*w; y=y0+(current_coordinatei1+shapey)*w; if(x<x0|y<y0) continue; Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /畫桌面上的表格線 hPenOld=SelectObject(memDC,grayPen); for(i=0;i<=ROWS;i+) MoveToEx(memDC,x0,y0+i*w,NULL); LineTo(memDC,x0+COLUMS*w,y0+i*w); for(i=0;i<=COLUMS;i+) MoveToEx(memDC,x0+i*w,y0,NULL); LineTo(memDC,x0+i*w,y0+ROWS*w); SelectObject(memDC,hPenOld); /畫玩家得分 x0=x0+COLUMS*w+3*w; y0=y0+w; hFontOld=SelectObject(memDC,smallFont); SetTextColor(memDC,YELLOW); sprintf(score_char,SCORE,score); TextOut(memDC,x0,y0,score_char,strlen(score_char); /畫下一個(gè)方塊 y0+=w; SetTextColor(memDC,STONE); TextOut(memDC,x0,y0,"NEXT",4); x0+=w; y0+=2*w; hBrushOld=SelectObject(memDC,shapeBrushnext); for(i=0;i<4;i+) x=x0+shape_coordinatenexti0*w; y=y0+shape_coordinatenexti1*w; Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /打印幫助信息 x0=(COLUMS+2)*w; y0+=4*w; SetTextColor(memDC,GRAY); i=0; while(helpi) TextOut(memDC,x0,y0,helpi,strlen(helpi); y0+=w; i+; SelectObject(memDC,hFontOld); /(21)處理按鍵 void key_down(WPARAM wParam) /如果游戲不是運(yùn)行狀態(tài),按下回車鍵 if(state!=game_run) if(wParam=VK_RETURN) switch(state)case game_start:next_shape();state=game_run;break;case game_pause:state=game_run;break;case game_over:new_game();next_shape();state=game_run;break; /如果游戲狀態(tài)是運(yùn)行 else switch(wParam) case VK_SPACE: case VK_UP: transform(); break; case VK_LEFT: move_left(); break; case VK_RIGHT: move_right(); break; case VK_DOWN: move_down(); break; case VK_RETURN: state=game_pause; break; InvalidateRect(gameWND,NULL,TRUE); /(22)改變窗口大小 void resize() HDC hdc; LOGFONT lf; hdc=GetDC(gameWND); GetClientRect(gameWND,&clientRC); SelectObject(memDC,memBMOld); DeleteObject(memBM); memBM=CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom); memBMOld=SelectObject(memDC,memBM); DeleteObject(bigFont); memset(&lf,0,sizeof(LOGFONT); lf.lfWidth=(clientRC.right-clientRC.left)/CHARS_IN_LINE; lf.lfHeight=(clientRC.bottom-clientRC.top)/4; lf.lfItalic=1; lf.lfWeight=FW_BOLD; bigFont=CreateFontIndirect(&lf); DeleteObject(smallFont); lf.lfHeight=clientRC.bottom/(ROWS+2); lf.lfWidth=lf.lfHeight/2; lf.lfItalic=0; lf.lfWeight=FW_NORMAL; smallFont=CreateFontIndirect(&lf); ReleaseDC(gameWND,hdc); /(23)處理消息 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) switch(message) case WM_SIZE: resize(); return 0; case WM_ERASEBKGND: return 0; case WM_PAINT: paint(); return 0; case WM_KEYDOWN: key_down(wParam); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; /其他消息用Windows默認(rèn)的消息處理函數(shù)處理return DefWindowProc(hwnd,message,wParam,lParam); /(24)初始化 void initialize() LOGFONT lf; HDC hdc; int i; hdc=GetDC(gameWND); GetClientRect(gameWND,&clientRC); memDC=CreateCompatibleDC(hdc); memBM=CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom); memBMOld=SelectObject(memDC,memBM); blackBrush=CreateSolidBrush(BLACK); stoneBrush=CreateSolidBrush(STONE); /創(chuàng)建每個(gè)方塊對應(yīng)顏色的畫筆 for(i=0;i<SHAPE_COUNT;i+) shapeBrushi=CreateSolidBrush(shape_colori); grayPen=CreatePen(PS_SOLID,1,GRAY); memset(&lf,0,sizeof(LOGFONT); /創(chuàng)建一個(gè)大字體 lf.lfWidth=(clientRC.right-clientRC.left)/CHARS_IN_LINE; lf.lfHeight=(clientRC.bottom-clientRC.top)/4; lf.lfItalic=0; lf.lfWeight=FW_NORMAL; smallFont=CreateFontIndirect(&lf); ReleaseDC(gameWND,hdc); /(25)釋放資源 void finalize() int i=0; DeleteObject(blackBrush); DeleteObject(stoneBrush); for(i=0;i<SHAPE_COUNT;i+) DeleteObject(shapeBrushi); DeleteObject(grayPen); DeleteObject(bigFont); DeleteObject(smallFont); SelectObject(memDC,memBMOld); DeleteObject(memBM); DeleteObject(memDC); /(26) 入口函數(shù) int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) MSG msg; WNDCLASS wndclass; /設(shè)置窗口樣式 wndclass.style=CS_HREDRAW|CS_VREDRAW; wndclass.lpfnWndProc=WndProc; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hInstance=hInstance; wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName=NULL; wndclass.lpszClassName=APP_NAME; RegisterClass(&wndclass); /創(chuàng)建Windows窗口 gameWND=CreateWindow(APP_NAME, APP_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance,NULL); initialize(); ShowWindow(gameWND,iCmdShow); UpdateWindow(gameWND); new_game(); for(;) if(state=game_run) run_game(); /判斷是否有Windows消息 if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE) if(GetMessage(&msg,NULL,0,0) TranslateMessage(&msg); DispatchMessage(&msg); else break; finalize(); return msg.wParam;