俄罗斯方块

这里写目录标题

  • 俄罗斯方块
  • 俄罗斯方块的初始化
    • 欢迎界面
      • 初始化游戏场景
      • 清除方块
      • 绘制方块
      • 在指定位置绘制指定方块的指定方向
      • 清除指定位置指定方向的方块
      • 随机产生下一个方块
      • 在指定位置可以向指定方向移动
      • 检测游戏是否结束
      • 判断当前方块是否可以转向到指定方向
      • 间隔等待的时间
      • 移动
      • 消除第x行,并把上面的行都下移
      • 更新分数
      • 更新等级
      • 检查
      • 源码

俄罗斯方块的初始化

int block[BLOCK_COUNT*4][BLOCK_HEIGHT][BLOCK_WIDTH] = {// |  型方块{0, 0, 0, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 0, 0, 0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{  0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// L 形方块{ 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// 田 形方块{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },// T 形方块{ 0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },// Z 形方块{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 }
};

欢迎界面

void welcome(void) {// 初始化画布initgraph(550, 660);// 设置窗口标题HWND window = GetHWnd(); //获取窗口SetWindowText(window, _T("俄罗斯方块    (远航版本)")); //设置窗口标题// 设置文本的字体样式setfont(40, 0, _T("微软雅黑"));setcolor(WHITE);outtextxy(205, 200, _T("俄罗斯方块(远航)"));setfont(22, 0, _T("楷体"));outtextxy(175, 300, _T("俄罗斯方块(远航版本)!"));Sleep(3000); //睡眠(暂停)3000毫秒,3秒针
}

初始化游戏场景

void initGameScene(void) {char str[16];//清除屏幕cleardevice();rectangle(27, 27, 336, 635);rectangle(29, 29, 334, 633);rectangle(370, 50, 515, 195);setfont(24, 0, _T("楷体"));setcolor(LIGHTGRAY);outtextxy(405, 215, _T("下一个"));setcolor(RED);outtextxy(405, 280, _T("分数"));sprintf(str, "%d", score); outtextxy(415, 310, str);outtextxy(405, 375, _T("等级"));sprintf(str, "%d", rank); outtextxy(425, 405, str);// 操作说明  ↑  ↓ ← →setcolor(LIGHTBLUE);outtextxy(390, 475, "操作说明");outtextxy(390, 500, "↑:旋转");outtextxy(390, 525, "↓: 下降");outtextxy(390, 550, "←: 左移");outtextxy(390, 575, "→: 右移");outtextxy(390, 600, "空格:暂停");
}

清除方块

void clearBlock(void) {setcolor(BLACK);setfont(23, 0, "楷体");for (int i=0; i<BLOCK_HEIGHT; i++) {for (int j=0; j<BLOCK_WIDTH; j++) {//"■"int x = 391 + j * UNIT_SIZE;int y = 71 + i * UNIT_SIZE;outtextxy(x, y, "■");}}
}

绘制方块

void drawBlock(int x, int y) {setcolor(color[NextIndex]);setfont(23, 0, "楷体");for (int i=0; i<BLOCK_HEIGHT; i++) {for (int j=0; j<BLOCK_WIDTH; j++) {//"■"if (block[NextIndex*4][i][j] == 1) {int x2 = x + j * UNIT_SIZE;int y2 = y + i * UNIT_SIZE;outtextxy(x2, y2, "■");}}}
}

在指定位置绘制指定方块的指定方向

void drawBlock(int x, int y, int blockIndex, block_dir_t dir) {setcolor(color[blockIndex]);setfont(23, 0, "楷体");int id = blockIndex * 4 + dir;for (int i=0; i<BLOCK_HEIGHT; i++) {for (int j=0; j<BLOCK_WIDTH; j++) {//"■"if (block[id][i][j] == 1) {int x2 = x + j * UNIT_SIZE;int y2 = y + i * UNIT_SIZE;outtextxy(x2, y2, "■");}}}
}

清除指定位置指定方向的方块

void clearBlock(int x, int y, block_dir_t dir) {setcolor(BLACK);int id = BlockIndex * 4 + dir;y += START_Y;for (int i=0; i<5; i++) {for (int j=0; j<5; j++) {if (block[id][i][j] == 1) {// 擦除该方块的第i行的第j列outtextxy(x+20*j,  y+i*20, "■");}}}
}

随机产生下一个方块

void nextblock(void) {clearBlock(); // 清除右上角区域// 随机选择一种方块srand(time(NULL)); //使用时间函数的返回值,来作为随机种子NextIndex =  rand() % BLOCK_COUNT;drawBlock(391, 71);
}

在指定位置可以向指定方向移动

int moveable(int x0, int y0, move_dir_t moveDir, block_dir_t blockDir) {// 计算当前方块的左上角在30x15的游戏区中的位置(第多少行,第多少列)int x = (y0 - minY) / UNIT_SIZE;int y = (x0 - minX) / UNIT_SIZE;int id = BlockIndex * 4 + blockDir;int ret = 1;if (moveDir == MOVE_DOWN) {for (int i=0; i<5; i++) {for (int j=0; j<5; j++) {if (block[id][i][j] == 1 &&(x + i + 1 >= 30  ||  visit[x+i+1][y+j] == 1)) {ret = 0;}}}} else if (moveDir == MOVE_LEFT) {for (int i=0; i<5; i++) {for (int j=0; j<5; j++) {if (block[id][i][j] == 1 &&(y + j == 0 ||  visit[x+i][y+j-1]==1)) {ret = 0;}}}} else if (moveDir == MOVE_RIGHT) {for (int i=0; i<5; i++) {for (int j=0; j<5; j++) {if (block[id][i][j] == 1 && (y+j+1>=15 || visit[x+i][y+j+1]==1)) {ret = 0;}}}}return ret;
}

检测游戏是否结束

void failCheck() {if (!moveable(START_X, START_Y, MOVE_DOWN, BLOCK_UP)) {setcolor(WHITE);setfont(45, 0, "隶体");outtextxy(75, 300, "GAME OVER!");Sleep(1000);system("pause");closegraph();exit(0);}
}

判断当前方块是否可以转向到指定方向

int rotatable(int x, int y, block_dir_t dir) {int id = BlockIndex * 4 + dir;int xIndex = (y - minY) / 20;int yIndex = (x - minX) / 20;if (!moveable(x, y, MOVE_DOWN, dir)) {return 0;}for (int i=0; i<5; i++) {for (int j=0; j<5; j++) {if (block[id][i][j] == 1 &&(yIndex+j<0 || yIndex+j>=15 || visit[xIndex+i][yIndex+j]==1)) {return 0;}}}return 1;
}

间隔等待的时间

void wait(int interval) { int count  = interval / 10;for (int i=0; i<count; i++) {Sleep(10);if (kbhit()) {return;}}
}

移动

void move(void){int x = START_X;int y = START_Y;int k = 0;block_dir_t  blockDir = BLOCK_UP;// 检测游戏是否结束failCheck();// 持续向下降落while (1) {int curSpeed = speed;if (kbhit()) {int key = getch();if (key == KEY_SPACE) {getch();}}// 清除当前方块clearBlock(x, k, blockDir);if (kbhit()) {int key = getch();if(key == KEY_UP) {block_dir_t nextDir = (block_dir_t)((blockDir + 1) % 4);if (rotatable(x, y+k, nextDir)) {blockDir = nextDir;}} else if (key == KEY_DOWN) {curSpeed = 50;} else if (key == KEY_LEFT) {if (moveable(x, y+k+20, MOVE_LEFT, blockDir)) {x -= 20;}} else if (key ==KEY_RIGHT) {if (moveable(x, y+k+20, MOVE_RIGHT, blockDir)) {x += 20;  //x = x + 20;}}}k += 20;// 绘制当前方块drawBlock(x, y+k, BlockIndex, blockDir);wait(curSpeed);//k += 20;// 方块的“固化”处理if (!moveable(x, y+k, MOVE_DOWN, blockDir)) {mark(x, y+k, BlockIndex, blockDir);break;}}
}

消除第x行,并把上面的行都下移

void down(int x){for (int i=x; i>0; i--) {// 消除第i行,第j列的方格消除for (int j=0; j<15; j++) {if (visit[i-1][j]) {visit[i][j] = 1;markColor[i][j] = markColor[i-1][j];setcolor(markColor[i][j]);outtextxy(20*j + minX, 20*i+minY, "■");} else {visit[i][j] = 0;setcolor(BLACK);outtextxy(20*j + minX, 20*i+minY, "■");}}}// 清除最顶上的哪一行(就是行标为0的那一行)setcolor(BLACK);for (int j=0; j<15; j++) {visit[0][j] = 0;outtextxy(20*j + minX, minY, "■");}
}

更新分数

void addScore(int lines) {char str[32];setcolor(RED);score += lines * 10;sprintf(str, "%d", score);outtextxy(415, 310, str);
}

更新等级

void updateGrade() {// 更新等级的提示// 假设:50分一级rank = score / 50;char str[16];sprintf(str, "%d", rank);outtextxy(425, 405, str);// 更新速度, 等级越高,速度越快,speed越小!// 最慢:500, 最快是100speed = 500 - rank*100;if (speed <= 100) {speed = 100;}
}

检查

void check(void) {int i, j;int clearLines = 0;for (i=29; i>=0; i--) {// 检查第i行有没有满for (j=0; j<15 && visit[i][j]; j++) ;//执行到此处时,有两种情况:// 1. 第i行没有满,即表示有空位 此时 j<15// 2. 第i行已满了,此时 j>=15if (j >= 15) {// 此时,第i行已经满了,就需要消除第i行down(i);  //消除第i行,并把上面的行都下移i++;  // 因为最外层的循环中有 i--, 所以我们先i++, 使得下次循环时,再把这一行检查一下clearLines++;}}// 更新分数addScore(clearLines);// 更新等级(更新等级提示,更新速度)updateGrade();
}

源码

#include <stdio.h>
#include <graphics.h>
#include <time.h>
#include <conio.h> //kbhit()使用int score = 0; //总分
int rank = 0;  //等级#define BLOCK_COUNT    5
#define BLOCK_WIDTH    5
#define BLOCK_HEIGHT   5
#define UNIT_SIZE      20#define START_X   130
#define START_Y   30#define KEY_UP      72
#define KEY_RIGHT   77
#define KEY_DOWN    80
#define KEY_LEFT    75
#define KEY_SPACE   32int speed = 500;
int minX = 30;
int minY = 30;typedef enum {BLOCK_UP,BLOCK_RIGHT,BLOCK_DOWN,BLOCK_LEFT
} block_dir_t;typedef enum {MOVE_DOWN,MOVE_LEFT,MOVE_RIGHT
} move_dir_t;int NextIndex = -1;  //下一个方块的种类
int BlockIndex = -1; //当前方块的种类int color[BLOCK_COUNT] = {GREEN, CYAN,  MAGENTA, BROWN, YELLOW
};int visit[30][15]; //访问数组
int markColor[30][15]; //表示对应位置的颜色int block[BLOCK_COUNT * 4][BLOCK_HEIGHT][BLOCK_WIDTH] = {// |  型方块{0, 0, 0, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 0, 0, 0 },{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{  0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// L 形方块{ 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// 田 形方块{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },// T 形方块{ 0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },// Z 形方块{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 }
};// 欢迎界面
void welcome(void) {// 初始化画布initgraph(550, 660);// 设置窗口标题HWND window = GetHWnd(); //获取窗口SetWindowText(window, _T("俄罗斯方块    (远航版本)")); //设置窗口标题// 设置文本的字体样式settextstyle(40, 0, _T("微软雅黑"));setcolor(WHITE);outtextxy(205, 200, "俄罗斯方块(远航)");settextstyle(22, 0, _T("楷体"));outtextxy(175, 300, _T("俄罗斯方块(远航版本)!"));Sleep(3000); //睡眠(暂停)3000毫秒,3秒针
}// 初始化游戏场景
void initGameScene(void) {char str[16];//清除屏幕cleardevice();rectangle(27, 27, 336, 635);rectangle(29, 29, 334, 633);rectangle(370, 50, 515, 195);settextstyle(24, 0, "楷体");setcolor(LIGHTGRAY);outtextxy(405, 215, "下一个");setcolor(RED);outtextxy(405, 280, "分数");sprintf_s(str, "%d", score);outtextxy(415, 310, str);outtextxy(405, 375, "等级");sprintf_s(str, "%d", rank);outtextxy(425, 405, str);// 操作说明  ↑  ↓ ← →setcolor(LIGHTBLUE);outtextxy(390, 475, "操作说明");outtextxy(390, 500, "↑:旋转");outtextxy(390, 525, "↓: 下降");outtextxy(390, 550, "←: 左移");outtextxy(390, 575, "→: 右移");outtextxy(390, 600, "空格:暂停");
}void clearBlock(void) {setcolor(BLACK);settextstyle(23, 0, "楷体");for (int i = 0; i < BLOCK_HEIGHT; i++) {for (int j = 0; j < BLOCK_WIDTH; j++) {//"■"int x = 391 + j * UNIT_SIZE;int y = 71 + i * UNIT_SIZE;outtextxy(x, y, "■");}}
}
// 绘制方块
void drawBlock(int x, int y) {setcolor(color[NextIndex]);settextstyle(23, 0, "楷体");for (int i = 0; i < BLOCK_HEIGHT; i++) {for (int j = 0; j < BLOCK_WIDTH; j++) {//"■"if (block[NextIndex * 4][i][j] == 1) {int x2 = x + j * UNIT_SIZE;int y2 = y + i * UNIT_SIZE;outtextxy(x2, y2, "■");}}}
}// 绘制方块:  在指定位置绘制指定方块的指定方向
void drawBlock(int x, int y, int blockIndex, block_dir_t dir) {setcolor(color[blockIndex]);settextstyle(23, 0, "楷体");int id = blockIndex * 4 + dir;for (int i = 0; i < BLOCK_HEIGHT; i++) {for (int j = 0; j < BLOCK_WIDTH; j++) {//"■"if (block[id][i][j] == 1) {int x2 = x + j * UNIT_SIZE;int y2 = y + i * UNIT_SIZE;outtextxy(x2, y2, "■");}}}
}// 清除指定位置指定方向的方块
// 参数x: 方块的左上角的x坐标
// 参数y: 方块的左上角在游戏区域内的坐标,距离游戏区域顶部的距离
void clearBlock(int x, int y, block_dir_t dir) {setcolor(BLACK);int id = BlockIndex * 4 + dir;y += START_Y;for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1) {// 擦除该方块的第i行的第j列outtextxy(x + 20 * j, y + i * 20, "■");}}}
}void nextblock(void) {clearBlock(); // 清除右上角区域// 随机选择一种方块srand(time(NULL)); //使用时间函数的返回值,来作为随机种子NextIndex = rand() % BLOCK_COUNT;drawBlock(391, 71);
}// 如果在指定位置可以向指定方向移动,就返回1, 否则就返回0
int moveable(int x0, int y0, move_dir_t moveDir, block_dir_t blockDir) {// 计算当前方块的左上角在30x15的游戏区中的位置(第多少行,第多少列)int x = (y0 - minY) / UNIT_SIZE;int y = (x0 - minX) / UNIT_SIZE;int id = BlockIndex * 4 + blockDir;int ret = 1;if (moveDir == MOVE_DOWN) {for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1 &&(x + i + 1 >= 30 || visit[x + i + 1][y + j] == 1)) {ret = 0;}}}}else if (moveDir == MOVE_LEFT) {for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1 &&(y + j == 0 || visit[x + i][y + j - 1] == 1)) {ret = 0;}}}}else if (moveDir == MOVE_RIGHT) {for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1 &&(y + j + 1 >= 15 || visit[x + i][y + j + 1] == 1)) {ret = 0;}}}}return ret;
}// 检测游戏是否结束
void failCheck() {if (!moveable(START_X, START_Y, MOVE_DOWN, BLOCK_UP)) {setcolor(WHITE);settextstyle(45, 0, "隶体");outtextxy(75, 300, "GAME OVER!");Sleep(1000);system("pause");closegraph();exit(0);}
}// 判断当前方块是否可以转向到指定方向
// 注意, 此时还没有转到该方向!!!
int rotatable(int x, int y, block_dir_t dir) {int id = BlockIndex * 4 + dir;int xIndex = (y - minY) / 20;int yIndex = (x - minX) / 20;if (!moveable(x, y, MOVE_DOWN, dir)) {return 0;}for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1 &&(yIndex + j < 0 || yIndex + j >= 15 || visit[xIndex + i][yIndex + j] == 1)) {return 0;}}}return 1;
}void wait(int interval) {int count = interval / 10;for (int i = 0; i < count; i++) {Sleep(10);if (_kbhit()) {return;}}
}void mark(int x, int y, int blockIndex, block_dir_t dir) {int id = blockIndex * 4 + dir;int x2 = (y - minY) / 20;int y2 = (x - minX) / 20;for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (block[id][i][j] == 1) {visit[x2 + i][y2 + j] = 1;markColor[x2 + i][y2 + j] = color[blockIndex];}}}
}void move(void) {int x = START_X;int y = START_Y;int k = 0;block_dir_t  blockDir = BLOCK_UP;// 检测游戏是否结束failCheck();// 持续向下降落while (1) {int curSpeed = speed;if (_kbhit()) {int key = _getch();if (key == KEY_SPACE) {_getch();}}// 清除当前方块clearBlock(x, k, blockDir);if (_kbhit()) {int key = _getch();if (key == KEY_UP) {block_dir_t nextDir = (block_dir_t)((blockDir + 1) % 4);if (rotatable(x, y + k, nextDir)) {blockDir = nextDir;}}else if (key == KEY_DOWN) {curSpeed = 50;}else if (key == KEY_LEFT) {if (moveable(x, y + k + 20, MOVE_LEFT, blockDir)) {x -= 20;}}else if (key == KEY_RIGHT) {if (moveable(x, y + k + 20, MOVE_RIGHT, blockDir)) {x += 20;  //x = x + 20;}}}k += 20;// 绘制当前方块drawBlock(x, y + k, BlockIndex, blockDir);wait(curSpeed);//k += 20;// 方块的“固化”处理if (!moveable(x, y + k, MOVE_DOWN, blockDir)) {mark(x, y + k, BlockIndex, blockDir);break;}}
}void newblock() {// 确定即将使用的方块的类别BlockIndex = NextIndex;// 绘制刚从顶部下降的方块drawBlock(START_X, START_Y);// 让新出现的方块暂停一会,让用户识别到Sleep(100); //0.1秒// 在右上角区域,绘制下一个方块nextblock();// 方块降落move();
}//消除第x行,并把上面的行都下移
void down(int x) {for (int i = x; i > 0; i--) {// 消除第i行,第j列的方格消除for (int j = 0; j < 15; j++) {if (visit[i - 1][j]) {visit[i][j] = 1;markColor[i][j] = markColor[i - 1][j];setcolor(markColor[i][j]);outtextxy(20 * j + minX, 20 * i + minY, "■");}else {visit[i][j] = 0;setcolor(BLACK);outtextxy(20 * j + minX, 20 * i + minY, "■");}}}// 清除最顶上的哪一行(就是行标为0的那一行)setcolor(BLACK);for (int j = 0; j < 15; j++) {visit[0][j] = 0;outtextxy(20 * j + minX, minY, "■");}
}// 更新分数,参数lines表示消除的行数
void addScore(int lines) {char str[32];setcolor(RED);score += lines * 10;sprintf_s(str, "%d", score);outtextxy(415, 310, str);
}void updateGrade() {// 更新等级的提示// 假设:50分一级rank = score / 50;char str[16];sprintf_s(str, "%d", rank);outtextxy(425, 405, str);// 更新速度, 等级越高,速度越快,speed越小!// 最慢:500, 最快是100speed = 500 - rank * 100;if (speed <= 100) {speed = 100;}
}void check(void) {int i, j;int clearLines = 0;for (i = 29; i >= 0; i--) {// 检查第i行有没有满for (j = 0; j < 15 && visit[i][j]; j++);//执行到此处时,有两种情况:// 1. 第i行没有满,即表示有空位 此时 j<15// 2. 第i行已满了,此时 j>=15if (j >= 15) {// 此时,第i行已经满了,就需要消除第i行down(i);  //消除第i行,并把上面的行都下移i++;  // 因为最外层的循环中有 i--, 所以我们先i++, 使得下次循环时,再把这一行检查一下clearLines++;}}// 更新分数addScore(clearLines);// 更新等级(更新等级提示,更新速度)updateGrade();
}int main(void) {welcome();initGameScene();// 产生新方块nextblock();Sleep(500);// 初始化访问数组memset(visit, 0, sizeof(visit));while (1) {newblock();// 消除满行,并更新分数和速度check();}system("pause");closegraph();return 0;
}


这个是效果图

俄罗斯方块窗口模式--更新迭代相关推荐

  1. android qq聊天窗口切换,手机QQ重磅更新!新增聊天多窗口模式,希望微信也能有...

    原标题:手机QQ重磅更新!新增聊天多窗口模式,希望微信也能有 近日,手机QQ开放了8.0.8版本的内侧版本,新增了特别多的功能,全都非常实用!网友直呼:这QQ新增的功能,都是微信用户期待已久的呀! 聊 ...

  2. android应用窗口模式,[技巧]如何启用Android N开发者预览版中的“自由窗口”模式...

    这里是Android N开发者预览版"自有窗口"模式的一些实际演示截图. 对于已经参加了"Beta Program"的人们来说,通过OTA获取Android N ...

  3. AndroidQ 分屏窗口模式 (AMS部分)

    1. 多窗口 1.1 栈 Android7.0开始支持多窗口,多窗口分为三种,画中画,分屏,自由窗口,多窗口的核心原理其实就是分栈和设置栈边界, 分栈即把不同窗口模式下的Activity放在不同的Ac ...

  4. 关于博客笔记大汇总,持续更新迭代

    目录介绍 1.关于知识图谱 1.1 关于Android知识图谱 1.2 关于博客类型知识图谱 1.3 关于印象笔记思维导图 2.关于开源的项目[13个] 2.1 开源项目思维导图 2.2 开源项目说明 ...

  5. 家居行业渠道商销售系统线上线下一体化运作,促进产品更新迭代

    随着与中国互联网共同成长起来的90后逐渐成长为消费主力,家居行业的数字化都是一个必然的趋势.尤其是在疫情突然来袭的2020年,线下缺失的巨大冲击,让数字化成为了很多企业不得不面对的问题. 家居行业两大 ...

  6. 【Python_PyQtGraph 学习笔记(五)】基于PyQtGraph和GraphicsLayoutWidget动态绘图并实现窗口模式,且保留全部绘图信息

    基于PyQtGraph和GraphicsLayoutWidget动态绘图并实现窗口模式,且保留全部绘图信息 前言 基于PySide2.PyQtGraph和GraphicsLayoutWidget动态绘 ...

  7. Android 7.1 FreeForm 多窗口模式

    平台 RK3288 + Android 7.1 关于Freeform Android N上的多窗口功能有三种模式:(扩展-4) 分屏模式 这种模式可以在手机上使用.该模式将屏幕一分为二,同时显示两个应 ...

  8. 做公众号收入百万的这一年, 时间窗口模式 (Time Window Pattern) 来讲解

    年终总结 写了微信公众号一年啦, 想要总结一下这年的写作情况 这一年总共写了 40 篇文章, 最后有 221 位小伙伴关注了 codog代码狗 文章总结 这些文章里面有一些比较典型的文章, 下面我来列 ...

  9. 计算机知识更新迭代太快,技术更新迭代的步伐越走越快 盘点一年IT圈 几多欢喜几多愁...

    随着新一轮科技革命和产业变革的到来,这几年,技术更新迭代的步伐越走越快.即将过去的2019年,更有不少承上启下.继往开来的突破点.转折点.闪光点,屡屡为我们制造惊喜或惊讶. 在基础设施方面,5G商用的 ...

最新文章

  1. flask小知识点总结
  2. python写出的程序如何给别人使用-如何用PYTHON代码写出音乐
  3. 火星今天飞抵西非国家寻找埃博拉疫情
  4. window - JDK的安装与卸载
  5. Factory Method模式
  6. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建
  7. 想了解Xtrabackup备份原理和常见问题分析,看这篇就够了
  8. luoguP3799 妖梦拼木棒 [组合数学]
  9. 温度湿度传感器流程图_温度传感器和湿度传感器在高铁轨道板智能养护中的应用...
  10. 常见Sqlite管理工具
  11. delphi2007不使用msbuild的方法
  12. 手绘图形识别方法(算法)
  13. 计算机主板清理,电脑主板脏了如何清洗电脑主板才是正确
  14. 2022年茶叶行业现状分析
  15. 回文数,用scratch编程实现回文数
  16. 我的世界基岩版python插件编写教程(pyr教程)
  17. 网页服务器磁盘满了怎么办,远程服务器磁盘满了怎么办
  18. uni-app获取当前位置并计算出某个地点距离
  19. Linux系统配置及服务管理_第07章_存储管理2
  20. JDBC与JAVA程序笔记

热门文章

  1. Ubuntu20.04设置中文失败或重启恢复英文的解决方案
  2. fabric加载gif图片
  3. java逻辑量_Java逻辑类型常量有两个:( )和( )。_学小易找答案
  4. 四款CROSS车型推荐篇
  5. CSS文本字体与背景样式
  6. java 语法检查_Java中的语法检查
  7. Oracle认证专家视频教程-OCP全套教程之学习笔记-logminer
  8. osgEarth要素立体挤出 15. feature_extrude.earth
  9. 华为云排名仅为第二?市场占有率营收被阿里双碾压
  10. elementui 表格插入图片并且鼠标移入放大