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的值,从而实现在运动中改变运动的方向。

运行后效果如下

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

相关推荐
wb18926 分钟前
流编辑器sed
运维·笔记·ubuntu·云计算
sunny-ll1 小时前
【C++】详解vector二维数组的全部操作(超细图例解析!!!)
c语言·开发语言·c++·算法·面试
西装没钱买2 小时前
C语言多进程TCP服务器与客户端
服务器·c语言·tcp/ip·进程
嵌入式@秋刀鱼2 小时前
《第四章-筋骨淬炼》 C++修炼生涯笔记(基础篇)数组与函数
开发语言·数据结构·c++·笔记·算法·链表·visual studio code
CloudHu19892 小时前
UE5 免费且好用的插件收集(不定期更新)
游戏·ue5·免费插件
嵌入式@秋刀鱼2 小时前
《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
c语言·开发语言·数据结构·c++·笔记·算法·visual studio code
m0_678693333 小时前
深度学习笔记26-天气预测(Tensorflow)
笔记·深度学习·tensorflow
自由鬼3 小时前
企业架构框架深入解析:TOGAF、Zachman Framework、FEAF与Gartner EA Framework
程序人生·架构
whoarethenext3 小时前
使用 C/C++的OpenCV 裁剪 MP4 视频
c语言·c++·opencv
桂?3 小时前
使用离线依赖解决Android Studio编译报错(下载不了jar)——笔记
笔记·android studio·jar