设为首页 加入收藏

TOP

从零实现俄罗斯方块(c语言+思路分析)(六)
2023-07-23 13:38:34 】 浏览:183
Tags:从零实 罗斯方 语言 路分析
j), y + i); //光标跳转到指定位置 printf("■"); //输出方块 } } } }

空格覆盖

无论是游戏区方块的移动,还是提示区右上角下一个方块的显示,都需要方块位置的变换,而在变化之前肯定是要先将之前打印的方块用空格进行覆盖,然后再打印变化后的方块。

在覆盖方块时特别需要注意的是,要覆盖一个小方块需要用两个空格。

//空格覆盖
void DrawSpace(int shape, int form, int x, int y)
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			if (block[shape][form].space[i][j] == 1) //如果该位置有方块
			{
				CursorJump(2 * (x + j), y + i); //光标跳转到指定位置
				printf("  "); //打印空格覆盖(两个空格)
			}
		}
	}
}

打印方块的函数到此写完了,然后开始实现下一个目标:若在给定时间间隔内键盘被敲击,则根据所敲击的按键给出相应反馈。很显然我们需要让计算机对我们的键盘进行响应,为了让代码更美观,我们写个宏定义代表每个按键。

#define DOWN 80 //方向键:下
#define LEFT 75 //方向键:左
#define RIGHT 77 //方向键:右

#define SPACE 32 //空格键
#define ESC 27 //Esc键

讲到这里,你们可能会说,啊为什么我就要定义下键为80, 为什么左键是75,不能定义其他的东西嘛。这里我们就要考虑到计算机如何知道我们按下了上下左右键。很简单,百度一下c语言怎么知道键盘按下了什么。我们得知,想要让计算机知道按下了按键,我们要用到一个c语言中一个叫getch()的函数。好我们再搜一下getch函数怎么使用。然后就找到了以下的东西,我给你们贴在这里。

C语言中getch()函数

功 能: 从stdio流中读字符,即从控制台读取一个字符,但不显示在屏幕上

这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏

在用getch()(在头文件conio.h)获得上下左右键的键值时候,他们是双键值,会返回高八位和低八位的int型数值。

int key1=getch()

? key2=getch()

在键盘中按下“上键”后,key1会返回key1=224,key2=72;

下键: key1=224,key2=80;

左键: key1=224,key2=75;

右键: key1=224,key2=77;

至此,我们知道,想要让计算机知道我们按了上下左右,我们就用getch函数捕捉键盘,其中每个值都是不一样的,所以必须设置为80,75,77。

隐藏光标

在用C语言制作动画,游戏或其他需要大量用到清屏指令的程序时,光标会闪烁不停,十分干扰视线,但是只要隐藏光标就可以让体验更佳许多。在这里我们并不讨论如何理解这段代码的使用方法,因为程序员写的大部分代码往往只是解决需求,而不是学会每一种技术的深层使用含义,善于使用Google和百度是你们的必修课,这里我们就直接搜索如何在c语言小游戏中隐藏光标,随便找到一个前人已经替我们写好的函数复制粘贴过来即可。

//隐藏光标

void HideCursor()
{
	CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
	curInfo.dwSize = 1;  //如果没赋值的话,隐藏光标无效
	curInfo.bVisible = FALSE; //将光标设置为不可见
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
	SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}

然后我们开始实现方块下落时判断下落后的合法性

合法性判断

其实在方块移动过程中,无时无刻都在判断方块下一次变化后的位置是否合法,只有合法才会允许该变化的进行。

所谓非法,就是指该方块进行了该变化后落在了本来就有方块的位置。

//合法性判断
int IsLegal(int shape, int form, int x, int y)
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			//如果方块落下的位置本来就已经有方块了,则不合法
			if ((block[shape][form].space[i][j] == 1) && (face.data[y + i][x + j] == 1))
				return 0; //不合法
		}
	}
	return 1; //合法
}

合法性判断至此,开始实现判断得分与结束

判断得分与结束

判断得分:
从下往上判断,若某一行方块全满,则将改行方块数据清空,并将该行上方的方块全部下移,下移结束后返回1,表示还需再次调用该函数进行判断,因为被下移的行并没有进行判断,可能还存在满行。

判断结束:

直接判断游戏区最上面的一行当中是否有方块存在,若存在方块,则游戏结束。
游戏结束后,除了给出游戏结束提示语之外,如果玩家本局游戏分数大于历史最高记录,则需要更新最高分到文件当中。
游戏结束后询问玩家是否再来一局。

//判断得分与结束
int JudeFunc()
{
	//判断是否得分
	for (int i = ROW - 2; i > 4; i--)
	{
		int sum = 0; //记录第i行的方块个数
		for (int j = 1; j < COL - 1; j++)
		{
			sum += face.data[i][j]; //统计第i行的方块个数
		}
		if (sum == 0) //该行没有方块,无需再判断其上的层次(无需再继续判断是否得分)
			break; //跳出循环
		if (sum == COL - 2) //该行全是方块,可得分
		{
			grade += 10; //满一行加10分
			color(7); //颜色设置为白色
			CursorJump(2 * COL + 4, ROW - 3); //光标跳转到显示当前分数的位置
			printf("当前分数:%d", grade); //更新当前分数
			for (int j = 1; j < COL - 1; j++) //清除得分行的方块信息
			{
				face.data[i][j] = 0; //该位置得分后被清除,标记为无方块
				CursorJump(2 * j, i); //光标跳转到该位置
				printf("  "); //打印空格覆盖(两个空格)
			}
			//把被清除行上面的行整体向下挪一格
			for (int m = i; m >1; m--)
			{
				sum = 0; //记录上一行的方块个数
				for (int n = 1; n < COL - 1; n++)
				{
					sum += face.data[m - 1][n]; //统计上一行的方块个数
					face.data[m][n] = face.da
首页 上一页 3 4 5 6 7 8 下一页 尾页 6/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇What is Point? 下一篇函数执行顺序

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目