首页 > 编程语言 >C++学习路线(二十一)

C++学习路线(二十一)

时间:2024-10-23 20:19:52浏览次数:3  
标签:int void 二十一 ++ C++ 路线 outtextxy BLOCK 方块

俄罗斯方块 

初始化页面

#include <iostream>
#include <graphics.h>
#include <Windows.h>
using namespace std;

void welcome() {
	initgraph(550 , 660);
	HWND window = GetHWnd();
	SetWindowText(window, _T("俄罗斯方块"));
	setfont(40, 0, _T("Arial"));
	outtextxy(120, 200, _T("欢迎来到俄罗斯方块"));
	setfont(20, 0, _T("Arial"));
	outtextxy(200, 250, _T("按任意键开始游戏"));

}

int main() {
	welcome();
	system("pause");
	return 0;
}

设置游戏背景

#include <iostream>
#include <graphics.h>
#include <Windows.h>
using namespace std;

int score = 0;
int rank = 0;

void welcome() {
	initgraph(550 , 660);
	HWND window = GetHWnd();
	SetWindowText(window, _T("俄罗斯方块"));
	setfont(40, 0, _T("Arial"));
	outtextxy(120, 200, _T("欢迎来到俄罗斯方块"));
	setfont(20, 0, _T("Arial"));
	outtextxy(200, 250, _T("按任意键开始游戏"));
	char ch;
	cin >> ch;
}
void initScenes() {
	char str[16];
	cleardevice();
	rectangle(27, 27, 336, 635);
	rectangle(29, 29, 334, 633);
	rectangle(370, 50, 515, 195);

	setfont(30, 0, _T("Arial"));
	setcolor(RED);
	outtextxy(405, 215, _T("下一个"));
	outtextxy(405, 280, _T("得分"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 310, str);
	outtextxy(405, 375, _T("排名"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 405, str);

	setcolor(LIGHTBLUE);
	outtextxy(390, 475, "操作说明:");
	outtextxy(390, 500, "↑↓←→:移动方块");
}

int main() {
	welcome();
	initScenes();
	system("pause");
	return 0;
}

每个方块有4种形态:

4个方向,所以使用4个二维数组来表示1种方块

#include <iostream>
#include <graphics.h>
#include <Windows.h>
using namespace std;

int score = 0;
int rank = 0;
#define  BLOCK_COUNT 5
#define  BLOCK_WIDTH 5
#define  BLOCK_HEIGHT 5
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() {
	initgraph(550 , 660);
	HWND window = GetHWnd();
	SetWindowText(window, _T("俄罗斯方块"));
	setfont(40, 0, _T("Arial"));
	outtextxy(120, 200, _T("欢迎来到俄罗斯方块"));
	setfont(20, 0, _T("Arial"));
	outtextxy(200, 250, _T("按任意键开始游戏"));
	char ch;
	cin >> ch;
}
void initScenes() {
	char str[16];
	cleardevice();
	rectangle(27, 27, 336, 635);
	rectangle(29, 29, 334, 633);
	rectangle(370, 50, 515, 195);

	setfont(30, 0, _T("Arial"));
	setcolor(RED);
	outtextxy(405, 215, _T("下一个"));
	outtextxy(405, 280, _T("得分"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 310, str);
	outtextxy(405, 375, _T("排名"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 405, str);

	setcolor(LIGHTBLUE);
	outtextxy(390, 475, "操作说明:");
	outtextxy(390, 500, "↑↓←→:移动方块");
}

int main() {
	welcome();
	initScenes();
	system("pause");
	return 0;
}

右上角那个方块的显示

#include <iostream>
#include <graphics.h>
#include <Windows.h>
using namespace std;

int score = 0;
int rank = 0;
#define  BLOCK_COUNT 5
#define  BLOCK_WIDTH 5
#define  BLOCK_HEIGHT 5
#define  BLOCK_UNIT 20
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() {
	initgraph(550 , 660);
	HWND window = GetHWnd();
	SetWindowText(window, _T("俄罗斯方块"));
	setfont(40, 0, _T("Arial"));
	outtextxy(120, 200, _T("欢迎来到俄罗斯方块"));
	setfont(20, 0, _T("Arial"));
	outtextxy(200, 250, _T("按任意键开始游戏"));
	char ch;
	cin >> ch;
}
void initScenes() {
	char str[16];
	cleardevice();
	rectangle(27, 27, 336, 635);
	rectangle(29, 29, 334, 633);
	rectangle(370, 50, 515, 195);
	setfont(30, 0, _T("Arial"));
	setcolor(RED);
	outtextxy(405, 215, _T("下一个"));
	outtextxy(405, 280, _T("得分"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 310, str);
	outtextxy(405, 375, _T("排名"));
	sprintf_s(str, "%d", score);
	outtextxy(415, 405, str);
	setcolor(LIGHTBLUE);
	outtextxy(390, 475, "操作说明:");
	outtextxy(390, 500, "↑↓←→:移动方块");
}
int nextIndex = -1;
void clearBlock() {
	setcolor(BLACK);
	setfont(23, 0, "楷体");
	for(int i = 0 ; i < BLOCK_COUNT ; i++)
		for (int j = 0; j < BLOCK_WIDTH; j++) {
			int x = 391 + i * BLOCK_UNIT;
			int y = 70 + j * BLOCK_UNIT;
			outtextxy(x, y, "■"); // 正方形■
		}
}
int color[BLOCK_COUNT] = {
	RED, GREEN, BLUE, YELLOW, CYAN
};
void drawBlock() {
	setcolor(color[nextIndex]);
	setfont(23, 0, "楷体");
	for (int i = 0; i < BLOCK_COUNT; i++)
		for (int j = 0; j < BLOCK_WIDTH; j++) {
			if (block[4 * nextIndex][i][j] == 1) {
				int x = 391 + i * BLOCK_UNIT;
				int y = 70 + j * BLOCK_UNIT;
				outtextxy(x, y, "■");
			}
		}
}
void nextBlock() {
	clearBlock();
	srand(time(NULL)); // 随机种子
	nextIndex = rand() % BLOCK_COUNT;
	drawBlock();
}

int main() {
	welcome();
	initScenes();
	nextBlock();
	system("pause");
	return 0;
}

初始化访问数组

int vis[30][15];

主要函数实现

#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	32

int 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("俄罗斯方块    奇牛学院 Rock")); //设置窗口标题

	// 设置文本的字体样式
	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_s(str, "%d", score);
	outtextxy(415, 310, str);

	outtextxy(405, 375, _T("等级"));
	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);
	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, "■");
			}
		}
	}
}



// 清除指定位置指定方向的方块
// 参数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);
		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 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;
	int curSpeed = speed;

	// 检测游戏是否结束
	failCheck();

	// 持续向下降落
	while (1) {
		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, 最快是100
	speed = 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>=15
		if (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;
}

标签:int,void,二十一,++,C++,路线,outtextxy,BLOCK,方块
From: https://blog.csdn.net/weixin_45169583/article/details/143062464

相关文章

  • C++ deque容器
    dequedeque是C++STL库中的一个容器,常用来当stack、queue的适配器。在算法领域中,适用于解决单调队列单调栈等问题。下面我们就来认识一下deque容器。文章目录deque1.vector与list区别2.deque的介绍和使用2.1deque的介绍2.2deque的使用2.2.1数据访问(**Elementacce......
  • C++ STL基本用法概述(简洁版)
    vector变长数组,倍增思想基本函数 size()   //返回元素个数,时间复杂度为o(1)empty()   //返回a是否为空,时间复杂度为o(1)clear()   //清空front()/back()   //返回第一个数/最后一个数push_back()   //最后插入一个数pop_back()   //删掉最后一个数......
  • 七月在线公开课笔记-二十一-
    七月在线公开课笔记(二十一)人工智能—推荐系统公开课(七月在线出品)-P16:快速入门推荐系统串讲-七月在线-julyedu-BV1Ry4y127CV今天跟大家分享的是深入浅出推荐系统啊,然后我们会围绕着推荐系统,它的核心内容呃,想召回排序重排,这些核心模块进行展开介绍,那首先做下自我介绍。我......
  • (分享源码)计算机毕业设计必看必学 上万套实战教程手把手教学JAVA、PHP,node.js,C++、pyth
    摘 要大数据时代下,数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在网络小说的要求下,开发一款整体式结构的小说网站,将复杂的系统进行拆分,能够实现对需求的变化快速响应、系统稳定性的保......
  • 计算机毕业设计项目推荐,基于协同过滤算法的短视频推荐系统设计与实现30213(开题答辩+程
    摘 要现阶段,社会的发展和科技的进步,以及大数据时代下纷繁数据信息的融合,使得人们在生产及生活过程中,都将会接收到各种类型的数据信息,而通过计算机技术与网络技术,则能够将众多人们所不了解或不常用的信息,以简单的模式转化并传递给人们,使得人们的生产及生活质量得以显著提升......
  • 计算机毕业设计项目推荐:基于Web的社区人员管理系统的设计36303(开题答辩+程序定制+全套
    摘要科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作规则和开发步骤,采用ASP.NET技术建设社......
  • C++多线程同步和加锁的方式
    多线程同步和加锁的方式1.互斥锁(Mutex)互斥锁是一种常见的线程同步机制,用于保护共享资源,确保同一时间只有一个线程可以访问该资源。C++标准库提供了std::mutex类来实现互斥锁。std::mutex的lock()成员函数获取锁,使用完毕后调用unlock()释放锁。推荐使用std::lock_guard......
  • C++实现stack功能
    C++代码实现stack功能,具体代码如下:#include"stdafx.h"#include<iostream>#include<vector>#include<stdexcept>//forstd::out_of_rangetemplate<typenameT>classStack{private: std::vector<T>elements;//底层容器,用于存......
  • C++试题带答案
    阅读以下程序,回答问题1.试写出下列程序的输出结果与功能。 输出:2   sunny  24功能:求所有同学中年龄最大的同学2.试写出下列程序中函数fun()的功能及程序的输出结果。 函数fun()的功能:实现整数m的逆向输出程序的输出结果:543213.简述String类中Setc、Getc和Append三......
  • 【产品经理修炼之道】-SaaS创业路线图(十二):由SaaS产品的价值链,拆解各部门动作
    市场、销售、售后各部门的配合关系如何设计?根据SaaS产品的价值链拆解各部门动作:一、先看看SaaS产品的价值链SaaS的价值链,简化一下是这样的:市场培育——新客户新购——增购用户数——增购新模块——老客户续费……从客户视角看是这样:遇到问题——在市场上看到解决方案/......