C语言俄罗斯方块(详解..)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("━"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2 , STARTY); printf("┳"); goto_rood(STARTX + (SCREEN_WIDTH + 2 + CONTRAL_WIDTH) * 2, STARTY + SCREEN_LENGTH + 1);
Message("[SpaceBack]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 18); Message("退出 [ESC]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 20); Message("设置 S", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 22);
hide_curcor(); //各种画边框 goto_rood(STARTX + (SCREEN_WIDTH + 2 + CONTRAL_WIDTH) * 2, STARTY); printf("┓"); goto_rood(STARTX, STARTY); printf("┏"); for (i = 0; i < SCREEN_WIDTH + CONTRAL_WIDTH + 1; i++)
goto_rood(STARTX, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + CONTRAL_WIDTH + 2) * 2, STARTY + i); printf("┃"); }
printf("□"); blockdata[i][j] = 1; } else blockdata[i][j] = 0; x1 += 2; } y1++; } }
void FillScreen(int xx, int yy) //方块停止后填充屏幕数组 {
int i, j; int screen_r = yy - STARTY; int screen_c = (xx - STARTX) / 2 ; for (i = 0; i < 4; i++)
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 13); Message("开始 [回车]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 15); Message("暂停 / 开始", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 17);
for (i = 0; i < 4; i++) { view_x = STARTX + SCREEN_WIDTH*2 + 7; for (j = 0; j < 4; j++) { goto_rood(view_x, view_y); n = (bk >> (3 - j) + 4 * (3 - i)) & 1; if (n) printf("□"); else printf(" "); view_x += 2; } view_y++; }
return FALSE; } //--------------------------------------------------------------------bool RightCollision(int xx, int yy, int block[][4]) //同上 {
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#define SCREEN_LENGTH 22 //游戏区屏幕长
#define SCREEN_WIDTH 14 //游戏区屏幕 实则 28,14 是一 2 个字符宽度计算的
for (j = 0; j < 4; j++) blockdata[i][j] = 0; //初始化方块数据
for (i = 1; i <= SCREEN_LENGTH; i++) for (j = 1; j <= SCREEN_WIDTH; j++) gamescreen[i][j] = 0;
//将屏幕边框初始化为 1,即满填充状态 for (j = 0; j < SCREEN_WIDTH + 2; j++)
#define CONTRAL_WIDTH 7 //控制区宽,控制区长与游戏区长相同
#define STARTX 15
//画界面的初始坐标 X 反省的时刻到了,如果我将屏幕数组
包含了边界,那样会简单很多的吧
#define STARTY 1 #define MARK 0xf
// ............. Y //检验数
//显示文字信息 void Message(char *s, int x, int y) {
goto_rood(x, y); puts(s); }
void delay(int ms) //延迟函数 {
int start, finish; start = finish = clock();
CLOCKS_PER_SECOND while (start + ms > finish) finish = clock();
}
//CLOCKS_PER_SECOND
1000000
返 回 值 是 clock() /
//随机生成一个小于 max 的数 int Random(int max) {
time_t num; num = time(NULL) % max; return num; } //初始化游戏窗口 void IniGameWindow() { int i, j; //将游戏区域屏幕初始化为 0, 即无填充状态 for (i = 0; i < 4; i++)
int i, j, n, marky; int x1, y1 = yy; int flag;
for (i = 0; i < 4; i++) {
x1 = xx; for (j = 0; j < 4; j++) {
goto_rood(x1, y1); //从左往右,从高位向地位填充方块数组 n = (bk >> (3 - j) + 4 *(3 - i)) & 1; //n 只能为 1 或 0,用来判断数组当前元素的 值 if(n) {
printf("┛"); goto_rood(STARTX, STARTY + SCREEN_LENGTH + 1); printf("┗"); for (i = 0; i < SCREEN_WIDTH + CONTRAL_WIDTH + 1; i++)
printf("━"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + SCREEN_LENGTH + 1); printf("┻"); for(i = 1; i <= SCREEN_LENGTH; i++) {
int i, j;
int screen_r = yy - STARTY; int screen_c = (xx - STARTX) / 2;
for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) { if (block[i][j]) if (gamescreen[screen_r + i][screen_c + j])//如果相邻位置已有方块占据 return TRUE; }
}//1 3 10 14 15 17 typedef unsigned __int16 u_int16; //新定义一个只表示 16 位的 int 的数据类型,其实直接 short int 就行。。 = =
//总共 19 种方块,这个数组用于表示 19 种方块的数据
u_int16 blockinds[19] = { 0x6600, //方块 □
//例如 0x6600,表示成二进制就是
0x4444, 0x0F00, // | — 0x2640, 0xC600, // =_ ∟ 块的样式
// 0110 // 0110
发现没有 1 表示的区域就是所绘方
0x4620, 0x3600, // _=
//
0x2700, 0x2620, 0x7200, 0x4640, // ⊥
gamescreen[0][j] = gamescreen[SCREEN_LENGTH + 1][j] = 1; for (i = 0; i < SCREEN_LENGTH + 2; i++)
gamescreen[i][0] = gamescreen[i][SCREEN_WIDTH + 1] = 1;
for (j = 0; j < 4; j++) if(blockdata[i][j]) gamescreen[screen_r + i][screen_c + j] = blockdata[i][j];
}
void DrawView(int bk) //画预览区 ,就是显示下一个方块的样子
{ int i, j, n; int view_x; int view_y = STARTY + 1;
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 5); Message("分数: ", STARTX + 2 *SCREEN_WIDTH + 4, STARTY + 7);
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 9); Message("等级: ", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 11);
0000 0000
Hale Waihona Puke Baidu
0x4460, 0x1700, 0x6220, 0x7400, // ∟ 0x44C0, 0x8E00, 0x6440, 0xE200 // 」
};
enum Gmstatue{ //游戏状态 GMOVER = 0, GOON = 1
};
//画方块 void DrawBlock(int xx, int yy, u_int16 bk) {
}
// 越界函数特别需要注意------------------------------------------------------------------bool LeftCollision(int xx, int yy, int block[][4]) //能否向左移,即向左移是否发生碰撞 {
}
void RemoveBlock(int xx, int yy) //消除方块 //传递当前矩阵的位置
{ int i, j; int x1, y1 = yy; for (i = 0; i < 4; i++) { x1 = xx; for (j = 0; j < 4; j++) { goto_rood(x1, y1); if (blockdata[i][j]) printf(" "); x1 += 2; } y1++; }
int gamescreen[SCREEN_LENGTH + 2][SCREEN_WIDTH + 2]; //界面数组,包含边框
int blockdata[4][4]; //用于存放方块的数据 //隐藏光标函数 void hide_curcor() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut, &cci); cci.bVisible = false; SetConsoleCursorInfo(hOut, &cci); }
//光标跳转函数 void goto_rood(int x, int y) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hOut, pos); }
Message("[SpaceBack]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 18); Message("退出 [ESC]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 20); Message("设置 S", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 22);
hide_curcor(); //各种画边框 goto_rood(STARTX + (SCREEN_WIDTH + 2 + CONTRAL_WIDTH) * 2, STARTY); printf("┓"); goto_rood(STARTX, STARTY); printf("┏"); for (i = 0; i < SCREEN_WIDTH + CONTRAL_WIDTH + 1; i++)
goto_rood(STARTX, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + CONTRAL_WIDTH + 2) * 2, STARTY + i); printf("┃"); }
printf("□"); blockdata[i][j] = 1; } else blockdata[i][j] = 0; x1 += 2; } y1++; } }
void FillScreen(int xx, int yy) //方块停止后填充屏幕数组 {
int i, j; int screen_r = yy - STARTY; int screen_c = (xx - STARTX) / 2 ; for (i = 0; i < 4; i++)
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 13); Message("开始 [回车]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 15); Message("暂停 / 开始", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 17);
for (i = 0; i < 4; i++) { view_x = STARTX + SCREEN_WIDTH*2 + 7; for (j = 0; j < 4; j++) { goto_rood(view_x, view_y); n = (bk >> (3 - j) + 4 * (3 - i)) & 1; if (n) printf("□"); else printf(" "); view_x += 2; } view_y++; }
return FALSE; } //--------------------------------------------------------------------bool RightCollision(int xx, int yy, int block[][4]) //同上 {
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#define SCREEN_LENGTH 22 //游戏区屏幕长
#define SCREEN_WIDTH 14 //游戏区屏幕 实则 28,14 是一 2 个字符宽度计算的
for (j = 0; j < 4; j++) blockdata[i][j] = 0; //初始化方块数据
for (i = 1; i <= SCREEN_LENGTH; i++) for (j = 1; j <= SCREEN_WIDTH; j++) gamescreen[i][j] = 0;
//将屏幕边框初始化为 1,即满填充状态 for (j = 0; j < SCREEN_WIDTH + 2; j++)
#define CONTRAL_WIDTH 7 //控制区宽,控制区长与游戏区长相同
#define STARTX 15
//画界面的初始坐标 X 反省的时刻到了,如果我将屏幕数组
包含了边界,那样会简单很多的吧
#define STARTY 1 #define MARK 0xf
// ............. Y //检验数
//显示文字信息 void Message(char *s, int x, int y) {
goto_rood(x, y); puts(s); }
void delay(int ms) //延迟函数 {
int start, finish; start = finish = clock();
CLOCKS_PER_SECOND while (start + ms > finish) finish = clock();
}
//CLOCKS_PER_SECOND
1000000
返 回 值 是 clock() /
//随机生成一个小于 max 的数 int Random(int max) {
time_t num; num = time(NULL) % max; return num; } //初始化游戏窗口 void IniGameWindow() { int i, j; //将游戏区域屏幕初始化为 0, 即无填充状态 for (i = 0; i < 4; i++)
int i, j, n, marky; int x1, y1 = yy; int flag;
for (i = 0; i < 4; i++) {
x1 = xx; for (j = 0; j < 4; j++) {
goto_rood(x1, y1); //从左往右,从高位向地位填充方块数组 n = (bk >> (3 - j) + 4 *(3 - i)) & 1; //n 只能为 1 或 0,用来判断数组当前元素的 值 if(n) {
printf("┛"); goto_rood(STARTX, STARTY + SCREEN_LENGTH + 1); printf("┗"); for (i = 0; i < SCREEN_WIDTH + CONTRAL_WIDTH + 1; i++)
printf("━"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + SCREEN_LENGTH + 1); printf("┻"); for(i = 1; i <= SCREEN_LENGTH; i++) {
int i, j;
int screen_r = yy - STARTY; int screen_c = (xx - STARTX) / 2;
for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) { if (block[i][j]) if (gamescreen[screen_r + i][screen_c + j])//如果相邻位置已有方块占据 return TRUE; }
}//1 3 10 14 15 17 typedef unsigned __int16 u_int16; //新定义一个只表示 16 位的 int 的数据类型,其实直接 short int 就行。。 = =
//总共 19 种方块,这个数组用于表示 19 种方块的数据
u_int16 blockinds[19] = { 0x6600, //方块 □
//例如 0x6600,表示成二进制就是
0x4444, 0x0F00, // | — 0x2640, 0xC600, // =_ ∟ 块的样式
// 0110 // 0110
发现没有 1 表示的区域就是所绘方
0x4620, 0x3600, // _=
//
0x2700, 0x2620, 0x7200, 0x4640, // ⊥
gamescreen[0][j] = gamescreen[SCREEN_LENGTH + 1][j] = 1; for (i = 0; i < SCREEN_LENGTH + 2; i++)
gamescreen[i][0] = gamescreen[i][SCREEN_WIDTH + 1] = 1;
for (j = 0; j < 4; j++) if(blockdata[i][j]) gamescreen[screen_r + i][screen_c + j] = blockdata[i][j];
}
void DrawView(int bk) //画预览区 ,就是显示下一个方块的样子
{ int i, j, n; int view_x; int view_y = STARTY + 1;
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 5); Message("分数: ", STARTX + 2 *SCREEN_WIDTH + 4, STARTY + 7);
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 9); Message("等级: ", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 11);
0000 0000
Hale Waihona Puke Baidu
0x4460, 0x1700, 0x6220, 0x7400, // ∟ 0x44C0, 0x8E00, 0x6440, 0xE200 // 」
};
enum Gmstatue{ //游戏状态 GMOVER = 0, GOON = 1
};
//画方块 void DrawBlock(int xx, int yy, u_int16 bk) {
}
// 越界函数特别需要注意------------------------------------------------------------------bool LeftCollision(int xx, int yy, int block[][4]) //能否向左移,即向左移是否发生碰撞 {
}
void RemoveBlock(int xx, int yy) //消除方块 //传递当前矩阵的位置
{ int i, j; int x1, y1 = yy; for (i = 0; i < 4; i++) { x1 = xx; for (j = 0; j < 4; j++) { goto_rood(x1, y1); if (blockdata[i][j]) printf(" "); x1 += 2; } y1++; }
int gamescreen[SCREEN_LENGTH + 2][SCREEN_WIDTH + 2]; //界面数组,包含边框
int blockdata[4][4]; //用于存放方块的数据 //隐藏光标函数 void hide_curcor() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut, &cci); cci.bVisible = false; SetConsoleCursorInfo(hOut, &cci); }
//光标跳转函数 void goto_rood(int x, int y) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hOut, pos); }