1 /******************************************** 2 * 程序名称:MR.DUAN 的打砖块(KILL THE BLOCKS !) 3 * 作 者:WindAutumn <duanxu@outlook.com> 4 * 最后修改:2012-8-11-PM 5 * 版 本 号:1.0 6 * 7 *// 好像有个BUG。。。间歇性发作,可能是编译器问题吧,不管了。。。 8 * 9 * *****************************************/ 10 11 #include<stdio.h> 12 #include<Windows.h> 13 #include<conio.h> 14 15 #define PI 3.1415926 16 #define LEFT 0 17 #define RIGHT34 18 #define UP 0 19 #define DOWN24 20 #define X_OFFSET 2 21 #define Y_OFFSET 1 22 #define BLOCK_MAP 0xffff// 砖块地图 23 24 unsigned short block[10]= {0}; 25 char blocks[10][16]= {0}; 26 int arm_head=10+X_OFFSET, arm_tail=18+X_OFFSET; 27 28 void HideCursor(HANDLE hBlock); 29 void GotoXY(HANDLE hBlock, int x, int y); 30 void InitScreen(HANDLE hBlock); 31 void GameStart(); 32 void GameOver(HANDLE hBlock, int mode); 33 void PrintBlock(HANDLE hBlock); 34 void ChangeArm(HANDLE hBlock); 35 void PrintBall(HANDLE hBlock); 36 void KillBlock(HANDLE hBlock, int x, int y); 37 38 void main() 39 { 40 system("color 7b");// 默认颜色,白色底色 41 SetConsoleTitle("KILL THE BLOCKS !");// 设置控制台标题 42 GameStart();// 开始游戏 43 } 44 45 void GameStart() 46 { 47 int i; 48 49 HANDLE hBlock = GetStdHandle(STD_OUTPUT_HANDLE); 50 HideCursor(hBlock);// 隐藏光标 51 InitScreen(hBlock);// 初始化屏幕 52 for(i=0; i<10; i++) 53 block[i]=BLOCK_MAP; 54 PrintBlock(hBlock);// 绘制砖块地图 55 56 GotoXY(hBlock, arm_head, DOWN - 1);// 以下3行打印托盘 57 for(i=0; i<(arm_tail-arm_head)/2+1; i++) 58 printf("□"); 59 60 PrintBall(hBlock);// 对小球的控制 61 } 62 63 void InitScreen(HANDLE hBlock)// 初始化屏幕 64 { 65 int i; 66 SetConsoleTextAttribute(hBlock, FOREGROUND_INTENSITY | FOREGROUND_BLUE | BACKGROUND_BLUE |BACKGROUND_GREEN | BACKGROUND_RED); 67 // 白的背景色,亮蓝色前景色 68 GotoXY(hBlock, 0, 0); 69 printf("╔"); 70 for(i=1; i<RIGHT/2; i++) 71 printf("═"); 72 //printf("%2d",i); 73 printf("╗"); 74 75 for(i=1; i< DOWN; i++) 76 { 77 GotoXY(hBlock, 0, i); 78 //printf("%d",i); 79 printf("║"); 80 GotoXY(hBlock, RIGHT, i); 81 printf("║"); 82 } 83 84 GotoXY(hBlock, 0, DOWN); 85 printf("╚"); 86 for(i=1; i<RIGHT/2; i++) 87 printf("═"); 88 printf("╝"); 89 90 GotoXY(hBlock, 0, 0); 91 92 } 93 94 void HideCursor(HANDLE hBlock)// 隐藏光标 95 { 96 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 97 SetConsoleCursorInfo(hBlock, &cursor_info); 98 } 99 100 void GotoXY(HANDLE hBlock, int x, int y) 101 { 102 COORD coord; 103 coord.X = x; 104 coord.Y = y; 105 SetConsoleCursorPosition(hBlock, coord); 106 } 107 108 void PrintBlock(HANDLE hBlock) 109 { 110 int i,j; 111 for(i=0; i<10; i++)// 打印右侧数字视图 112 { 113 for(j=0; j<16; j++) 114 { 115 if(((block[i]<<j)&0x8000) == (unsigned short)0x8000) 116 blocks[i][j]=1; 117 else blocks[i][j]=0; 118 GotoXY(hBlock,50+j,i); 119 printf("%d",blocks[i][j]); 120 } 121 } 122 for(i=0; i<10; i++)// 打印砖块 123 { 124 for(j=0; j<16; j++) 125 { 126 if(blocks[i][j]==1) 127 { 128 GotoXY(hBlock,2+2*j,1+i); 129 printf("□"); 130 } 131 } 132 } 133 } 134 135 void ChangeArm(HANDLE hBlock) 136 { 137 int key_direct=0; 138 if(_kbhit()) 139 { 140 key_direct = getch(); 141 if(key_direct == 'a'&&arm_head > LEFT+2)// 托盘往左走 142 { 143 arm_head -= 2; 144 GotoXY(hBlock, arm_head, DOWN-1); 145 printf("□"); 146 GotoXY(hBlock, arm_tail, DOWN-1); 147 printf(" "); 148 arm_tail -= 2; 149 } 150 if(key_direct == 'd'&&arm_tail < RIGHT-2)// 托盘向右走 151 { 152 arm_tail += 2; 153 GotoXY(hBlock, arm_tail, DOWN-1); 154 printf("□"); 155 GotoXY(hBlock, arm_head, DOWN-1); 156 printf(" "); 157 arm_head += 2; 158 } 159 } 160 } 161 162 void PrintBall(HANDLE hBlock) 163 { 164 int k,flag=0; 165 int x = (arm_head+arm_tail)/2, y =DOWN - 2;// 球的坐标 166 int tempx = x,tempy = y; 167 int degree =90;// 初始角度 168 169 GotoXY(hBlock, x, y);// 初始球坐标 170 printf("□"); 171 while(1) 172 { 173 if(x == LEFT+2 || x == RIGHT-2) 174 degree = (degree<=180)?(180-degree):(540-degree);// 碰左右边的角度计算 175 if(y == UP+1) 176 degree = 360 - degree;// 碰上边的角度计算 177 if(y == DOWN-2) 178 { 179 if(!(x>=arm_head&&x<=arm_tail))// 没有碰上托盘的情况 180 GameOver(hBlock,0);// 失败 181 else if(degree > 180) 182 { 183 if(x == (arm_head+arm_tail)/2) 184 degree = 360 - degree;// 计算碰托盘之后角度 185 else 186 degree = 360 - degree + 15 * ((arm_head+arm_tail)/2 - x); 187 } 188 189 } 190 switch(degree)// 根据角度确定方块移动方向 191 { 192 case 360: 193 case 0: 194 case 30 : 195 tempx = x+2; 196 tempy = y-1; 197 break; 198 case 60 : 199 tempx = x+2; 200 tempy = y-1; 201 break; 202 case 90 : 203 tempx = x ; 204 tempy = y-1; 205 break; 206 case 120 : 207 tempx = x-2; 208 tempy = y-1; 209 break; 210 case 150 : 211 tempx = x-2; 212 tempy = y-1; 213 break; 214 case 180: 215 case 210 : 216 tempx = x-2; 217 tempy = y+1; 218 break; 219 case 240 : 220 tempx = x-2; 221 tempy = y+1; 222 break; 223 case 270 : 224 tempx = x ; 225 tempy = y+1; 226 break; 227 case 300 : 228 tempx = x+2; 229 tempy = y+1; 230 break; 231 case 330 : 232 tempx = x+2; 233 tempy = y+1; 234 break; 235 } 236 237 GotoXY(hBlock, tempx, tempy);// 下一个点在哪? 238 printf("□"); 239 GotoXY(hBlock, x, y);// 消除上一个点 240 printf(" "); 241 x = tempx; 242 y = tempy; 243 244 ChangeArm(hBlock); 245 KillBlock(hBlock,x,y); 246 for(k=0; k<10; k++)// 如果每行非0就置flag为1 247 if(block[k]!=(unsigned short)0x0000) 248 flag=1; 249 if(flag==0)// 如果flag为0则游戏胜利 250 GameOver(hBlock,1); 251 flag=0; 252 GotoXY(hBlock,50,20);// 打印坐标,角度信息 253 printf("%3d,%2d,%2d",degree,x,y); 254 Sleep(100);// 暂停0.1s *********************important 255 } 256 } 257 258 void KillBlock(HANDLE hBlock, int x, int y) 259 { 260 int i,j; 261 unsigned short temp; 262 i=y-1; 263 j=(x-2)/2; 264 if(blocks[i][j] == 1) 265 { 266 blocks[i][j] = 0; 267 temp = ~(0x0001<<j);// 掩码 268 block[i]=block[i] & temp;// 将block信息与( 1111 1110 1111 1111 )进行与运算,消除bit位 269 GotoXY(hBlock,50+j,i);// 刷新右侧数字区 270 printf("0"); 271 //GotoXY(hBlock,50,12+i);// 打印实时每行信息 272 //printf("%#x",block[j]); 273 } 274 } 275 276 void GameOver(HANDLE hBlock, int mode) 277 { 278 GotoXY(hBlock,50,15); 279 if(mode) 280 printf("you win"); 281 else 282 printf("you loss"); 283 284 getch(); 285 exit(0); 286 }