俄罗斯方块demo
程序员文章站
2022-04-16 07:57:45
这是我的第一篇随笔,当然是发我写的第一个游戏啦! 大一(本人现在大二)寒假过完年,在家待着想起放假前计划写一个游戏的,因为本人立志走游戏开发这条路,加上大一上册学了C语言,就想写个游戏练练手。想了很久,最后决定写一个俄罗斯方块。 万事开头难,一开始真的不知道从何下手,所以百度查了一些资料(程序猿必须 ......
这是我的第一篇随笔,当然是发我写的第一个游戏啦!
大一(本人现在大二)寒假过完年,在家待着想起放假前计划写一个游戏的,因为本人立志走游戏开发这条路,加上大一上册学了c语言,就想写个游戏练练手。想了很久,最后决定写一个俄罗斯方块。
万事开头难,一开始真的不知道从何下手,所以百度查了一些资料(程序猿必须要学会百度),看了一下其他大牛写的,理了理思路,开干!
直接上代码!
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<windows.h> #include<conio.h> #define space 32 //空格键 旋转 #define left 75 //左方向键 向左移动 #define right 77 //右方向键 向右移动 #define down 80 //下方向键 加速向下移动 #define esc 27 //esc键 退出 #define wall 2 //围墙 #define box 1 //方块 #define kong 0 #define face_x 30 //方块长度 #define face_y 20 //方块高度 void start_game(); //游戏循环 void gotoxy(int x, int y); //设置光标位置 void hidden_cursor(); //隐藏光标 int color(int c); //设置颜色 void init_face(); //初始化界面 void init_dia(); //初始化方块形状 void draw_dia(int base, int space_t, int x, int y); //画方块 void draw_space(int base, int space_t, int x, int y); //画空格 int border(int n, int space_t, int x, int y); //边界检测 int del(); //删除增加分数 void read_file(); //读入最高纪录 void write_file(); //写入最高纪录 struct face { int data[face_x][face_y + 10]; //为1是方块,为0是空格 int color[face_x][face_y + 10]; }face; typedef struct diamonds { int space[4][4]; //4*4矩阵,为1是方块,为0是空格 }dia; dia dia[7][4]; //一维表示7种形状,二维表示旋转次数 int grade = 0; int max = 0; int b = 0; int main() { system("cls"); system("title 俄罗斯方块"); color(7); system("mode con cols=60 lines=30"); hidden_cursor(); srand(time(null)); read_file(); grade = 0; init_face(); init_dia(); b = rand() % 7; while (1) start_game(); return 0; } void start_game() { int n, ch, t = 0, x = 0, y = face_y / 2 - 2, i, j; int space_t = 0; draw_space(b, space_t, 4, face_y + 3); n = b; b = rand() % 7; color(b); draw_dia(b, space_t, 4, face_y + 3); while (1) { color(n); draw_dia(n, space_t, x, y); if (t == 0) t = 20000; while (--t) if (kbhit() != 0) break; if (t == 0) { if (border(n, space_t, x + 1, y) == 1) { draw_space(n, space_t, x, y); x++; } else { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (dia[n][space_t].space[i][j] == 1) { face.data[x + i][y + j] = 1; face.color[x + i][y + j] = n; while (del()); } } } return; } } else { ch = getch(); switch (ch) { case left: { if (border(n, space_t, x, y - 1) == 1) { draw_space(n, space_t, x, y); y--; } break; } case right: { if (border(n, space_t, x, y + 1) == 1) { draw_space(n, space_t, x, y); y++; } break; } case down: { if (border(n, space_t, x + 1, y) == 1) { draw_space(n, space_t, x, y); x++; } break; } case space: { if (border(n, (space_t + 1) % 4, x + 1, y) == 1) { draw_space(n, space_t, x, y); space_t = (space_t + 1) % 4; } break; } case esc: { system("cls"); gotoxy(face_x / 2 - 2, face_y); printf("游戏结束!\n"); gotoxy(face_x / 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 border(int n, int space_t, int x, int y) { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (dia[n][space_t].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; } int del() { int i, j, k, sum; for (i = face_x - 2; i >= face_x - 6; 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(800); system("cls"); color(7); gotoxy(face_x / 2 - 2, 2 * (face_y / 3)); if (grade > max) { printf("恭喜您打破记录,目前最高纪录为:%d", grade); write_file(); } else if (grade == max) printf("与纪录持平,请突破你的极限!"); else printf("请继续努力,你与最高记录只差:%d", max - grade); gotoxy(face_x / 2, 2 * (face_y / 3)); printf("game over!\n"); 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; } void read_file() { file *fp; fp = fopen("俄罗斯方块记录.txt", "r+"); if (fp == null) { fp = fopen("俄罗斯方块记录.txt", "w+"); fwrite(&max, sizeof(int), 1, fp); } fseek(fp, 0, 0); fread(&max, sizeof(int), 1, fp); fclose(fp); } void write_file() { file *fp; fp = fopen("俄罗斯方块记录.txt", "r+"); fwrite(&grade, sizeof(int), 1, fp); fclose(fp); } void draw_space(int base, int space_t, 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_t].space[i][j] == 1) printf(" "); } } } void draw_dia(int base, int space_t, 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_t].space[i][j] == 1) printf("■"); } } } void init_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 - 20, 2 * face_y + 2); printf("左移:←"); 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("旋转:space"); gotoxy(face_x - 12, 2 * face_y + 2); printf("暂停: s"); gotoxy(face_x - 10, 2 * face_y + 2); printf("退出: esc"); gotoxy(face_x - 8, 2 * face_y + 2); printf("重新开始:r"); gotoxy(face_x - 6, 2 * face_y + 2); printf("最高纪录:%d", max); gotoxy(face_x - 4, 2 * face_y + 2); printf("当前分数:%d", grade); } void init_dia() { int i, j, k, z; int b[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][2] = 1; dia[1][0].space[1][1] = 1; //l形 for (i = 1; i < 4; i++) dia[2][0].space[i][1] = 1; dia[2][0].space[1][2] = 1; //倒l形 for (i = 0; i < 2; i++) { dia[3][0].space[1][i] = 1; dia[3][0].space[2][i + 1] = 1; //z形 dia[4][0].space[1][i + 1] = 1; dia[4][0].space[2][i] = 1; //倒z形 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; //直形 for (i = 0; i < 7; i++) { for (z = 0; z < 3; z++) { for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { b[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] = b[3 - k][j]; } } } } } void gotoxy(int x, int y) { coord coord; coord.x = y; coord.y = x; setconsolecursorposition(getstdhandle(std_output_handle), coord); } void hidden_cursor() { console_cursor_info cci; getconsolecursorinfo(getstdhandle(std_output_handle), &cci); cci.bvisible = 0; setconsolecursorinfo(getstdhandle(std_output_handle), &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; }
由于是大一写的,所以没有什么注释,我补了一些,如果有感兴趣的朋友直接私聊我(1527985747@qq.com),我们可以一起讨论,一起进步!!!
上一篇: 课程《HTML 入门与实战》学习笔记分享
下一篇: 回文数题解