EasyX图形库note4,动画及键盘交互

大家好,这里是Dark Flame Master,专栏从这篇开始就会变得很有意思,我们可以利用今天所学的只是实现很多功能,同样为之后的更加好玩的内容打下基础,从这届开始将会利用所学的知识制作一些小游戏,废话不多说,开始今天的内容。

专栏:EasyX图形化编程

文章目录

动画

在之前的笔记中,我们所绘制的图形都是静态的,现在我们通过代码让图形动起来。

就像小时候我们看的葫芦娃小金刚一样,动画是由一帧一帧的图片逐个快速播放,利用人的视觉停留,就可以达到动画的效果。一般来说电视每秒播放24帧画面,游戏更高,在打游戏时游戏帧率越高,游戏画面也就越流畅。

用前边的知识绘制一个半径100圆形,窗体大小800*600,圆心初始坐标为(-400,0)。颜色可以自己选择。

  • 要实现像动画一样逐帧播放,我们可以不断改变圆心的x坐标,更改后清除上一次画的圆形,然后重新画出位置变化的圆形,同时要使用Sleep()函数暂停程序一段时间。

代码如下

cpp 复制代码
int main()
{
	initgraph(800,600);
	setbkcolor(RGB(150, 205, 205));
	cleardevice();
	setorigin(400, 300);
	setaspectratio(1, -1);
	setfillcolor(RGB(106, 90, 205));
	int dx = 15;
	for (int x = -400; x <= 400; x += dx)
	{
		solidcircle(x, 0, 100);
		Sleep(200);
		cleardevice();
		
	}
	getchar();
	return 0;
}

画出一个圆形后,Sleep200毫秒,清空屏幕后画出下一个,再Sleep200毫秒。直到运动到最右端循环结束,getchar阻塞进程。

运行后效果如下

因为休眠函数在每次循环时休眠200毫秒,所以在一秒内可以播放五帧画面,每次移动的距离为15像素,所以圆形的移动速度为每秒75像素。
如果想让画面更加流畅,然而圆形的移动速度几乎不变,就要加大帧率,减小每次移动的像素。

  • 将休眠时间改为50毫秒,将每次移动的像素即dx设置为5。
    运行后效果如图

    对比上边流畅很多。

键盘交互

在动画的基础上,加入键盘交互功能,按下w键,圆形向上移动,按下a键,圆形向左移动,按下d键,圆形向右移动,按下s键,圆形向下移动。

首先如何从键盘上读取信息?

我们会想到使用getchar函数,有了思路就开始编写代码实现按下w键,圆形向上移动50像素。

cpp 复制代码
int main()
{
	initgraph(800,600);
	setbkcolor(RGB(150, 205, 205));
	cleardevice();
	setorigin(400, 300);
	setaspectratio(1, -1);
	int x = 0;
	int y = 0;
	setfillcolor(GREEN);
	solidcircle(x, y, 50);//画出圆形
	while (1)
	{
		char c = getchar();
		if (c == 'w')
		{
			y += 50;
		}
		cleardevice();//清除窗体
		solidcircle(x, y, 50);//画出圆形
	}
	
	getchar();
	return 0;
}

编写完成后运行代码,发现按下'w'键没有任何反应,按下回车后才会向上移动,而且点击n次w键,会直接向上移动n*50像素。这是为什么呢?

  • 让我们深入了解一下getchar函数

getchar函数从输入缓存区中读取一个字符,如果读取成功,就返回读取到的字符,如果缓存区中没有数据,函数将会阻塞进程,直到缓存区里有数据。
在控制台上输入数据,但数据还没有进入输入缓存区,需要按下回车键,才会将输入的全部数据放在缓存区,然后getchar函数取出第一个字符并返回这个字符。若在循环中,getchar会依次取出这些数据,直到没有数据为止。

我们想让动画和键盘交互组合,但getchar函数明显不满足需求,想要实现实时型交互,按下键盘后程序就作出反应,而不是按下回车后才运行,运行之后又堵塞。


这里就要提到getch函数


无需回车,只需要按下键盘就可以将数据送进输入缓存区。

别忘记包含头文件<conio.h>

写一串代码探究其特性

注:在使用getch函数时,要写成_getch的形式。

代码如下

cpp 复制代码
#include <conio.h>
int main()
{
	while (1)
	{
		char c;
		c = _getch();
		putchar(c - 32);
	}
	return 0;
}

运行后输入小写a就直接在控制台打印出A,输入b就直接打印B。

解决了回车问题,我们想在圆形移动的时候就可以控制圆移动的方向,而getch仍然具有阻塞程序运行的作用。这种用户输入之后场景才发生变化的适合推箱子游戏,2048等,然而对于就算没有输入整个场景仍然会变化的场景则不适用。

介绍一下函数kbhit

int kbhit(void);

kbhit函数会检查getch函数的输入缓存区中是否有数据,若没有数据就返回0,如果有数据就返回非0的数。

这个函数不会阻塞程序的运行,可以借此判断是否用户按下了键盘,然后再做出反应,这样就不会阻塞程序的运行。kbhit函数也要写作_kbhit。


对前边的圆形动画做出改变,加上键盘交互功能。

代码如下

cpp 复制代码
int main()
{
	initgraph(800, 600);
	setbkcolor(RGB(150, 205, 205));
	cleardevice();
	setorigin(400, 300);
	setaspectratio(1, -1);
	setfillcolor(RGB(106, 90, 205));
	int x = -400, y = 0;
	int dx = 5 , dy=0;
	while (1)
	{
		cleardevice();
		solidcircle(x, y, 50);
		Sleep(40);

		if (_kbhit() != 0)
		{
			char c = _getch();
			switch (c)
			{
			case'w':
				dx = 0;
				dy = 5;
				break;
			case'a':
				dx = -5;
				dy = 0;
				break;
			case's':
				dx = 0;
				dy = -5;
				break;
			case'd':
				dx = 5;
				dy = 0;
				break;
			}
			
		}
		x =x+ dx;
		y =y+ dy;
	}
	getchar();
	return 0;
}

起始位置在最左边,刚开始设置dx为5,即圆形向右移动,只有我们按下键盘才会进入switch语句,更改dx与dy的值,从而实现在运动中改变运动的方向。

运行后效果如下

接下来会用今天所学的知识来实现一个简单的弹球小游戏。希望大家有所收获。

相关推荐
1024小神2 分钟前
tauri项目在windows上的c盘没有权限写入文件
c语言·开发语言·windows
KoiHeng2 小时前
操作系统简要知识
linux·笔记
巴伦是只猫3 小时前
【机器学习笔记Ⅰ】11 多项式回归
笔记·机器学习·回归
DKPT7 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
巴伦是只猫9 小时前
【机器学习笔记Ⅰ】13 正则化代价函数
人工智能·笔记·机器学习
学不动CV了9 小时前
ARM单片机启动流程(二)(详细解析)
c语言·arm开发·stm32·单片机·51单片机
猫猫的小茶馆11 小时前
【STM32】通用定时器基本原理
c语言·stm32·单片机·嵌入式硬件·mcu·51单片机
Luna-player11 小时前
黑布淡入淡出效果
经验分享·游戏
pumpkin8451412 小时前
Rust 调用 C 函数的 FFI
c语言·算法·rust
2401_8582861113 小时前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序