您好,登錄后才能下訂單哦!
小編給大家分享一下基于VC 6.0如何使用C語言實(shí)現(xiàn)俄羅斯方塊,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
本文實(shí)例為大家分享了C語言實(shí)現(xiàn)俄羅斯方塊的具體代碼,供大家參考,具體內(nèi)容如下
效果如下:
代碼:
/***************************************************************/ /*俄羅斯方塊的實(shí)現(xiàn) * 基于VC 6.0 編譯鏈接即可運(yùn)行 * 已實(shí)現(xiàn)的功能: * 1、初步的規(guī)劃及背景圖案的顯示 * 2、四種方塊實(shí)現(xiàn)左右移動(dòng)、下鍵加速、上鍵變形(兩種變形)功能 * 3、下落方塊碰壁及觸碰到其它方塊的檢測 * 4、方塊積滿一行的消除并加分的功能 * 5、預(yù)測方塊的功能 * 6、引入set_windows_pos函數(shù)解決閃屏問題 * 未解決的缺陷或者代碼存在的問題 * 1、預(yù)測方塊處莫名其妙的出現(xiàn)背景塊 * 2、代碼耦合性太高,接口封裝還是不夠好 * 2017.3.22 * 版權(quán):通渭縣西關(guān)小學(xué)四年級(jí)一班田剛 */ /***************************************************************/ #include<stdio.h> #include<windows.h> #include<conio.h> #include<string.h> #define BACK 176//背景圖案 #define BACK_INT -80//背景的整數(shù)表示 #define FRAME 178//分割框圖案 #define NODE 219//方塊圖案 #define NODE_INT -37//方塊的整數(shù)表示 #define ERROR -1 #define OK 0 int score = 0;//計(jì)分 static int time = 500;//時(shí)間,初始為500毫秒 char back[20][30] = {0};//豎直為x軸,橫軸為y軸,原點(diǎn)在右上角 int block_type = 0;//方塊類型 void backgroud_init(void);//畫面背景的初始化 void set_windows_pos(int i, int j);//指定光標(biāo)位置 void block_display(int block_type, int dir_type, int coor_x, int coor_y, int color_type);//顯示或者消除方塊 void time_add(void);//加速函數(shù) void block_type_change(void);//方塊類型變化 int block_move_check_x(int block_type, int dir_type, int coor_x, int coor_y);//檢測方塊是否觸到下面已經(jīng)停止的方塊 int block_move_check_y(int block_type, int dir_type, int coor_x, int coor_y, int dir_block);//檢測方塊是否觸碰到左右的方塊 int new_back_y_check(int block_type, int dir_type, int coor_y);//檢測方塊是否觸碰到墻壁 int block_clear_sort(void);//檢測是否滿一行,需要消除得分 void block_clear_x(int row);//消除一個(gè)滿行(都是方塊) int main(void) { int c = 0; int new_dir_type = 0;//新的方塊方向 int befor_dir_type = 0;//舊的方塊方向 int new_back_x = 0;//新的方塊頭坐標(biāo)x int new_back_y = 0;//新的方塊頭坐標(biāo)y int befor_back_x = 0;//舊的方塊頭坐標(biāo)x int befor_back_y = -1;//舊的方塊頭坐標(biāo)y int block_dir = -1;//方塊的移動(dòng)方向 backgroud_init();//背景的顯示 while(1) { block_type_change();//方塊類型變化 new_back_y = 8;//每次方塊從最頂端出現(xiàn)時(shí),其y坐標(biāo)都為8 time = 500; //怎樣在這里清除鍵盤輸入,flush不起作用 for(new_back_x = 0; new_back_x < 20; new_back_x++) { befor_dir_type = new_dir_type; befor_back_x = new_back_x - 1; befor_back_y = new_back_y; block_dir = -1;//方塊的方向變量初始為-1 block_display(block_type, 0, 17, 26, NODE);//畫上預(yù)測區(qū)域的方塊 if(kbhit())//檢測有輸入 { c = getch(); if(c > 0) { switch(c) { case 119://上 if(0 == new_dir_type) { new_dir_type = 1;//豎向 } else { new_dir_type = 0;//橫向 } break; case 97://左 new_back_y--; block_dir = 0; break; case 100://右 new_back_y++; block_dir = 1; break; case 115://下 time_add();//加速 break; default://ESC break; } } } new_back_y = new_back_y_check(block_type, new_dir_type, new_back_y);//檢查是否觸碰到左右壁 block_display(block_type, befor_dir_type, befor_back_x, befor_back_y, BACK);//原來的方塊位置清除掉 if(-1 != block_dir)//左右移動(dòng)了方塊 { if(ERROR == block_move_check_y(block_type, new_dir_type, new_back_x, new_back_y, block_dir))//檢查移動(dòng)的方塊是觸碰到左右的方塊 { new_back_y = befor_back_y; } } block_display(block_type, new_dir_type, new_back_x, new_back_y, NODE);//畫下一個(gè)方塊位置 if(ERROR == block_move_check_x(block_type, new_dir_type, new_back_x, new_back_y))//檢查移動(dòng)的方塊是否觸發(fā)到下面的方塊 { break; } Sleep(time); } block_display(block_type, 0, 17, 26, BACK);//清楚預(yù)測區(qū)域的方塊 if(OK == block_clear_sort())//檢查下面方塊是否等夠得分,能得分則消除得分 { set_windows_pos(8, 22);//更新得分 printf("%d", score); } } return 0; } /***************************************************************/ /*** 畫面背景的初始化 ***/ /***其中原點(diǎn)在右上角,豎軸為x軸,橫軸為y軸。y(0 - 19)為方塊區(qū)***/ /***域,20 - 30 為計(jì)分區(qū)域及方塊預(yù)測提示區(qū)域 ***/ /***************************************************************/ void backgroud_init(void) { int x = 0, y = 0; for(x = 0; x < 20; x++) { for(y = 0; y < 20; y++) { back[x][y] = BACK; } } for(x = 0; x < 20; x++) { for(y = 20; y < 30; y++) { if((0 == x) || (4 == x) || (10 == x) || (19 == x)) { back[x][y] = FRAME; } if((20 == y) || (29 == y)) { back[x][y] = FRAME; } } } //背景圖案的顯示 for(x = 0; x < 20; x++) { for(y = 0; y < 30; y++) { printf("%c", back[x][y]); } printf("\n"); } //顯示TETRIS set_windows_pos(2, 22);//移動(dòng)windows的光標(biāo) printf("TETRIS\n"); //顯示積分 set_windows_pos(6, 22);//移動(dòng)windows的光標(biāo) printf("SORT\n"); set_windows_pos(8, 22); printf("%d\n", score); //顯示下一個(gè)要出現(xiàn)的方塊 set_windows_pos(12, 22);//移動(dòng)windows的光標(biāo) printf("EXPECT\n"); } /***************************************************************/ /*** 設(shè)置windows光標(biāo),類似于TC中的gotoxy ***/ /***i,j 為要傳入的x,y坐標(biāo) ***/ /***************************************************************/ void set_windows_pos(int i, int j)//設(shè)置windows光標(biāo),類似于TC中的gotoxy { /*if((0 > i) || (0 > j)) { return ERROR; }*/ /*windows的橫軸是x軸,而本程序設(shè)計(jì)的是豎軸是X軸 這里做個(gè)轉(zhuǎn)換*/ COORD pos={j,i}; HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut,pos); } /***************************************************************/ /***********************消除/填上方塊***************************/ /***輸入:block_type 方塊類型 1:長條 2:2型 3:7型 4:田型***/ /***輸入:dir_type 方向類型 0:橫向 1:豎向 ***/ /***輸入:coor_x coor_y 方塊當(dāng)前頭的坐標(biāo) ***/ /***輸入:color_type 圖標(biāo)類型 BACK 背景色 NODE 方塊色 ***/ /***初始coor_x,coor_y為一個(gè)方塊的最右下的一個(gè)方塊的坐標(biāo) ***/ /***************************************************************/ void block_display(int block_type, int dir_type, int coor_x, int coor_y, int color_type) { int x = 0, y = 0; switch (block_type) { case 1://長條 if(0 == dir_type)//橫向 { for(y = coor_y; y >= (coor_y - 3); y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } } else if(1 == dir_type)//豎向 { for(x = coor_x; (x >= (coor_x - 3)) && (x >= 0); x--) { back[x][coor_y] = color_type;//方塊色 set_windows_pos(x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[x][coor_y]); } } else { printf("dir_type is error!\n"); } break; case 2://2型 if(0 == dir_type)//橫向 { for(y = coor_y; y >= coor_y - 1; y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } coor_x--; coor_y--; if(coor_x < 0) { return; } for(y = coor_y; y >= coor_y - 1; y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } } else if(1 == dir_type)//豎向 { for(x = coor_x; (x >= coor_x - 1) && (x >= 0); x--) { back[x][coor_y] = color_type;//方塊色 set_windows_pos(x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[x][coor_y]); } coor_x--; coor_y--; if(coor_x < 0) { return; } for(x = coor_x; x >= coor_x - 1; x--) { back[x][coor_y] = color_type;//方塊色 set_windows_pos(x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[x][coor_y]); } } else { printf("dir_type is error!\n"); } break; case 3://7型 if(0 == dir_type)//橫向 { for(y = coor_y; y >= coor_y - 2; y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } coor_x--; coor_y = coor_y - 2; if(coor_x < 0) { return; } back[coor_x][coor_y] = color_type;//方塊色 set_windows_pos(coor_x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][coor_y]); } else if(1 == dir_type)//豎向 { for(x = coor_x; (x >= coor_x - 2) && (x >= 0); x--) { back[x][coor_y] = color_type;//方塊色 set_windows_pos(x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[x][coor_y]); } coor_x = coor_x - 2; coor_y--; if(coor_x < 0) { return; } back[coor_x][coor_y] = color_type;//方塊色 set_windows_pos(coor_x, coor_y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][coor_y]); } else { printf("dir_type is error!\n"); } break; case 4://田型 if((0 == dir_type) || (1 == dir_type))//橫向 { for(y = coor_y; y >= coor_y - 1; y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } coor_x--; if(coor_x < 0) { return; } for(y = coor_y; y >= coor_y - 1; y--) { back[coor_x][y] = color_type;//方塊色 set_windows_pos(coor_x, y);//移動(dòng)windows的光標(biāo) printf("%c", back[coor_x][y]); } } else { printf("dir_type is error!\n"); } break; default: printf("block_type is error!\n"); break; } } void time_add(void)//加速函數(shù) { if(500 == time) { time = 100;//減少的100毫秒 } else if(100 == time) { time = 500; } else { ;//暫時(shí)留空 } } void block_type_change(void)//方塊類型變化 { block_type++; if(block_type > 4) { block_type = 1; } } /***************************************************************/ /*******************方塊y坐標(biāo)撞墻檢測***************************/ /***輸入:block_type 方塊類型 1:長條 2:2型 3:7型 4:田型***/ /***輸入:dir_type 方向類型 0:橫向 1:豎向 ***/ /***輸入:coor_y 方塊當(dāng)前頭(右下角第一個(gè)方塊)的坐標(biāo) ***/ /***************************************************************/ int new_back_y_check(int block_type, int dir_type, int coor_y) { if(coor_y > 19) { coor_y = 19; } switch (block_type) { case 1://長條 if(0 == dir_type)//橫向 { if(coor_y - 3 < 0) { coor_y = 3; } } else if(1 == dir_type)//豎向 { if(coor_y < 0) { coor_y = 0; } } else { printf("dir_type is error!\n"); } break; case 2://2型 if(0 == dir_type)//橫向 { if(coor_y - 2 < 0) { coor_y = 2; } } else if(1 == dir_type)//豎向 { if(coor_y - 1 < 0) { coor_y = 1; } } else { printf("dir_type is error!\n"); } break; case 3://7型 if(0 == dir_type)//橫向 { if(coor_y - 2 < 0) { coor_y = 2; } } else if(1 == dir_type)//豎向 { if(coor_y - 1 < 0) { coor_y = 1; } } else { printf("dir_type is error!\n"); } break; case 4://田型 if((0 == dir_type) || (1 == dir_type))//橫向 { if(coor_y - 1 < 0) { coor_y = 1; } } else { printf("dir_type is error!\n"); } break; default: printf("block_type is error!\n"); break; } return coor_y; } /* 檢查方塊是否觸到下面已經(jīng)停止的方塊,觸碰到就返回ERROR */ /***************************************************************/ /****檢查方塊是否觸到下面已經(jīng)停止的方塊,觸碰到就返回ERROR ***/ /***輸入:block_type 方塊類型 1:長條 2:2型 3:7型 4:田型***/ /***輸入:dir_type 方向類型 0:橫向 1:豎向 ***/ /***輸入:coor_x coor_y 方塊當(dāng)前頭的坐標(biāo) ***/ /***初始coor_x,coor_y為一個(gè)方塊的最右下的一個(gè)方塊的坐標(biāo) ***/ /***************************************************************/ int block_move_check_x(int block_type, int dir_type, int coor_x, int coor_y) { int ret = OK; int x = 0, y = 0; switch (block_type) { case 1://長條 if(0 == dir_type)//橫向 { for(y = coor_y; y >= coor_y - 3; y--) { if(NODE_INT == back[coor_x + 1][y]) { ret = ERROR; break; } } } else if(1 == dir_type)//豎向 { if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } } else { printf("dir_type is error!\n"); } break; case 2://2型 if(0 == dir_type)//橫向 { for(y = coor_y; y >= coor_y - 1; y--) { if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; break; } } coor_x--; coor_y =coor_y - 2 ; if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } } else if(1 == dir_type)//豎向 { if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } coor_x--; coor_y--; if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } } else { printf("dir_type is error!\n"); } break; case 3://7型 if(0 == dir_type)//橫向 { for(y = coor_y; y >= coor_y - 2; y--) { if(NODE_INT == back[coor_x + 1][y]) { ret = ERROR; break; } } } else if(1 == dir_type)//豎向 { if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } coor_x = coor_x - 2; coor_y--; if(NODE_INT == back[coor_x + 1][coor_y]) { ret = ERROR; } } else { printf("dir_type is error!\n"); } break; case 4://田型 if((0 == dir_type) || (1 == dir_type))//橫向 { for(y = coor_y; y >= coor_y - 1; y--) { if(NODE_INT == back[coor_x + 1][y]) { ret = ERROR; break; } } } else { printf("dir_type is error!\n"); } break; default: printf("block_type is error!\n"); break; } return ret; } /***************************************************************/ /****檢查方塊在向下移動(dòng)的過程中是否觸到左右的方塊 ***/ /***輸入:block_type 方塊類型 1:長條 2:2型 3:7型 4:田型***/ /***輸入:dir_type 方向類型 0:橫向 1:豎向 ***/ /***輸入:coor_x coor_y 方塊當(dāng)前頭(右下)的坐標(biāo) ***/ /***輸入:dir_block 當(dāng)前方塊的移動(dòng)方向(左右) ***/ /***************************************************************/ int block_move_check_y(int block_type, int dir_type, int coor_x, int coor_y, int dir_block) { int x = 0, y = 0; int ret = OK; switch (block_type) { case 1://長條 if(0 == dir_type)//橫向 { if(1 == dir_block)//右移 { if(NODE_INT == back[coor_x][coor_y]) { ret = ERROR; } } else if(0 == dir_block)//左移 { if(NODE_INT == back[coor_x][coor_y - 3]) { ret = ERROR; } } else { printf("dir_block is error!"); } } else if(1 == dir_type)//豎向 { //當(dāng)長條為豎向時(shí),不用判斷長條是往左移還是往右移 for(x = coor_x; x >= coor_x - 3; x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } } else { printf("dir_type is error!\n"); } break; case 2://2型 if(0 == dir_type)//橫向 { if(1 == dir_block)//右移 { if(NODE_INT == back[coor_x][coor_y]) { ret = ERROR; break; } if(NODE_INT == back[coor_x - 1][coor_y - 1]) { ret = ERROR; } } else if(0 == dir_block)//左移 { if(NODE_INT == back[coor_x][coor_y - 1]) { ret = ERROR; break; } if(NODE_INT == back[coor_x - 1][coor_y - 2]) { ret = ERROR; } } else { printf("dir_block is error!"); } } else if(1 == dir_type)//豎向 { if(1 == dir_block)//右移 { for(x = coor_x; x >= coor_x - 1; x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } if(NODE_INT == back[coor_x - 2][coor_y - 1]) { ret = ERROR; } } else if(0 == dir_block)//左移 { if(NODE_INT == back[coor_x][coor_y]) { ret = ERROR; break; } coor_x--; coor_y--; for(x = coor_x; x >= coor_x - 1; x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } } else { printf("dir_block is error!"); } } else { printf("dir_type is error!\n"); } break; case 3://7型 if(0 == dir_type)//橫向 { if(1 == dir_block)//右移 { if(NODE_INT == back[coor_x][coor_y]) { ret = ERROR; break; } if(NODE_INT == back[coor_x - 1][coor_y - 2]) { ret = ERROR; } } else if(0 == dir_block)//左移 { if(NODE_INT == back[coor_x][coor_y - 2]) { ret = ERROR; break; } if(NODE_INT == back[coor_x - 1][coor_y - 2]) { ret = ERROR; } } else { printf("dir_block is error!"); } } else if(1 == dir_type)//豎向 { if(1 == dir_block)//右移 { for(x = coor_x; (x >= coor_x - 2) && (x >= 0); x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } } else if(0 == dir_block)//左移 { for(x = coor_x - 1; (x >= coor_x - 2) && (x >= 0); x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } coor_x = coor_x - 2; coor_y--; if(NODE_INT == back[coor_x][coor_y]) { ret = ERROR; } } else { printf("dir_block is error!"); } } else { printf("dir_type is error!\n"); } break; case 4://田型 if((0 == dir_type) || (1 == dir_type))//橫向 { if(1 == dir_block)//右移 { for(x = coor_x; x >= coor_x - 1; x--) { if(NODE_INT == back[x][coor_y]) { ret = ERROR; break; } } } else if(0 == dir_block)//左移 { for(x = coor_x; x >= coor_x - 1; x--) { if(NODE_INT == back[x][coor_y - 1]) { ret = ERROR; break; } } } else { printf("dir_block is error!"); } } else { printf("dir_type is error!\n"); } break; default: printf("block_type is error!\n"); break; } return ret; } void block_clear_x(int row)//消除某一行 { int x = 0, y = 0; char back_replace[20][30] = {0};//替代back memcpy(back_replace, back, sizeof(back));//將back暫存到back_replace中 for(x = 0; x <= row; x++) { for(y = 0; y < 20; y++) { back[x][y] = BACK;//初始化未背景色 } } for(x = row; x >= 1; x--) { for(y = 0; y < 20; y++) { back[x][y] = back_replace[x - 1][y];//消除一行,方塊下沉 } } set_windows_pos(0, 0);//移動(dòng)windows的光標(biāo) for(x = 0; x < 20; x++) { for(y = 0; y < 20; y++) { printf("%c", back[x][y]); } printf("\n"); } } /* 檢查是否消行并且進(jìn)行計(jì)分 */ int block_clear_sort(void) { int x = 0, y = 0; int ret = ERROR; int flag = 0; for(x = 19; x >= 0; x--)//行 { flag = 0; for(y = 0; y < 20; y++) { if(NODE_INT == back[x][y]) { flag++;//一行的塊計(jì)數(shù) } if(20 == flag)//表示一行有20個(gè)方塊 { block_clear_x(x);//消行 score++;//加分 ret = OK; } } } return ret; }
以上是“基于VC 6.0如何使用C語言實(shí)現(xiàn)俄羅斯方塊”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。