C语言实现俄罗斯方块游戏
生活随笔
收集整理的這篇文章主要介紹了
C语言实现俄罗斯方块游戏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、首先放上全部源碼:
1 #include <stdio.h> 2 #include <windows.h> 3 #include <conio.h> 4 #include <time.h> 5 //游戲窗口 6 #define FrameX 4 //游戲窗口左上角的X軸坐標 7 #define FrameY 4 //游戲窗口左上角的Y軸坐標 8 #define Frame_height 20 //游戲窗口的高度 9 #define Frame_width 18 //游戲窗口的寬度 10 //定義全局變量 11 int i,j,temp,temp1,temp2; //temp,temp1,temp2用于記住和轉換方塊變量的值 12 int a[80][80]={0}; //標記游戲屏幕的圖案:2,1,0分別表示該位置為游戲邊框、方塊、無圖案;初始化為無圖案 13 int b[4]; //標記4個"口"方塊:1表示有方塊,0表示無方塊 14 15 //聲明俄羅斯方塊的結構體 16 struct Tetris 17 { 18 int x; //中心方塊的x軸坐標 19 int y; //中心方塊的y軸坐標 20 int flag; //標記方塊類型的序號 21 int next; //下一個俄羅斯方塊類型的序號 22 int speed; //俄羅斯方塊移動的速度 23 int count; //產生俄羅斯方塊的個數 24 int score; //游戲的分數 25 int level; //游戲的等級 26 }; 27 //函數原型聲明 28 //光標移到指定位置 29 void gotoxy(HANDLE hOut, int x, int y); 30 //制作游戲窗口 31 void make_frame(); 32 //隨機產生方塊類型的序號 33 void get_flag(struct Tetris *); 34 //制作俄羅斯方塊 35 void make_tetris(struct Tetris *); 36 //打印俄羅斯方塊 37 void print_tetris(HANDLE hOut,struct Tetris *); 38 //清除俄羅斯方塊的痕跡 39 void clear_tetris(HANDLE hOut,struct Tetris *); 40 //判斷是否能移動,返回值為1,能移動,否則,不動 41 int if_moveable(struct Tetris *); 42 //判斷是否滿行,并刪除滿行的俄羅斯方塊 43 void del_full(HANDLE hOut,struct Tetris *); 44 //開始游戲 45 void start_game(); 46 47 int main() 48 { 49 //制作游戲窗口 50 make_frame(); 51 //開始游戲 52 start_game(); 53 } 54 /******光標移到指定位置**************************************************************/ 55 void gotoxy(HANDLE hOut, int x, int y) 56 { 57 COORD pos; 58 pos.X = x; //橫坐標 59 pos.Y = y; //縱坐標 60 SetConsoleCursorPosition(hOut, pos); 61 } 62 /******制作游戲窗口******************************************************************/ 63 void make_frame() 64 { 65 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定義顯示器句柄變量 66 gotoxy(hOut,FrameX+Frame_width-5,FrameY-2); //打印游戲名稱 67 printf("俄羅斯方塊"); 68 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7); //打印選擇菜單 69 printf("**********下一個方塊:"); 70 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13); 71 printf("**********"); 72 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17); 73 printf("↑鍵:變體"); 74 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19); 75 printf("空格:暫停游戲"); 76 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15); 77 printf("Esc :退出游戲"); 78 gotoxy(hOut,FrameX,FrameY); //打印框角并記住該處已有圖案 79 printf("╔"); 80 gotoxy(hOut,FrameX+2*Frame_width-2,FrameY); 81 printf("╗"); 82 gotoxy(hOut,FrameX,FrameY+Frame_height); 83 printf("╚"); 84 gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height); 85 printf("╝"); 86 a[FrameX][FrameY+Frame_height]=2; 87 a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2; 88 for(i=2;i<2*Frame_width-2;i+=2) 89 { 90 gotoxy(hOut,FrameX+i,FrameY); 91 printf("═"); //打印上橫框 92 } 93 for(i=2;i<2*Frame_width-2;i+=2) 94 { 95 gotoxy(hOut,FrameX+i,FrameY+Frame_height); 96 printf("═"); //打印下橫框 97 a[FrameX+i][FrameY+Frame_height]=2; //記住下橫框有圖案 98 } 99 for(i=1;i<Frame_height;i++) 100 { 101 gotoxy(hOut,FrameX,FrameY+i); 102 printf("║"); //打印左豎框 103 a[FrameX][FrameY+i]=2; //記住左豎框有圖案 104 } 105 for(i=1;i<Frame_height;i++) 106 { 107 gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i); 108 printf("║"); //打印右豎框 109 a[FrameX+2*Frame_width-2][FrameY+i]=2; //記住右豎框有圖案 110 } 111 } 112 /******制作俄羅斯方塊********************************************************************/ 113 void make_tetris(struct Tetris *tetris) 114 { 115 a[tetris->x][tetris->y]=b[0]; //中心方塊位置的圖形狀態:1-有,0-無 116 switch(tetris->flag) //共6大類,19種類型 117 { 118 case 1: //田字方塊 119 { 120 a[tetris->x][tetris->y-1]=b[1]; 121 a[tetris->x+2][tetris->y-1]=b[2]; 122 a[tetris->x+2][tetris->y]=b[3]; 123 break; 124 } 125 case 2: //直線方塊:---- 126 { 127 a[tetris->x-2][tetris->y]=b[1]; 128 a[tetris->x+2][tetris->y]=b[2]; 129 a[tetris->x+4][tetris->y]=b[3]; 130 break; 131 } 132 case 3: //直線方塊: | 133 { 134 a[tetris->x][tetris->y-1]=b[1]; 135 a[tetris->x][tetris->y-2]=b[2]; 136 a[tetris->x][tetris->y+1]=b[3]; 137 break; 138 } 139 case 4: //T字方塊 140 { 141 a[tetris->x-2][tetris->y]=b[1]; 142 a[tetris->x+2][tetris->y]=b[2]; 143 a[tetris->x][tetris->y+1]=b[3]; 144 break; 145 } 146 case 5: //T字順時針轉90度方塊 147 { 148 a[tetris->x][tetris->y-1]=b[1]; 149 a[tetris->x][tetris->y+1]=b[2]; 150 a[tetris->x-2][tetris->y]=b[3]; 151 break; 152 } 153 case 6: //T字順時針轉180度方塊 154 { 155 a[tetris->x][tetris->y-1]=b[1]; 156 a[tetris->x-2][tetris->y]=b[2]; 157 a[tetris->x+2][tetris->y]=b[3]; 158 break; 159 } 160 case 7: //T字順時針轉270度方塊 161 { 162 a[tetris->x][tetris->y-1]=b[1]; 163 a[tetris->x][tetris->y+1]=b[2]; 164 a[tetris->x+2][tetris->y]=b[3]; 165 break; 166 } 167 case 8: //Z字方塊 168 { 169 a[tetris->x][tetris->y+1]=b[1]; 170 a[tetris->x-2][tetris->y]=b[2]; 171 a[tetris->x+2][tetris->y+1]=b[3]; 172 break; 173 } 174 case 9: //Z字順時針轉90度方塊 175 { 176 a[tetris->x][tetris->y-1]=b[1]; 177 a[tetris->x-2][tetris->y]=b[2]; 178 a[tetris->x-2][tetris->y+1]=b[3]; 179 break; 180 } 181 case 10: //Z字順時針轉180度方塊 182 { 183 a[tetris->x][tetris->y-1]=b[1]; 184 a[tetris->x-2][tetris->y-1]=b[2]; 185 a[tetris->x+2][tetris->y]=b[3]; 186 break; 187 } 188 case 11: //Z字順時針轉270度方塊 189 { 190 a[tetris->x][tetris->y+1]=b[1]; 191 a[tetris->x+2][tetris->y-1]=b[2]; 192 a[tetris->x+2][tetris->y]=b[3]; 193 break; 194 } 195 case 12: //7字方塊 196 { 197 a[tetris->x][tetris->y-1]=b[1]; 198 a[tetris->x][tetris->y+1]=b[2]; 199 a[tetris->x-2][tetris->y-1]=b[3]; 200 break; 201 } 202 case 13: //7字順時針轉90度方塊 203 { 204 a[tetris->x-2][tetris->y]=b[1]; 205 a[tetris->x-2][tetris->y+1]=b[2]; 206 a[tetris->x+2][tetris->y]=b[3]; 207 break; 208 } 209 case 14: //7字順時針轉180度方塊 210 { 211 a[tetris->x][tetris->y-1]=b[1]; 212 a[tetris->x][tetris->y+1]=b[2]; 213 a[tetris->x+2][tetris->y+1]=b[3]; 214 break; 215 } 216 case 15: //7字順時針轉270度方塊 217 { 218 a[tetris->x-2][tetris->y]=b[1]; 219 a[tetris->x+2][tetris->y-1]=b[2]; 220 a[tetris->x+2][tetris->y]=b[3]; 221 break; 222 } 223 case 16: //倒7字方塊 224 { 225 a[tetris->x][tetris->y+1]=b[1]; 226 a[tetris->x][tetris->y-1]=b[2]; 227 a[tetris->x+2][tetris->y-1]=b[3]; 228 break; 229 } 230 case 17: //倒7字順指針轉90度方塊 231 { 232 a[tetris->x-2][tetris->y]=b[1]; 233 a[tetris->x-2][tetris->y-1]=b[2]; 234 a[tetris->x+2][tetris->y]=b[3]; 235 break; 236 } 237 case 18: //倒7字順時針轉180度方塊 238 { 239 a[tetris->x][tetris->y-1]=b[1]; 240 a[tetris->x][tetris->y+1]=b[2]; 241 a[tetris->x-2][tetris->y+1]=b[3]; 242 break; 243 } 244 case 19: //倒7字順時針轉270度方塊 245 { 246 a[tetris->x-2][tetris->y]=b[1]; 247 a[tetris->x+2][tetris->y+1]=b[2]; 248 a[tetris->x+2][tetris->y]=b[3]; 249 break; 250 } 251 } 252 } 253 //******判斷是否可動*************************************************************************/ 254 int if_moveable(struct Tetris *tetris) 255 { 256 if(a[tetris->x][tetris->y]!=0)//當中心方塊位置上有圖案時,返回值為0,即不可移動 257 { 258 return 0; 259 } 260 else 261 { 262 if( //當為田字方塊且除中心方塊位置外,其他"口"字方塊位置上無圖案時,返回值為1,即可移動 263 ( tetris->flag==1 && ( a[tetris->x][tetris->y-1]==0 && 264 a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 265 //或為直線方塊且除中心方塊位置外,其他"口"字方塊位置上無圖案時,返回值為1,即可移動 266 ( tetris->flag==2 && ( a[tetris->x-2][tetris->y]==0 && 267 a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) ) || 268 ( tetris->flag==3 && ( a[tetris->x][tetris->y-1]==0 && 269 a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) ) || 270 ( tetris->flag==4 && ( a[tetris->x-2][tetris->y]==0 && 271 a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) ) || 272 ( tetris->flag==5 && ( a[tetris->x][tetris->y-1]==0 && 273 a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) ) || 274 ( tetris->flag==6 && ( a[tetris->x][tetris->y-1]==0 && 275 a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 276 ( tetris->flag==7 && ( a[tetris->x][tetris->y-1]==0 && 277 a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 278 ( tetris->flag==8 && ( a[tetris->x][tetris->y+1]==0 && 279 a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || 280 ( tetris->flag==9 && ( a[tetris->x][tetris->y-1]==0 && 281 a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || 282 ( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0 && 283 a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 284 ( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0 && 285 a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 286 ( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0 && 287 a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) || 288 ( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0 && 289 a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 290 ( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0 && 291 a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || 292 ( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0 && 293 a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 294 ( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0 && 295 a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) || 296 ( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0 && 297 a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 298 ( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0 && 299 a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || 300 ( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0 && 301 a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ) 302 { 303 return 1; 304 } 305 } 306 return 0; 307 } 308 /******隨機產生俄羅斯方塊類型的序號**********************************************************/ 309 void get_flag(struct Tetris *tetris) 310 { 311 tetris->count++; //記住產生方塊的個數 312 srand((unsigned)time(NULL)); //初始化隨機數 313 if(tetris->count==1) 314 { 315 tetris->flag = rand()%19+1; //記住第一個方塊的序號 316 } 317 tetris->next = rand()%19+1; //記住下一個方塊的序號 318 } 319 /******打印俄羅斯方塊**********************************************************************/ 320 void print_tetris(HANDLE hOut,struct Tetris *tetris) 321 { 322 for(i=0;i<4;i++) 323 { 324 b[i]=1; //數組b[4]的每個元素的值都為1 325 } 326 make_tetris(tetris); //制作俄羅斯方塊 327 for( i=tetris->x-2; i<=tetris->x+4; i+=2 ) 328 { 329 for(j=tetris->y-2;j<=tetris->y+1;j++) 330 { 331 if( a[i][j]==1 && j>FrameY ) 332 { 333 gotoxy(hOut,i,j); 334 printf("□"); //打印邊框內的方塊 335 } 336 } 337 } 338 //打印菜單信息 339 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1); 340 printf("level : %d",tetris->level); 341 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3); 342 printf("score : %d",tetris->score); 343 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5); 344 printf("speed : %dms",tetris->speed); 345 } 346 /******清除俄羅斯方塊的痕跡****************************************************************/ 347 void clear_tetris(HANDLE hOut,struct Tetris *tetris) 348 { 349 for(i=0;i<4;i++) 350 { 351 b[i]=0; //數組b[4]的每個元素的值都為0 352 } 353 make_tetris(tetris); //制作俄羅斯方塊 354 for( i=tetris->x-2; i<=tetris->x+4; i+=2 ) 355 { 356 for(j=tetris->y-2;j<=tetris->y+1;j++) 357 { 358 if( a[i][j]==0 && j>FrameY ) 359 { 360 gotoxy(hOut,i,j); 361 printf(" "); //清除方塊 362 } 363 } 364 } 365 } 366 /******判斷是否滿行并刪除滿行的俄羅斯方塊****************************************************/ 367 void del_full(HANDLE hOut,struct Tetris *tetris) 368 { //當某行有Frame_width-2個方塊時,則滿行 369 int k,del_count=0; //分別用于記錄某行方塊的個數和刪除方塊的行數的變量 370 for(j=FrameY+Frame_height-1;j>=FrameY+1;j--) 371 { 372 k=0; 373 for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2) 374 { 375 if(a[i][j]==1) //豎坐標依次從下往上,橫坐標依次由左至右判斷是否滿行 376 { 377 k++; //記錄此行方塊的個數 378 if(k==Frame_width-2) 379 { 380 for(k=FrameX+2;k<FrameX+2*Frame_width-2;k+=2) 381 { //刪除滿行的方塊 382 a[k][j]=0; 383 gotoxy(hOut,k,j); 384 printf(" "); 385 Sleep(1); 386 } 387 for(k=j-1;k>FrameY;k--) 388 { //如果刪除行以上的位置有方塊,則先清除,再將方塊下移一個位置 389 for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2) 390 { 391 if(a[i][k]==1) 392 { 393 a[i][k]=0; 394 gotoxy(hOut,i,k); 395 printf(" "); 396 a[i][k+1]=1; 397 gotoxy(hOut,i,k+1); 398 printf("□"); 399 } 400 } 401 } 402 j++; //方塊下移后,重新判斷刪除行是否滿行 403 del_count++; //記錄刪除方塊的行數 404 } 405 } 406 } 407 } 408 tetris->score+=100*del_count; //每刪除一行,得100分 409 if( del_count>0 && ( tetris->score%1000==0 || tetris->score/1000>tetris->level-1 ) ) 410 { //如果得1000分即累計刪除10行,速度加快20ms并升一級 411 tetris->speed-=20; 412 tetris->level++; 413 } 414 } 415 /******開始游戲******************************************************************************/ 416 void start_game() 417 { 418 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定義顯示器句柄變量 419 struct Tetris t,*tetris=&t; //定義結構體的指針并指向結構體變量 420 unsigned char ch; //定義接收鍵盤輸入的變量 421 tetris->count=0; //初始化俄羅斯方塊數為0個 422 tetris->speed=300; //初始移動速度為300ms 423 tetris->score=0; //初始游戲的分數為0分 424 tetris->level=1; //初始游戲為第1關 425 while(1) 426 {//循環產生方塊,直至游戲結束 427 get_flag(tetris); //得到產生俄羅斯方塊類型的序號 428 temp=tetris->flag; //記住當前俄羅斯方塊序號 429 //打印下一個俄羅斯方塊的圖形(右邊窗口) 430 tetris->x=FrameX+2*Frame_width+6; 431 tetris->y=FrameY+10; 432 tetris->flag = tetris->next; 433 print_tetris(hOut,tetris); 434 tetris->x=FrameX+Frame_width; //初始中心方塊x坐標 435 tetris->y=FrameY-1; //初始中心方塊y坐標 436 tetris->flag=temp; //取出當前的俄羅斯方塊序號 437 while(1) 438 {//控制方塊方向,直至方塊不再下移 439 label:print_tetris(hOut,tetris);//打印俄羅斯方塊 440 Sleep(tetris->speed); //延緩時間 441 clear_tetris(hOut,tetris); //清除痕跡 442 temp1=tetris->x; //記住中心方塊橫坐標的值 443 temp2=tetris->flag; //記住當前俄羅斯方塊序號 444 if(kbhit()) 445 { //判斷是否有鍵盤輸入,有則用ch↓接收 446 ch=getch(); 447 if(ch==75) //按←鍵則向左動,中心橫坐標減2 448 { 449 tetris->x-=2; 450 } 451 if(ch==77) //按→鍵則向右動,中心橫坐標加2 452 { 453 tetris->x+=2; 454 } 455 if(ch==72) //按↑鍵則變體即當前方塊順時針轉90度 456 { 457 if( tetris->flag>=2 && tetris->flag<=3 ) 458 { 459 tetris->flag++; 460 tetris->flag%=2; 461 tetris->flag+=2; 462 } 463 if( tetris->flag>=4 && tetris->flag<=7 ) 464 { 465 tetris->flag++; 466 tetris->flag%=4; 467 tetris->flag+=4; 468 } 469 if( tetris->flag>=8 && tetris->flag<=11 ) 470 { 471 tetris->flag++; 472 tetris->flag%=4; 473 tetris->flag+=8; 474 } 475 if( tetris->flag>=12 && tetris->flag<=15 ) 476 { 477 tetris->flag++; 478 tetris->flag%=4; 479 tetris->flag+=12; 480 } 481 if( tetris->flag>=16 && tetris->flag<=19 ) 482 { 483 tetris->flag++; 484 tetris->flag%=4; 485 tetris->flag+=16; 486 } 487 } 488 if(ch==32) //按空格鍵,暫停 489 { 490 print_tetris(hOut,tetris); 491 while(1) 492 { 493 if(kbhit()) //再按空格鍵,繼續游戲 494 { 495 ch=getch(); 496 if(ch==32) 497 { 498 goto label; 499 } 500 } 501 } 502 } 503 if(if_moveable(tetris)==0) //如果不可動,上面操作無效 504 { 505 tetris->x=temp1; 506 tetris->flag=temp2; 507 } 508 else //如果可動,執行操作 509 { 510 goto label; 511 } 512 } 513 tetris->y++; //如果沒有操作指令,方塊向下移動 514 if(if_moveable(tetris)==0) //如果向下移動且不可動,方塊放在此處 515 { 516 tetris->y--; 517 print_tetris(hOut,tetris); 518 del_full(hOut,tetris); 519 break; 520 } 521 } 522 for(i=tetris->y-2;i<tetris->y+2;i++) 523 {//游戲結束條件:方塊觸到框頂位置 524 if(i==FrameY) 525 { 526 j=0; //如果游戲結束,j=0 527 } 528 } 529 if(j==0) 530 { 531 system("cls"); 532 getch(); 533 break; 534 } 535 //清除下一個俄羅斯方塊的圖形(右邊窗口) 536 tetris->flag = tetris->next; 537 tetris->x=FrameX+2*Frame_width+6; 538 tetris->y=FrameY+10; 539 clear_tetris(hOut,tetris); 540 } 541 } View Code
?
二、整個游戲的流程圖
三、函數解析
?
轉載于:https://www.cnblogs.com/null-/p/9993108.html
總結
以上是生活随笔為你收集整理的C语言实现俄罗斯方块游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: simulink封装子系统(mask s
- 下一篇: 3D视觉概述与立体成像原理