俄罗斯方块
上学期看到学长写了一个贪吃蛇,就一直想要做一个不同的游戏,当时觉得写出来并不是不可能,可还是因为能力有限,很多东西都不懂,就放弃了这个想法。这学期还没开始,就一直心想着编一个俄罗斯方块出来,可是当我真正开始的时候,才发现没有那么简单,什么头绪也没有就开始凭着感觉去写。大干花了两个晚上的时间写了大概有100~200行代码,再回过头来去看那个贪吃蛇的代码,发现自己写的完全什么用也没有。没办法只有全部删掉,先研究研究再从头开始。
在中途也碰到过很多问题,有一段时间就干脆不去管它,搁置了大概有一两周的时间,之后开始写才一点一点理清思路,写各种函数(由于对c++还算是没入门,只能用c语言写下去了),再考虑各种情况,再一点一点拼凑起来,总算是把他给摆平了。不过到现在也还是有各种BUG,还希望多多见谅。(实在是不好找错了)。没事了可以拿去玩一玩。还希望各位指出其中的BUG,容小菜再去改一改。。。
从这500行的代码中,其实感觉自己也没用到什么新东西,不懂得直接调用别人的,其他的基本上都是FOR循环以及IF和ELSE,所以这不算什么学到很多新知识,但是有一点,就是从这么长的代码中明白一点,就是如何去管理这样长的代码:用容易理解的函数名以及变量名;各种函数的功能明确;如何去安排每个细节;然后就是一点一点耐心的调试,一边调试一边编写。。。。还是很有收获的!!!
游戏图片:(高手勿喷!!!)
代码
1 /*******************************/ 2 /******Writer: GJ *******/ 3 /******Language: C *******/ 4 /******Date: 2013 3 23 *******/ 5 /*******************************/ 6 #include<iostream> 7 #include<stdio.h> 8 //#include<conio.h> 9 #include<string.h> 10 #include<time.h> 11 #include<stdlib.h> 12 #include<windows.h> 13 using namespace std; 14 #define me(a) memset(a,0,sizeof(a)) 15 #define judge(bl,ok) for(i=0;i<5;i++)if(bl[i].x&&map[bl[i].x][bl[i].y])ok=0 16 #define is_pure(node,ok) if(map[node.x][node.y])ok=0 17 const int HEIGHT=24,LENGTH=40,SIDE=22; 18 19 char INIT_MAP[HEIGHT+1][LENGTH+1]; 20 int map[HEIGHT][SIDE]; 21 struct node{int x,y;int color;}; 22 const int TIME_DWELL=1000; 23 int state=0; 24 25 /**********获取句柄**********/ 26 HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE); 27 HANDLE Input=GetStdHandle(STD_INPUT_HANDLE); 28 29 /**********设置光标位置**********/ 30 void SetCursor(int x,int y){ 31 COORD cd={x,y}; 32 SetConsoleCursorPosition(Output,cd); 33 } 34 35 /**************初始化图**************/ 36 void INITMAP() 37 { 38 for(int i=0;i<HEIGHT;i++) 39 for(int j=0;j<SIDE;j++){ 40 if(i==0||i==HEIGHT-1||j==0||j==SIDE-1)map[i][j]=1; 41 else map[i][j]=0; 42 } 43 } 44 45 /********右上方提前显示方块******/ 46 node bl[5]; 47 void Former_Print_block(int n) 48 { 49 int i; 50 for(i=0;i<5;i++){bl[i].x=bl[i].y=0;} 51 if(n==0){ 52 bl[0].x=3,bl[0].y=28; bl[1].x=3,bl[1].y=30; 53 bl[2].x=4,bl[2].y=30; bl[3].x=4,bl[3].y=32; 54 } 55 if(n==1){ 56 bl[0].x=3,bl[0].y=32; bl[1].x=3,bl[1].y=30; 57 bl[2].x=4,bl[2].y=30; bl[3].x=4,bl[3].y=28; 58 } 59 if(n==2){ 60 bl[0].x=3,bl[0].y=30; bl[1].x=4,bl[1].y=28; 61 bl[2].x=4,bl[2].y=30; bl[3].x=4,bl[3].y=32; 62 } 63 if(n==3){ 64 bl[0].x=3,bl[0].y=27; bl[1].x=3,bl[1].y=29; 65 bl[2].x=3,bl[2].y=31; bl[3].x=3,bl[3].y=33; 66 } 67 if(n==4){ 68 bl[0].x=3,bl[0].y=29; bl[1].x=3,bl[1].y=31; 69 bl[2].x=4,bl[2].y=29; bl[3].x=4,bl[3].y=31; 70 } 71 if(n==5){ 72 bl[0].x=3,bl[0].y=28; bl[1].x=4,bl[1].y=28; 73 bl[2].x=4,bl[2].y=30; bl[3].x=4,bl[3].y=32; 74 } 75 if(n==6){ 76 bl[0].x=3,bl[0].y=32; bl[1].x=4,bl[1].y=28; 77 bl[2].x=4,bl[2].y=30; bl[3].x=4,bl[3].y=32; 78 } 79 for(i=0;i<5;i++){ 80 SetCursor(bl[i].y,bl[i].x); 81 printf("■"); 82 } 83 } 84 85 /*********获取不同的方块,出现在中间***********/ 86 node block[5];//全局使用的核心!!! 87 void print_block(int n) 88 {int i; 89 for(i=0;i<5;i++){block[i].x=block[i].y=0;} 90 if(n==0){ 91 block[0].x=1,block[0].y=7; block[1].x=1,block[1].y=9; 92 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=11; 93 } 94 if(n==1){ 95 block[0].x=1,block[0].y=11; block[1].x=1,block[1].y=9; 96 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=7; 97 } 98 if(n==2){ 99 block[0].x=1,block[0].y=9; block[1].x=2,block[1].y=7; 100 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=11; 101 } 102 if(n==3){ 103 block[0].x=1,block[0].y=7; block[1].x=1,block[1].y=9; 104 block[2].x=1,block[2].y=11; block[3].x=1,block[3].y=13; 105 } 106 if(n==4){ 107 block[0].x=1,block[0].y=9; block[1].x=1,block[1].y=11; 108 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=11; 109 } 110 if(n==5){ 111 block[0].x=1,block[0].y=7; block[1].x=2,block[1].y=7; 112 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=11; 113 } 114 if(n==6){ 115 block[0].x=1,block[0].y=11; block[1].x=2,block[1].y=7; 116 block[2].x=2,block[2].y=9; block[3].x=2,block[3].y=11; 117 } 118 for(i=0;i<5;i++){ 119 SetCursor(block[i].y,block[i].x); 120 printf("■"); 121 } 122 } 123 124 125 /*************按 上 键 旋转*************/ 126 void Exchange(int m) 127 { 128 int i,ok=1; 129 node blo[5]; 130 for(i=0;i<5;i++)blo[i]=block[i]; 131 if(m==0){ 132 if(state==0){ 133 blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y+=2;blo[3].x-=2; 134 judge(blo,ok); 135 if(map[blo[0].x][blo[0].y-2])ok=0; 136 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;} 137 } 138 else{ 139 blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y-=2;blo[3].x+=2; 140 judge(blo,ok); 141 if(map[blo[1].x-1][blo[1].y])ok=0; 142 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;} 143 } 144 } 145 else if(m==1){ 146 if(state==0){ 147 blo[0].x-=1;blo[0].y-=2;blo[2].x-=1;blo[2].y+=2;blo[3].y+=4; 148 judge(blo,ok); 149 if(map[blo[1].x][blo[1].y-2])ok=0; 150 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;} 151 } 152 else { 153 blo[0].x+=1;blo[0].y+=2;blo[2].x+=1;blo[2].y-=2;blo[3].y-=4; 154 judge(blo,ok); 155 if(map[blo[0].x-1][blo[0].y])ok=0; 156 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;} 157 } 158 } 159 else if(m==2) 160 { 161 if(state==0) 162 { 163 blo[0].x+=1;blo[0].y-=2; blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2; 164 judge(blo,ok); 165 if(map[blo[0].x+1][blo[0].y]||map[blo[0].x-1][block[0].y]||map[blo[3].x][blo[3].y+2])ok=0; 166 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;} 167 } 168 else if(state==1) 169 { 170 blo[0].x+=1;blo[0].y+=2; blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2; 171 judge(blo,ok); 172 if(map[blo[0].x][blo[0].y+2]||map[blo[0].x][blo[0].y-2]||map[blo[3].x-1][blo[3].y])ok=0; 173 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;} 174 } 175 else if(state==2) 176 { 177 blo[0].x-=1;blo[0].y+=2; blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2; 178 judge(blo,ok); 179 if(map[blo[0].x+1][blo[0].y]||map[blo[0].x-1][blo[0].y]||map[blo[3].x][blo[3].y-2])ok=0; 180 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;} 181 } 182 else{ 183 blo[0].x-=1;blo[0].y-=2; blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2; 184 judge(blo,ok); 185 if(map[blo[0].x][blo[0].y+2]||map[blo[0].x][blo[0].y-2]||map[blo[3].x+1][blo[1].y])ok=0; 186 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;} 187 } 188 } 189 else if(m==3) 190 { 191 if(state==0){ 192 blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y-=2;blo[3].x-=2;blo[3].y-=4; 193 judge(blo,ok); 194 if(map[blo[0].x][blo[0].y-2]||map[blo[2].x][blo[2].y+2])ok=0; 195 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;} 196 } 197 else { 198 blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y+=2;blo[3].x+=2;blo[3].y+=4; 199 judge(blo,ok); 200 if(map[blo[0].x+1][blo[0].y]||map[blo[2].x-1][blo[2].y])ok=0; 201 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;} 202 } 203 } 204 else if(m==5) 205 { 206 if(state==0) 207 { 208 blo[0].x+=2;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2; 209 judge(blo,ok); 210 if(map[blo[3].x][blo[3].y+2])ok=0; 211 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;} 212 } 213 else if(state==1) 214 { 215 blo[0].y+=4;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2; 216 judge(blo,ok); 217 if(map[blo[3].x-1][blo[3].y])ok=0; 218 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;} 219 } 220 else if(state==2) 221 { 222 blo[0].x-=2;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2; 223 judge(blo,ok); 224 if(map[blo[3].x][blo[3].y-2])ok=0; 225 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;} 226 } 227 else{ 228 blo[0].y-=4;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2; 229 judge(blo,ok); 230 if(map[blo[3].x+1][blo[3].y])ok=0; 231 if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;} 232 } 233 } 234 else if(m==6) 235 { 236 if(state==0) 237 { 238 blo[0].y-=4;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2; 239 judge(blo,ok); 240 if(map[blo[1].x][blo[1].y-2])ok=0; 241 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;} 242 } 243 else if(state==1) 244 { 245 blo[0].x+=2;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2; 246 judge(blo,ok); 247 if(map[blo[1].x+1][blo[1].y])ok=0; 248 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=2;} 249 } 250 else if(state==2) 251 { 252 blo[0].y+=4;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2; 253 judge(blo,ok); 254 if(map[blo[1].x][blo[1].y+2])ok=0; 255 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=3;} 256 } 257 else{ 258 blo[0].x-=2;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2; 259 judge(blo,ok); 260 if(map[blo[1].x-1][blo[1].y])ok=0; 261 if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;} 262 } 263 } 264 } 265 266 /*********清除当前方块**********/ 267 void clear_cube(node* block) 268 { 269 for(int i=0;i<5;i++){ 270 if(block[i].x){ 271 SetCursor(block[i].y,block[i].x); 272 printf(" ");} 273 } 274 } 275 276 /*******打印当前方块*********/ 277 void printt_cube(node* block) 278 { 279 for(int i=0;i<5;i++){ 280 if(block[i].x){ 281 SetCursor(block[i].y,block[i].x); 282 printf("■"); 283 } 284 } 285 } 286 287 /**********按键***********/ 288 void Move(int m,int n){ 289 int i; 290 if(n==0){//左 291 for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y-=2; 292 } 293 if(n==1){//右 294 for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y+=2; 295 } 296 if(n==2)//上 297 { 298 Exchange(m); 299 } 300 if(n==3)//下 301 { 302 int ok=1; 303 while(ok){ 304 for(i=0;i<5;i++)if(block[i].x) 305 if(map[block[i].x+1][block[i].y])ok=0; 306 if(ok)for(i=0;i<5;i++)if(block[i].x) 307 block[i].x+=1; 308 } 309 } 310 } 311 312 /******判断是否可以向左移动*****/ 313 int If_Can_Left(node* block) 314 { 315 int ok=1,i; 316 int min=22; 317 for(i=0;i<5&&block[i].x;i++)if(block[i].y<min)min=block[i].y; 318 if(min-2<1)ok=0; 319 for(i=0;i<5&&block[i].x;i++)if(block[i].x) 320 if(map[block[i].x][block[i].y-2])ok=0; 321 return ok; 322 } 323 324 /******判断是否可以向右移动********/ 325 int If_Can_Right(node* block) 326 { 327 int ok=1,i; 328 int max=0; 329 for(i=0;i<5&&block[i].x;i++)if(block[i].y>max)max=block[i].y; 330 if(max+2>19)ok=0; 331 for(i=0;i<5&&block[i].x;i++)if(block[i].x) 332 if(map[block[i].x][block[i].y+2])ok=0; 333 return ok; 334 } 335 336 /*********打印图**********/ 337 void print_map() 338 { 339 int i,j; 340 me(INIT_MAP); 341 for(i=0;i<HEIGHT;i++) 342 { 343 if(i==0||i==23){ 344 for(j=0;j<LENGTH;j++)printf("%c",INIT_MAP[i][j]='-'); 345 } 346 else{ 347 printf("%c",INIT_MAP[i][0]='|'); 348 for(j=1;j<SIDE-1;j++)printf("%c",INIT_MAP[i][j]=' '); 349 printf("%c%c",INIT_MAP[i][j++]='|',INIT_MAP[i][j++]='|'); 350 for(;j<LENGTH-1;j++)printf("%c",INIT_MAP[i][j]=' '); 351 printf("%c",INIT_MAP[i][j]='|'); 352 } 353 cout<<endl; 354 } 355 SetCursor(SIDE+1,10); 356 printf("================"); 357 SetCursor(SIDE+1,11); 358 printf("Speed"); 359 SetCursor(SIDE+1,13); 360 printf("================"); 361 SetCursor(SIDE+1,14); 362 printf("Score"); 363 SetCursor(SIDE+1,16); 364 printf("================"); 365 SetCursor(SIDE+1,19); 366 printf(" Created By "); 367 SetCursor(SIDE+1,20); 368 printf(" Gong Jing "); 369 } 370 371 /*******下降一格*******/ 372 void cube_drop(node *block) 373 { 374 int i; 375 for(i=0;i<5;i++)if(block[i].x) 376 block[i].x+=1; 377 } 378 379 /*****到达底部返回1*******/ 380 int is_at_botton(node* block) 381 { 382 for(int i=0;i<5;i++) 383 if(block[i].x&&map[block[i].x+1][block[i].y])return 1; 384 return 0; 385 } 386 387 /******到达底部map赋值为1*****/ 388 void print_map(node *block) 389 { 390 int i; 391 for(i=0;i<5;i++){ 392 if(block[i].x){ 393 map[block[i].x][block[i].y]=1; 394 SetCursor(block[i].y,block[i].x); 395 printf("■"); 396 } 397 } 398 } 399 400 /******是否可以消去并消去**********/ 401 int Can_It_Cut() 402 { 403 int i,j; 404 int cut=0; 405 for(i=HEIGHT-2;i>1;i--){ 406 int ok=1; 407 for(j=1;j<SIDE-1;j+=2) 408 if(map[i][j]==0){ok=0;break;} 409 if(ok){ 410 for(j=i;j>1;j--)for(int k=1;k<SIDE-1;k+=2) 411 map[j][k]=map[j-1][k]; 412 cut++;i++; 413 } 414 } 415 for(i=HEIGHT-2;i>1;i--) 416 for(int j=1;j<SIDE-1;j+=2) 417 { 418 SetCursor(j,i); 419 if(map[i][j])printf("■"); 420 else printf(" "); 421 } 422 return cut; 423 } 424 425 426 /********是否GameOver********/ 427 int is_gameover(int num) 428 { 429 int i,j,ok=1; 430 print_block(num); 431 for(i=0;i<5;i++)if(block[i].x&&map[block[i].x][block[i].y])ok=0; 432 if(!ok){ 433 char aa[20]={"Game Over!!!"}; 434 for(i=9;i<12;i++) 435 { 436 if(i==10){ 437 int t=0; 438 for(int j=4;j<18;j++){ 439 SetCursor(j,i); 440 if(j>=5&&j<17)printf("%c",aa[t++]); 441 else printf(" "); 442 } 443 } 444 else for(j=4;j<18;j++){ 445 SetCursor(j,i); 446 printf(" "); 447 } 448 } 449 SetCursor(1,12);printf(" Enter To Continue. "); 450 SetCursor(1,13);printf(" Esc To Escape. "); 451 SetCursor(1,14);printf(" "); 452 } 453 return ok; 454 } 455 456 /*******游戏结束,再来一局,清理屏幕******/ 457 void Clear_map() 458 { 459 for(int i=22;i>0;i--) 460 for(int j=1;j<SIDE-1;j+=2) 461 { 462 map[i][j]=0; 463 SetCursor(j,i); 464 printf(" "); 465 } 466 } 467 468 int main() 469 { 470 srand(time(NULL)); 471 print_map(); 472 INITMAP(); 473 int gameover=1; 474 int ok=1;//用于判断游戏是否结束 475 while(gameover){ 476 int Score=0; 477 int Speed=0; 478 int numm=(rand()%7)*(rand()%7)%7; 479 Sleep(TIME_DWELL); 480 while(ok) 481 { 482 SetCursor(SIDE+4+Speed,12); 483 printf(" "); 484 SetCursor(SIDE+4,15); 485 printf(" "); 486 SetCursor(SIDE+4+Speed,12); 487 printf("*"); 488 SetCursor(SIDE+4,15); 489 printf("%d",Score); 490 Sleep(200); 491 int num=numm; //第num个方块,初始时为0这个状态 492 numm=(rand()%7)*(rand()%7)%7; //提前显示的方块 493 clear_cube(bl); 494 Former_Print_block(numm); //打印提前显示的方块 495 print_block(num); //打印要落下的方块初始位置 496 state=0; 497 int botton=1;//用于判断是否已经落到底部 498 while(botton) 499 { 500 clear_cube(block); 501 /**********键位响应**********/ 502 if(GetAsyncKeyState(VK_LEFT)&&If_Can_Left(block))Move(num,0); 503 else if(GetAsyncKeyState(VK_RIGHT)&&If_Can_Right(block))Move(num,1); 504 else if(GetAsyncKeyState(VK_UP))Move(num,2); 505 else if(GetAsyncKeyState(VK_DOWN)){Move(num,3);botton=0;} 506 507 if(!is_at_botton(block))cube_drop(block); 508 else botton=0; 509 printt_cube(block);//打印当前方块 510 if(!botton)print_map( block); 511 Sleep(100*(4-Score/80)); 512 } 513 int cut=Can_It_Cut(); 514 if(cut){ 515 Score+=cut*10; 516 Speed=Score/80; 517 } 518 ok=is_gameover(numm); 519 } 520 if(GetAsyncKeyState(VK_ESCAPE))gameover=0; 521 else if(GetAsyncKeyState(VK_RETURN)){Clear_map();ok=1;} 522 } 523 return 0; 524 }
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号