主要要實現以下幾個功能:方塊的移動控制、方塊變形、斷定方塊是否接觸邊界和進行方塊堆積、對方塊進行消除。git
1.方塊的移動控制
上下左右四個方向
上-->變形,下-->加速下落,左-->向左移動,右-->向右移動
注意在移動的時候,還要斷定是否接觸邊界,特別是向下移動,除了須要肯定是否接觸底部邊界外,還要注意是否發生方塊堆積。github
1 void Piece::show(){ 2 fd_set set; 3 FD_ZERO(&set); 4 FD_SET(0, &set); 5 struct timeval timeout; 6 timeout.tv_sec = 0; 7 timeout.tv_usec= 500000; 8 if (select(1, &set, NULL, NULL, &timeout) == 0){ 9 //mvwprintw(game_win,21,20,"+"); 10 pos_x++; 11 if(reachBottom()){ 12 pos_x--; 13 int x=10; 14 for(int i=0;i<shape_x;i++){ 15 for(int j=0;j<shape_y;j++){ 16 if(shape[i][j]==1){ 17 map[pos_x+i+1][pos_y+j+1]=1; 18 mvwaddch(game_win,pos_x+i+1,pos_y+j+1,'#'); 19 } 20 } 21 } 22 pos_x=0; 23 srand((int)time(0)); 24 pos_y=rand()%(map_y-2); 25 while(pos_y==0){ 26 pos_y=rand()%(map_y-2); 27 } 28 next_shape_id=rand()%7; 29 //shape_id=3; 30 nextShape(); 31 wrefresh(game_win); 32 int flag=1; 33 int lines=0; 34 if(flag==1){ 35 for(int i=map_x-3;i>=2;i--){ 36 while(fullLine(i)){ 37 lines++; 38 int k=i-1; 39 while(fullLine(k)){ 40 k--; 41 lines++; 42 } 43 for(int j=0;j<(map_y-3);j++){ 44 map[k+2][j+1]=0; 45 mvwaddch(game_win,k+2,j+1,' '); 46 } 47 int kk=k+1; 48 for(;kk>=2;kk--){ 49 for(int jj=0;jj<(map_y-3);jj++){ 50 if(map[kk][jj+1]==1){ 51 map[kk+1][jj+1]=1; 52 mvwaddch(game_win,kk+1,jj+1,'#'); 53 }else{ 54 map[kk+1][jj+1]=0; 55 mvwaddch(game_win,kk+1,jj+1,' '); 56 } 57 } 58 } 59 score+=(lines*10); 60 std::string tempS; 61 std::ostringstream ex_msg; 62 ex_msg<<"score: "<<score; 63 tempS=ex_msg.str(); 64 mvwprintw(score_win,5,5,tempS.c_str()); 65 wrefresh(score_win); 66 //mvwaddch(game_win,k+1,j,' '); 67 wrefresh(game_win); 68 } 69 } 70 } 71 }else{ 72 //mvwprintw(game_win,21,20,"-"); 73 for(int i=3;i>=0;i--){ 74 for(int j=3;j>=0;j--){ 75 if(shape[i][j]==1){ 76 int x=11; 77 mvwaddch(game_win,pos_x+i,pos_y+1+j,' '); 78 mvwaddch(game_win,pos_x+i+1,pos_y+1+j,'#'); 79 } 80 } 81 } 82 wrefresh(game_win); 83 } 84 } 85 if(FD_ISSET(0,&set)){ 86 while((key=getch())==-1); 87 88 if(key==KEY_RIGHT){ 89 //clearShape(); 90 pos_y++; 91 if(reachBottom()){ 92 pos_y--; 93 }else{ 94 for(int i=0;i<=3;i++){ 95 for(int j=3;j>=0;j--){ 96 if(shape[i][j]==1){ 97 //列上的移動 98 mvwaddch(game_win,pos_x+i+1,pos_y+j,' '); 99 mvwaddch(game_win,pos_x+i+1,pos_y+j+1,'#'); 100 } 101 } 102 } 103 wrefresh(game_win); 104 } 105 } 106 107 if(key==KEY_LEFT){ 108 //clearShape(); 109 pos_y--; 110 if(reachBottom()){ 111 pos_y++; 112 }else{ 113 for(int i=0;i<=3;i++){ 114 for(int j=0;j<=3;j++){ 115 if(shape[i][j]==1){ 116 //列上的移動 117 mvwaddch(game_win,pos_x+i+1,pos_y+j+2,' '); 118 mvwaddch(game_win,pos_x+i+1,pos_y+j+1,'#'); 119 } 120 } 121 } 122 wrefresh(game_win); 123 } 124 } 125 126 if(key==KEY_UP){ 127 changeShape(); 128 } 129 if(key==KEY_DOWN){ 130 pos_x++; 131 if(reachBottom()){ 132 pos_x--; 133 }else{ 134 for(int i=3;i>=0;i--){ 135 for(int j=3;j>=0;j--){ 136 if(shape[i][j]==1){ 137 int x=11; 138 mvwaddch(game_win,pos_x+i,pos_y+1+j,' '); 139 mvwaddch(game_win,pos_x+i+1,pos_y+1+j,'#'); 140 } 141 } 142 } 143 wrefresh(game_win); 144 } 145 } 146 } 147 }
2.方塊變形
作法很簡單,首先,4x4總體按左右對稱,再交換方塊實際長和寬的值,在實際的長和寬這個範圍內再進行左右對稱。
一樣這裏要注意是否發生了越界和方塊堆積,若是發生了,就恢復原形狀。數組
1 void Piece::changeShape(){ 2 int temp[4][4]={0}; 3 int temp1[4][4]={0}; 4 int temp2[4][4]={0}; 5 for(int i=0;i<4;i++){ 6 for(int j=0;j<4;j++){ 7 temp[j][i]=shape[i][j]; 8 temp2[i][j]=shape[i][j];//保存shape數組 9 } 10 } 11 for(int i=0;i<4;i++){ 12 for(int j=0;j<4;j++) 13 shape[i][j]=0; 14 } 15 int temp3=shape_x; 16 shape_x=shape_y; 17 shape_y=temp3; 18 for(int i=0;i<shape_x;i++){ 19 for(int j=0;j<shape_y;j++){ 20 temp1[i][shape_y-1-j]=temp[i][j]; 21 } 22 } 23 for(int i=0;i<4;i++){ 24 for(int j=0;j<4;j++) 25 shape[i][j]=temp1[i][j]; 26 } 27 if(reachBottom()){ 28 for(int i=0;i<4;i++){ 29 for(int j=0;j<4;j++) 30 shape[i][j]=temp2[i][j]; 31 } 32 int temp3=shape_x; 33 shape_x=shape_y; 34 shape_y=temp3; 35 }else{ 36 for(int i=0;i<4;i++){ 37 for(int j=0;j<4;j++){ 38 if(temp2[i][j]==1){ 39 mvwaddch(game_win,pos_x+i+1,pos_y+1+j,' '); 40 } 41 } 42 } 43 wrefresh(game_win); 44 for(int i=3;i>=0;i--){ 45 for(int j=3;j>=0;j--){ 46 if(shape[i][j]==1){ 47 mvwaddch(game_win,pos_x+i+1,pos_y+1+j,'#'); 48 wrefresh(game_win); 49 } 50 } 51 } 52 } 53 }
3.斷定方塊是否接觸邊界和進行方塊堆積
這裏主要是要考慮到,左右上下相似裝飾條的行。方塊堆積就是斷定下一行方塊要佔據的位置是否已經有其餘方塊佔據了。spa
1 bool Piece::reachBottom(){ 2 for(int i=0;i<shape_x;i++){ 3 for(int j=0;j<shape_y;j++){ 4 if(shape[i][j]==1){ 5 if(pos_x+i>(map_x-3)){ 6 return true; 7 } 8 if(pos_y+j>(map_y-3)||pos_y+j<0){ 9 return true; 10 } 11 if(map[pos_x+i+1][pos_y+j+1]==1){ 12 return true; 13 } 14 } 15 } 16 } 17 return false; 18 }
4.對方塊進行消除
從最後一行放置方塊的行號開始,依次斷定此行是否須要消除,消除後還要繼續斷定本行的狀況(應對連續消除多行的狀況)。code
1 for(int i=map_x-3;i>=2;i--){ 2 while(fullLine(i)){ 3 lines++; 4 int k=i-1; 5 while(fullLine(k)){ 6 k--; 7 lines++; 8 } 9 for(int j=0;j<(map_y-3);j++){ 10 map[k+2][j+1]=0; 11 mvwaddch(game_win,k+2,j+1,' '); 12 } 13 int kk=k+1; 14 for(;kk>=2;kk--){ 15 for(int jj=0;jj<(map_y-3);jj++){ 16 if(map[kk][jj+1]==1){ 17 map[kk+1][jj+1]=1; 18 mvwaddch(game_win,kk+1,jj+1,'#'); 19 }else{ 20 map[kk+1][jj+1]=0; 21 mvwaddch(game_win,kk+1,jj+1,' '); 22 } 23 } 24 } 25 score+=(lines*10); 26 std::string tempS; 27 std::ostringstream ex_msg; 28 ex_msg<<"score: "<<score; 29 tempS=ex_msg.str(); 30 mvwprintw(score_win,5,5,tempS.c_str()); 31 wrefresh(score_win); 32 //mvwaddch(game_win,k+1,j,' '); 33 wrefresh(game_win); 34 } 35 }
完整代碼:https://github.com/JsonZhangAA/shiyanlou/tree/master/C%2B%2B_%E4%BF%84%E7%BD%97%E6%96%AF%E6%96%B9%E5%9D%97blog