本文共 7947 字,大约阅读时间需要 26 分钟。
1.设计内容
(1)设计需要生成游戏界面,包括墙壁和底 (2)然后设计生成俄罗斯方块中七个基础方块,设计旋转程序,将其进行旋转,生成21种方块模型 (3)设计程序随机生成21中模型的方块,并自动下移,设计移动方块,left,right,down移动 (4)设计判断程序,当方块碰到墙壁和底停止移动;当方块堆满一行,消除方块;当方块碰到顶,游戏结束 (5)设计隐藏光标程序,让方块在移动过程中不显示光标 2.需求分析 在本代码中,需要规定一个游戏界卖弄,包括墙壁和底部,构建出大概类似于房子的结构,需要函数来实现方块的产生,通过键盘输入来控制方块的移动(right/left/down),旋转(空格键),需要设定判断条件,当方块触碰到墙壁或者底部,便不再继续向着墙壁或者底部的方向移动,当触碰到顶部时便结束游戏,在此时,还需在设定一个判断,看用户是否要继续游戏(y/n),如果是,便继续游戏,如果否,便按任意键结束游戏,还有就是得设定一个判断,当小方块堆积满一行便进行消除。为了美观,还需要写一个子函数来对方块进行上色和隐藏光标,当然,计分又是游戏的重要一部分,我们还需要设计子函数来对玩家的分数进行记录。3.系统设计
共设计了10个子函数来实现俄罗斯方块的生成,旋转,自由下落,实现隐藏光标,移动光标,给方块上色,制作出游戏界面,实行判断,看方块有无碰到墙壁,看方块是否堆积成一行,进行消除。记录分数,当方块碰到顶部就退出游戏,再看用户是否要继续游戏(y/n),如果是,便继续游戏,如果否,便按任意键结束游戏。 3.1 模块划分 模块分为方块的产生与清除,方块的移动与颜色,消行于计分,隐藏光标于判断方块是否到底四部分。 功能模块图void stat_game(){ int n, ch, t = 0, x = 0, y = FACE_Y / 2 - 2, i, j; int space1 = 0;//旋转次数 kongge(nn, space1, 4, FACE_Y + 3); n = nn; nn = rand() % 7; //随机生成下一块 color(nn); fangkuai(nn, space1, 4, FACE_Y + 3); while (1) { color(n); fangkuai(n, space1, x, y);//画-出图形 if (t == 0) t = 15000; while (--t) { if (kbhit() != 0)//有输入就跳出 break; } if (t == 0) { if (judge(n, space1, x + 1, y) == 1) { kongge(n, space1, x, y); x++; //自动向下降落 } else //不能下落后使图形的方为aBox { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (dia[n][space1].space[i][j] == 1) { face.data[x + i][y + j] = Box; face.color[x + i][y + j] = n; while (compare()); } } } return; } } else { ch = getch(); switch (ch) //移动 { case LEFT: if (judge(n, space1, x, y - 1) == 1) //判断是否左可以移动 { kongge(n, space1, x, y); y--; } break; case RIGHT: if (judge(n, space1, x, y + 1) == 1) //判断是否右可以移动 { kongge(n, space1, x, y); y++; } break; case DOWN: if (judge(n, space1, x + 1, y) == 1) //判断是否下可以移动 { kongge(n, space1, x, y); x++; } break; case SPACE: if (judge(n, (space1 + 1) % 4, x + 1, y) == 1) //判断是否能旋转 { kongge(n, space1, x, y); space1 = (space1 + 1) % 4; } break; case ESC: system("cls"); gotoxy(FACE_X / 2, FACE_Y); printf("---游戏结束!---\n\n"); gotoxy(FACE_X / 2 + 2, FACE_Y); printf("---按任意键退出---\n"); getch(); exit(0); break; case 'R': case 'r': main(); exit(0); case 'S': case 's': while (1) { if (kbhit() != 0)//有输入就跳出 break; } break; } } }}
输入:空
输出:表现在方块的移动,输出“游戏结束”“按任意键退出”等字体 效果:int compare(){ int i, j, k, sum; for (i = FACE_X - 2; i > 4; i--) { sum = 0; for (j = 1; j < FACE_Y - 1; j++) { sum += face.data[i][j]; } if (sum == 0) break; if (sum == FACE_Y - 2) //满行减掉,消除 { grade += 100; color(7); gotoxy(FACE_X - 4, 2 * FACE_Y + 2); printf("分数:%d", grade); for (j = 1; j < FACE_Y - 1; j++) { face.data[i][j] = Kong; gotoxy(i, 2 * j); printf(" "); } for (j = i; j > 1; j--) { sum = 0; for (k = 1; k < FACE_Y - 1; k++) { sum += face.data[j - 1][k] + face.data[j][k]; face.data[j][k] = face.data[j - 1][k]; if (face.data[j][k] == Kong) { gotoxy(j, 2 * k); printf(" "); } else { gotoxy(j, 2 * k); color(face.color[j][k]); printf("■"); } } if (sum == 0) return 1; } } } for (i = 1; i < FACE_Y - 1; i++) { if (face.data[1][i] == Box) { char n; Sleep(2000); //延时 system("cls"); color(7); do { gotoxy(FACE_X / 2 + 2, 2 * (FACE_Y / 3)); printf("是否重新开始游戏(y/n): "); scanf("%c", &n); gotoxy(FACE_X / 2 + 4, 2 * (FACE_Y / 3)); if (n != 'n' && n != 'N' && n != 'y' && n != 'Y') printf("输入错误请重新输!"); else break; } while (1); if (n == 'n' || n == 'N') { gotoxy(FACE_X / 2 + 4, 2 * (FACE_Y / 3)); printf("按任意键退出游戏"); exit(0); } else if (n == 'y' || n == 'Y') main(); } } return 0;}
输入:空
输出:表现在方块堆满一行便进行消除 效果:int judge(int n, int space_c, int x, int y) //判断是否到底{ int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (dia[n][space_c].space[i][j] == 0) continue; else if (face.data[x + i][y + j] == Wall || face.data[x + i][y + j] == Box) return 0; } } return 1;}
输入:空
输出:表现在方块到底便不再移动 效果:void kongge(int base, int space_c, int x, int y){ int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { gotoxy(x + i, 2 * (y + j)); if (dia[base][space_c].space[i][j] == 1) printf(" "); } }}
输入:空
输出“ “ 效果:void fangkuai(int base, int space_c, int x, int y){ int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { gotoxy(x + i, 2 * (y + j)); if (dia[base][space_c].space[i][j] == 1) printf("■"); } }}
输入:空
输出;■ 效果:void init_dia(){ int i, j, k, z; int tmp[4][4]; for (i = 0; i < 3; i++) dia[0][0].space[1][i] = 1; dia[0][0].space[2][1] = 1; //土形? for (i = 1; i < 4; i++) dia[1][0].space[i][1] = 1; dia[1][0].space[1][2] = 1; //L形1 for (i = 1; i < 4; i++) dia[2][0].space[i][2] = 1; dia[2][0].space[1][1] = 1; //L形2 for (i = 0; i < 2; i++) { dia[3][0].space[1][i] = 1; dia[3][0].space[2][i + 1] = 1; //Z形1 dia[4][0].space[1][i + 1] = 1; dia[4][0].space[2][i] = 1;//Z形2 dia[5][0].space[1][i + 1] = 1; dia[5][0].space[2][i + 1] = 1;//田字形 } for (i = 0; i < 4; i++) dia[6][0].space[i][2] = 1;//1形? //基础个形状 for (i = 0; i < 7; i++) { for (z = 0; z < 3; z++) { for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { tmp[j][k] = dia[i][z].space[j][k]; } } for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { dia[i][z + 1].space[j][k] = tmp[4 - k - 1][j]; } } } } //旋转的21个形状}
输入:旋转(空格键)
输出:生成21种俄罗斯方块 效果:void inter_face()//开始界面{ int i, j; for (i = 0; i < FACE_X; i++) { for (j = 0; j < FACE_Y + 10; j++) { if (j == 0 || j == FACE_Y - 1 || j == FACE_Y + 9) { face.data[i][j] = Wall; gotoxy(i, 2 * j); printf("■"); } else if (i == FACE_X - 1) { face.data[i][j] = Box; gotoxy(i, 2 * j); printf("■"); } else face.data[i][j] = Kong; } } gotoxy(FACE_X - 18, 2 * FACE_Y + 2); printf("左移:←"); gotoxy(FACE_X - 16, 2 * FACE_Y + 2); printf("右移:→"); gotoxy(FACE_X - 14, 2 * FACE_Y + 2); printf("旋转"); gotoxy(FACE_X - 12, 2 * FACE_Y + 2); printf("暂停ª"); gotoxy(FACE_X - 10, 2 * FACE_Y + 2); printf("退出 ESC"); gotoxy(FACE_X - 8, 2 * FACE_Y + 2); printf("重新开始"); gotoxy(FACE_X - 4, 2 * FACE_Y + 2); printf("分数%d", grade);}
输入:<-/->
输出:表现生成的游戏界面和方块的移动上 效果:void gotoxy(int x, int y) //移动光标{ COORD coord; coord.X = y; coord.Y = x; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);}
输入:空
输出:表现在方块的移动上 效果:void hidden_cursor()//隐藏光标{ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut, &cci); cci.bVisible = 0;//赋1为显示,赋0为隐藏 SetConsoleCursorInfo(hOut, &cci);}
输入:空
输出:表现在在方块移动时不出现光标 效果:int color(int c){ switch (c) { case 0: c = 9; break; case 1: case 2: c = 12; break; case 3: case 4: c = 14; break; case 5: c = 10; break; case 6: c = 13; break; default: c = 7; break; } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色¦ return 0;}
输入:空
输出:表现在方块颜色上 效果:转载地址:http://nqoiz.baihongyu.com/