大一C语言期末程序设计——钢琴快

        本人目前大二,C语言程序设计是大一下学期学的,暂时还没有学数据结构,C语言中比较深入一点的知识也是浅尝辄止,路过的大佬请多多指教!

C语言是一种接近底层的语言,个人认为如果想要用C语言做一个游戏的话还是多运用一些必要的C语言库比较容易实现,所以再开始做项目之前我自学了eaxyx库。本人在接触C语言之前进行过较为系统的Python学习,在学习期间对Python中的pygame库颇感兴趣,在听到C语言期末作业要做一个游戏的时候首先有了‘C语言有没有自己的图形库’之类的疑问,并带着疑问百度搜索,最后在C语言中文网学习了《easyx初级教程》,简单来讲,它的功能就在于可以在C语言环境中进行图形绘制。(easyx的简单使用可以自行百度,太多了,但是建议只学会代码怎么用就好)easyx安装地址https://easyx.cn/

首先,在做事之前先对自己进行能力定位是我的一大习惯。我要用仅有的编程知识做出一个游戏就要尽可能降低难度,所以我选择了钢琴块。钢琴块的实现的简单之处在于它只需要对一个对象做考虑,也就是随机位置落下的方块。

在整个程序中用到的头文件:

#include<stdio.h>//C语言最基本的库所需头文件,不做解释

#include<stdlib.h>//运用链表时所要用到的库所需头文件

#include<graphics.h>//easyx库所需头文件,用于简单的图形绘制

#include<conio.h>//_kbhit()函数所需头文件,用于监听键盘输入,它和scanf()函数最大的区别在于它在进行键盘输入时不需要按回车键

  1. 首先我需要绘制背景和实现小球的降落,这里我用了三条线作为边界(两竖一横),实现代码为

我将屏幕设置成了大致和手机屏幕类似的竖屏,并分为四个区域,之后的方块会在四个区域中的随机区域开始降落。现在的方块只能在第一区域降落一次,并且方块暂时用填充小球代替

  1. 然后我需要实现方块在随机区域的出现,为了实现随机这个特点,我用到了rand()函数,它可以取连续的随机数,但是我要实现的四个区域的X坐标显然是不连续的(75、185、295、405),所以我又声明了一个新的变量xl,并且用switch()函数实现了随机区域的功能。当然,方块既然是从随机区域开始降落,那他就不止一次降落,所以这一就又要用到循环,所以我需要用到链表+for循环的方式。之所以用链表实现,是因为方块这一结构可能不止一个成员,比如我需要考虑它的随机区域的X坐标的值,后面还要判断它是否被消灭(判断游戏是否可以继续或结束),当然,更大的原因是想证明我可以熟练运用链表。

创建并初始化链表:

扫描二维码关注公众号,回复: 15317213 查看本文章

随机区域的实现:

这个for循环的意思是一共会出现51个方块,定义整型变量a并赋予0-3之间的一个随机数,然后用开关函数根据随机数a给整型变量xl赋上X坐标的值,定义整型变量xl而不是直接给x赋值的原因是我认为后面用q->x=xl;更容易理解,当然在开关函数中直接用q->x=75;的方式赋值也是可以的。

然后是用_kbhit()函数进行键盘输入的接收和游戏是否能继续或结束的判断

方块下落到一定高度范围时通过按下所对应区域的按键消灭他,否则方块触底时将会判定为游戏失败。这里我是通过判断Y坐标(高度)实现的,660-720是游戏可以继续的判定范围,当方块落入此区域时按下对应按键时即可消灭方块(p->state=1)。其中_kbhit()意为判断按下了按键,定义整型变量put赋予接收按键对应的数值,接收数值由_getch()函数实现,72是键盘←的对应数值,80,75,77分别对应键盘↓,→,↑的数值。

这里有个问题,就是程序对键盘的命令非常迟钝,经常读取不到键盘命令,所以我一般都是狂按键盘,无解。

游戏结束的判定:

当方块触底且方块未被消灭(p->state==0)时游戏结束(清屏)。

增加亿点细节

增加游戏难度,随已循环次数增加方块下落速度也增加,最大值为30ms

给方块换个造型:

这里比较简单,就是用line()函数画几条线,游戏是否继续或结束的判定用方块的下边界作为判定

最后,我想要加上游戏得分的显示功能,不过我不知道怎样才能在屏幕上输出变量的值,所以作罢。如果想要再增加游戏难度还可以增加一个新的结构体,然后增加新的一条链表,在同一个循环里运行两条链表,最后用延时效果就可以实现了,但是VS崩溃了,本人才疏学浅,暂时无法解决。

完整代码:

#include <stdio.h>
#include<stdlib.h>
#include <graphics.h>
#include<conio.h>
struct black
{
	int state;//方块是否被消灭,1为是0为否
	int x;//方块位置
	struct black* next;
};
typedef struct black Black;
int main()
{
	Black* head, * p, * q;
	p = (Black*)malloc(sizeof(Black));
	p->state = 0;
	p->x = 185;
	head = p;
	initgraph(480, 720);//屏幕大小
	setfillcolor(WHITE);//方块填充色
	for (int i = 0; i <= 50; i++)
	{
		int a = rand() % 3;
		int xl;
		switch (a)
		{
		case 1:
			xl = 75;
			break;
		case 2:
			xl = 185;
			break;
		case 3:
			xl = 295;
			break;
		case 0:
			xl = 405;
			break;
		}
		q = (Black*)malloc(sizeof(Black));
		q->state = 0;
		q->x = xl;
		p->next = q;
		p = q;
	}
	for (Black* p = head; p != NULL; p = p->next)
	{
		double speed = 80;
		for (int y = 0; y <= 720; y += 10)
		{
			line(20, 0, 20, 720);//左边界
			line(460, 0, 460, 720);//右边界
			line(0, 680, 480, 680);//下边界
			line(130, 0, 130, 720);//从左边界开始数第一条竖线
			line(240, 0, 240, 720);//第二条竖线
			line(350, 0, 350, 720);//第三条竖线
			line(460, 0, 460, 720);//第四条竖线
			line(p->x + 15, y - 60, p->x + 15, y);//方块右边界
			line(p->x - 15, y - 60, p->x - 15, y);//方块左边界
			line(p->x - 15, y - 60, p->x + 15, y - 60);//方块上边界
			line(p->x - 15, y, p->x + 15, y);//方块下边界
			Sleep(speed);
			cleardevice();
			switch (p->x)
			{
			case 75:
				if (y > 660 && y < 720 && _kbhit())
				{
					int put = _getch();
					if (put == 72)
					{
						p->state = 1;
					}
				}
			case 185:
				if (y > 660 && y < 720 && _kbhit())
				{
					int put = _getch();
					if (put == 80)
					{
						p->state = 1;
					}
				}
			case 295:
				if (y > 660 && y < 720 && _kbhit())
				{
					int put = _getch();
					if (put == 75)
					{
						p->state = 1;
					}
				}
			case 405:
				if (y > 660 && y < 720 && _kbhit())
				{
					int put = _getch();
					if (put == 77)
					{
						p->state = 1;
					}
				}
			}
			if (y >= 720 && p->state == 0)
			{
				getchar();
				closegraph();
			}
		}
		if (speed <= 30)
		{
			speed -= 5;
		}
	}
	getchar();
	closegraph();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_54182919/article/details/120044096
今日推荐