C++制造俄羅斯方塊。本站提示廣大學習愛好者:(C++制造俄羅斯方塊)文章只能為提供參考,不一定能成為您想要的結果。以下是C++制造俄羅斯方塊正文
緣起:
在玩Codeblocks自帶的俄羅斯方塊時認為不錯,但是有時光限制。所以想本身再寫一個。
法式後果:
重要內容:
法式中有一個board數組,個中有要顯示的部門,也有不顯示的部門,不顯示的部門都存儲1。
以下圖:
shape采取4*4數組(shape)保留。如:
0 0 0 0
0 1 0 0
1 1 1 0
0 0 0 0
別的用變量row和column保留shape數組左上角在board中的地位。
每次著落或閣下挪動,先對row和column做出轉變,然後檢測以後row和column下,shape能否重合了為1的格子,假如有重合,就解釋shape出界了或許達到著落最低點,則要恢復row和column值。別的,假如是著落,還要將shape放在board上,並發生新的shape。
扭轉時,先對shape數組停止扭轉操作,然後檢測重合,假如有重合,則反向扭轉回來。
代碼:
#if defined(UNICODE) && !defined(_UNICODE) #define _UNICODE #elif defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include <tchar.h> #include <windows.h> #include <pthread.h> #include <stdio.h> #include <time.h> /*-----------------宏界說--------------------------------------------------------*/ #define WIDTH 180 #define HEIGHT 400 #define LONG_SLEEP 300 #define BKCOLOR RGB(238,238,238)//配景色 /*-----------------變量----------------------------------------------------------*/ static int shapes[7][4][4];//存儲7個外形 static int high_score[4]= {0,0,0,0};//前三個元素存儲最高分,最初一個元素存儲此次得分 static int **shape;//以後外形 static int **board; static int M=15;//顯示的列數 static int N=30;//顯示的行數 static int MM=M+8;//board的列數 static int NN=N+4;//board的行數 static int LEFT=4;//顯示的最左一列 static int RIGHT=LEFT+M-1;//顯示的最右一列 static int TOP=0;//顯示的最上一列 static int BOTTOM=N-1;//顯示的最下一列 static int score=0; static int row=0;//外形地點行 static int column=MM/2;//外形坐在列 static bool is_pause=false; static HBRUSH grey_brush =CreateSolidBrush (RGB(210,210,210)); static HBRUSH white_brush =CreateSolidBrush (RGB(130,130,130)); static HBRUSH bk_brush =CreateSolidBrush (BKCOLOR); static HPEN hPen = CreatePen(PS_SOLID,1,RGB(147,155,166)); static int lattices_top=40;//下面留白 static int lattices_left=20;//左邊留白 static int width=WIDTH/M;//每一個格子的寬度 static int height=(HEIGHT-lattices_top)/N;//每一個格子的高度 /*-----------------函數-----------------------------------------------------------*/ void add_score() ; bool check_is_lose() ; void clear_up() ;//清除沒有空格子的行 void* down_thread_function(void * args) ;//外形著落過程要履行的函數 void exit_game(HWND hwnd) ; void give_new_shape() ;//隨機生成一個新外形 int handle_key(HWND hwnd,WPARAM wParam) ; int init_down_thread(HWND hwnd) ;//初始化外形著落過程 int init_game(HWND hwnd) ;//初始化游戲法式 void init_play() ;//初始化游戲數據 bool is_legel() ;//檢測外形在以後地位能否正當(等於否重合了非空的格子) int load_scores(int* a) ;//讀取游戲最高分數據 int load_shape() ;//從文件中加載7個外形 void lose_game(HWND hwnd) ; int move_down(HWND hwnd) ;//外形著落 int move_lr(HWND hwnd,int lr) ;//外形閣下挪動 void paint_lattice(HDC hdc,int x,int y,int color) ;//顯示一個格子 void paint_UI(HDC hdc) ;//畫界面 void reset_rc() ; void rerotate_matrix(int mn) ;//順時針扭轉一個行列數為mn的方陣 void rotate_matrix(int mn) ;//逆時針扭轉一個行列數為mn的方陣 int rotate_shape(HWND hwnd) ;//扭轉以後外形並更新界面 bool save_score(HWND hwnd) ;//保留最高分數據 void shape_to_ground() ;//以後外形落地以後,更新board bool sort_scores(int* a) ;//對最高分和此次得分排序,若發明新記載則前往true void update_UI(HWND hwnd) ;//更新界面,僅更新Rect區域(外形地點的那幾行)內 void update_UI_all(HWND hwnd) ;//更新界面,更新全部界面 int write_scores(int* a) ;//寫最高分數據 /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ TCHAR szClassName[ ] = _T("Tris"); int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground =bk_brush; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ _T("Tris"), /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ WIDTH+200, /* The programs width */ HEIGHT+70, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nCmdShow); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } //從文件中加載7個外形 int load_shape() { FILE* f=fopen("shapes.txt","rb"); if(f==NULL) { return -1; } for(int i=0; i<7; i++) { for(int j=0; j<4; j++) { for(int k=0; k<4; k++) { if(fscanf(f,"%d",&shapes[i][j][k])!=1) { return -1; } } } } fclose(f); return 0; } //隨機生成一個新外形 void give_new_shape() { int shape_num=rand()%7; for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { shape[i][j]=shapes[shape_num][i][j]; } } } void add_score() { score+=100; } //清除沒有空格子的行 void clear_up() { for(int i=row; i<=row+3; i++) { if(i>BOTTOM)continue; bool there_is_blank=false; for(int j=LEFT; j<=RIGHT; j++) { if(board[i][j]==0) { there_is_blank=true; break; } } if(!there_is_blank) { add_score(); for(int r=i; r>=1; r--) { for(int c=LEFT; c<=RIGHT; c++) { board[r][c]=board[r-1][c]; } } } } } //檢測外形在以後地位能否正當(等於否重合了非空的格子) bool is_legel() { for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { if(shape[i][j]==1&&board[row+i][column+j]==1) { return false; } } } return true; } //逆時針扭轉一個行列數為mn的方陣 void rotate_matrix(int mn) { int** a=shape; int s=0; for(int n=mn; n>=1; n-=2) { for(int i=0; i<n-1; i++) { int t=a[s+i][s]; a[s+i][s]=a[s][s+n-i-1]; a[s][s+n-i-1]=a[s+n-i-1][s+n-1]; a[s+n-i-1][s+n-1]=a[s+n-1][s+i]; a[s+n-1][s+i]=t; } s++; } } //順時針扭轉一個行列數為mn的方陣 void rerotate_matrix(int mn) { int** a=shape; int s=0; for(int n=mn; n>=1; n-=2) { for(int i=0; i<n-1; i++) { int t=a[s+i][s]; a[s+i][s]=a[s+n-1][s+i]; a[s+n-1][s+i]=a[s+n-i-1][s+n-1]; a[s+n-i-1][s+n-1]=a[s][s+n-i-1]; a[s][s+n-i-1]=t; } s++; } } //顯示一個格子 void paint_lattice(HDC hdc,int x,int y,int color) { if(x<TOP||x>BOTTOM||y<LEFT||y>RIGHT) { return ; } x-=TOP; y-=LEFT; int left=lattices_left+y*width; int right=lattices_left+y*width+width; int top=lattices_top+x*height; int bottom=lattices_top+x*height+height; MoveToEx (hdc,left,top, NULL) ; LineTo (hdc,right,top) ; MoveToEx (hdc,left,top, NULL) ; LineTo (hdc,left,bottom) ; MoveToEx (hdc,left,bottom, NULL) ; LineTo (hdc,right,bottom) ; MoveToEx (hdc,right,top, NULL) ; LineTo (hdc,right,bottom) ; SelectObject(hdc, grey_brush); if(color==0) { SelectObject(hdc, white_brush); } Rectangle(hdc,left,top,right,bottom); } //更新界面,僅更新Rect區域(外形地點的那幾行)內 void update_UI(HWND hwnd) { static RECT rect; rect.left=lattices_left; rect.right=lattices_left+M*width+width; rect.top=lattices_top+(row-1)*height; rect.bottom=lattices_top+(row+4)*height; InvalidateRect (hwnd,&rect, false) ; } //更新界面,更新全部界面 void update_UI_all(HWND hwnd) { InvalidateRect (hwnd,NULL, false) ; } //畫界面 void paint_UI(HDC hdc) { SetBkColor(hdc,BKCOLOR); SelectObject(hdc,hPen); //選用畫筆 char score_str[20]; sprintf(score_str,"Score:%d",score); TextOut(hdc,10,10,score_str,strlen(score_str)); sprintf(score_str,"Highest Scores:"); TextOut(hdc,WIDTH+50,50,score_str,strlen(score_str)); for(int i=0; i<3; i++) { sprintf(score_str,"%d",high_score[i]); TextOut(hdc,WIDTH+50,50+(i+1)*20,score_str,strlen(score_str)); } for(int i=TOP; i<=BOTTOM; i++) { for(int j=LEFT; j<=RIGHT; j++) { paint_lattice(hdc,i,j,board[i][j]); } } for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { if(shape[i][j]==1) paint_lattice(hdc,row+i,column+j,shape[i][j]); } } } //扭轉以後外形並更新界面 int rotate_shape(HWND hwnd) { int mn=4; rotate_matrix(mn); if(!is_legel()) { rerotate_matrix(mn); } update_UI(hwnd); } void reset_rc() { row=0; column=MM/2-2; } //讀取游戲最高分數據 int load_scores(int* a) { FILE* f=fopen("scores.txt","r"); if(f==NULL)return -1; fscanf(f,"%d%d%d",&a[0],&a[1],&a[2]); return 0; } //初始化游戲數據 void init_play() { load_scores(high_score); for(int i=0; i<NN; i++) { for(int j=0; j<MM; j++) { board[i][j]=0; } } for(int i=0; i<N; i++) { for(int j=0; j<LEFT; j++) { board[i][j]=1; } } for(int i=0; i<N; i++) { for(int j=RIGHT+1; j<MM; j++) { board[i][j]=1; } } for(int i=BOTTOM+1; i<NN; i++) { for(int j=0; j<MM; j++) { board[i][j]=1; } } reset_rc(); score=0; give_new_shape(); is_pause=false; return ; } bool check_is_lose() { if(row==0)return true; return false; } //對最高分和此次得分排序,若發明新記載則前往true bool sort_scores(int* a) { int temp=a[3]; for(int i=0; i<4; i++) { for(int j=0; j<3; j++) { if(a[j]<a[j+1]) { int t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } if(temp>a[3])return true; return false; } //寫最高分數據 int write_scores(int* a) { FILE* f=fopen("scores.txt","w"); if(f==NULL)return -1; fprintf(f,"%d\n%d\n%d\n",a[0],a[1],a[2]); return 0; } //保留最高分數據 bool save_score(HWND hwnd) { high_score[3]=score; bool made_record=sort_scores(high_score); if(write_scores(high_score)!=0) { MessageBox(hwnd,"Write file error.Program will exit.","Error",NULL); DestroyWindow(hwnd); } return made_record; } void lose_game(HWND hwnd) { if(is_pause)return ; is_pause=true; char message[200]="You lose the Game.\n"; char title[50]="Game Over"; if(save_score(hwnd)) { strcat(message,"You have made a new record.\n"); char score_str[100]; sprintf(score_str,"The Highest Scores:\n%d\n%d\n%d\n",high_score[0],high_score[1],high_score[2]); strcat(message,score_str); } strcat(message,"\nPlay again?\n"); if(MessageBox(hwnd,message,title,MB_YESNO)==IDYES) { init_play(); update_UI_all(hwnd); } else { exit(0); } } void exit_game(HWND hwnd) { is_pause=true; char message[200]=""; char title[50]="Exit"; if(save_score(hwnd)) { strcat(message,"You have made a new record.\n"); char score_str[100]; sprintf(score_str,"The Highest Scores:\n%d\n%d\n%d\n",high_score[0],high_score[1],high_score[2]); strcat(message,score_str); MessageBox(hwnd,message,title,NULL); } exit(0); } //以後外形落地以後,更新board void shape_to_ground() { for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { board[row+i][column+j]=shape[i][j]==1?1:board[row+i][column+j]; } } } //外形著落 int move_down(HWND hwnd) { row++; if(!is_legel()) { row--; if(check_is_lose()) { lose_game(hwnd); return 0; } shape_to_ground(); clear_up(); update_UI_all(hwnd); reset_rc(); give_new_shape(); } update_UI(hwnd); } //過程參數構造體 struct thread_arg { HWND arg_hwnd; }; //外形著落過程要履行的函數 void* down_thread_function(void * args) { thread_arg *arg=(thread_arg*)args; HWND dhwnd=arg->arg_hwnd; while(true) { if(is_pause) { Sleep(300); continue; } move_down(dhwnd); Sleep(LONG_SLEEP); } } //初始化外形著落過程 int init_down_thread(HWND hwnd) { int ret; pthread_t t; thread_arg *argp=new thread_arg; argp->arg_hwnd=hwnd; ret=pthread_create(&t,NULL,down_thread_function,argp); delete argp; if(ret!=0) { return -1; } return 0; } //初始化游戲法式 int init_game(HWND hwnd) { board=new int*[NN]; for(int i=0; i<NN; i++) { board[i]=new int[MM]; } shape=new int*[4]; for(int i=0; i<4; i++) { shape[i]=new int[4]; } srand(time(0)); if(load_shape()!=0) { MessageBox(hwnd,"Read file error.Program will exit.","Error",NULL); exit(-1); } init_play(); update_UI_all(hwnd); if(init_down_thread(hwnd)!=0) { MessageBox(hwnd,"Thread error.Program will exit.","Error",NULL); exit(-1); } return 0; } //外形閣下挪動 int move_lr(HWND hwnd,int lr) { int temp=column; if(lr==0)column--; else { column++; } if(!is_legel()) { column=temp; } update_UI(hwnd); } int handle_key(HWND hwnd,WPARAM wParam) { if(wParam==VK_ESCAPE) {//ESC加入 exit_game(hwnd); } if(wParam==VK_SPACE) {//空格暫停 is_pause=!is_pause; } if(is_pause==true) { Sleep(300); return 0; } if(wParam==VK_UP) { rotate_shape(hwnd); } if(wParam==VK_DOWN) { move_down(hwnd); } if(wParam==VK_LEFT) { move_lr(hwnd,0); } if(wParam==VK_RIGHT) { move_lr(hwnd,1); } return 0; } /* This function is called by the Windows function DispatchMessage() */ HWND hwnd; LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hdc; static HDC hdcBuffer; static HBITMAP hBitMap; static PAINTSTRUCT ps ; switch (message) { /* handle the messages */ case WM_CREATE: init_game(hwnd); break; case WM_KEYDOWN: handle_key(hwnd,wParam); break; case WM_DESTROY: exit_game(hwnd); PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; paint_UI(hdc); EndPaint (hwnd, &ps) ; break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }