ege图形库-- 抓取屏幕,贴图,动画基础框架(三)

贴图
//使用IMAGE——抓图,绘画到IMAGE,IMAGE到屏幕
#include 

//IMAGE对象相当于一个绘图板,而同时也可以作为图片画到其它IMAGE上
//它是一个非常灵活的对象,复杂的绘图都要借助IMAGE,以便更好地保存和输出图像

int main()
{
	//声明一个img图片对象
	PIMAGE img;

	initgraph(640, 480);

	//先随便画一些东西
	setcolor(EGERGB(0xFF, 0xFF, 0x0));
	setfillcolor(EGERGB(0xFF, 0x0, 0x80));
	fillellipse(50, 50, 50, 50);

	//用newimage在initgraph后创建这个对象。但记得要在不使用的时候delimage
	img = newimage();

	//从屏幕上截取(0, 0) - (80, 60)这部分作为img,这个img大小为80*60
	//img的尺寸会重设,大小由第三第四个参数决定
	//注意,(0,0)这点会被包含在img里,但(80, 60)不包含
	getimage(img, 0, 0, 80, 60);

	//对img设置填充色为绿色
	setfillcolor(EGERGB(0x0, 0x70, 0x0), img);

	//对img画实心矩形
	bar(40, 20, 70, 50, img);


			//把img整个,画在指定的坐标上,左上角对齐这个坐标
			putimage( 80,  60, img);
	
	getch();

	delimage(img);

	closegraph();
	return 0;
}

通过实验知,getimage截图了自身窗口上的制定区域,放在后台,bar函数也是在后台绘制,同时如果注销掉putimage,就不会有图片显示在屏幕上。
ege图形库-- 抓取屏幕,贴图,动画基础框架(三)_第1张图片
bar函数绘图时,坐标是相对image来定位,比如把改成bar(0, 0, 70, 50, img),则图像变为:
ege图形库-- 抓取屏幕,贴图,动画基础框架(三)_第2张图片
个人感觉ege图形库在这方面做的不好,一个函数实在有太多参数了,使用了c++的多态,函数名相同,根据参数的个数或类型不同来确定具体调用哪一个。
ege图形库-- 抓取屏幕,贴图,动画基础框架(三)_第3张图片
ege图形库-- 抓取屏幕,贴图,动画基础框架(三)_第4张图片
少则4,5个参数,多则8,9个参数,造成了使用起来很不方便,表面上是把函数的数量给减少了,还不如每一个函数完成一个具体而清晰的功能。

动画基础
//基础动画二:简单平移动画
#include 

void mainloop()
{
	// 动画控制变量,控制横坐标,初始值为0
	int x = 0;

	setcolor(EGERGB(0, 0xFF, 0));
	setfillcolor(EGERGB(0, 0, 0xFF));

	for ( ; is_run(); delay_fps(60) )
	{
		// todo: 逻辑更新
		//计算新坐标,右移一个像素,如果等于440则重新移回x=0,达到动画循环
		x = ( x + 1 ) % 440;

		// todo: 图形更新
		//清屏,重新在新的位置绘图图像
		cleardevice();
		//以x为圆的左边界绘画,为什么是左边界?因为圆心坐标是 (x + 半径) 了
		fillellipse(x + 100, 200, 100, 100);
	}
}

int main(void)
{
	//INIT_ANIMATION相当于INIT_NOFORCEEXIT|INIT_DEFAULT|INIT_RENDERMANUAL
	//下面就不需要再多一步setrendermode
	setinitmode(INIT_ANIMATION);
	// 图形初始化,窗口尺寸640x480
	initgraph(640, 480);
	// 随机数初始化,如果需要使用随机数的话
	randomize();
	// 程序主循环
	mainloop();
	// 关闭绘图设备
	closegraph();
	return 0;
}

学习几个知识:

  1. 整个框架在于初始化,主循环,关闭。

  2. 主循环里又分成两个部分,逻辑更新,图形更新。

  3. is_run 检测程序是否收到关闭消息,收到的话会返回false,即应该退出程序;delay_fps 控制帧率,60表示“平均延时”为1000/60毫秒。

  4. 为什么使用60?因为60是显示器的默认刷新率,99.9%的显示器都是这个设置

  5. setinitmode(INIT_ANIMATION)把绘图更新模式设置为手动,仅调用delay_fps/delay_ms等函数时才刷新,避免闪烁
    区别是在RENDER_AUTO模式下,任何绘图操作进行时都可能刷新,甚至刚cleardevice就显示, 导致屏幕上有时仅显示一个背景而没有其它内容导致闪烁。

为什么会闪烁?并不是图像太复杂,绘图太慢造成的,而是因为常规绘图之前,要先清屏(用背景色覆盖),如果不清屏,那无论怎么绘制都不会闪烁,只不过这时候图像会变成一团乱,不停在叠加新图像。

闪烁的本质是反差,通常背景色与需要绘制的图像颜色相差很大,在一清屏一绘制的快速过程中,人眼就会觉得闪烁不适。如果清屏1秒,绘制1秒,那么10秒内会闪烁5次;如果图像足够复杂,清屏1秒,绘制9秒,那么10秒内只闪烁1次,反而大大降低了人眼闪烁感。

现在不知道ege用的什么方式来清除闪烁,按照官方介绍调用delay_fps/delay_ms等函数时才刷新,看代码应该是降低了刷新频率,每一次清屏和绘制的时间间隔被尽量拉长,每隔16.66毫秒才刷新一次。

  1. 对x边界的判断,没有使用常见的if语句,而是用的取余%,取余本身带有“每隔……”的含义,本意就是一种循环。这样比起if语句的来说,提高了代码效率,前者每秒60帧需要做60次逻辑判断。

你可能感兴趣的:(图形库系统)