通过之前的任务,我们已经能够实现小飞机在屏幕上自由移动了,这次博客的任务是是的我们的小飞机看起来更有灵性——尾部喷气特效的绘制。
1、帧率
说道帧率,玩游戏的人可能并不陌生。如果你是一个lol的玩家,那你肯定最关心两件事,一是帧率(FPS),二是延迟。延迟取决于网络性能,而帧率则取决于电脑的硬件配置,自然是帧率越高游戏画面就越流畅。帧率,简单理解就是游戏在一秒钟进行多少次画面刷新。Pygame支持的帧率大约是从30到120,为了避免游戏程序因为电脑性能的差异出现太大差别,我们在此为程序指定一个时钟的帧率(比如说三十)。
Pygame通过pygame.time.Clock()函数来设置帧率,具体来说由下面两条语句完成:
~~~
clock = pygame.time.Clock() # 设置帧率
clock.tick(60) # 设置帧数为60
~~~
意义很明确,设置游戏的帧率为60,需要强调的一点是第二句话一定要放在while循环内部,否则将不起作用。为了体验帧率的实际意义,大家可以尝试把帧率设置为一个低值(比如设为1),来体验一下帧率的实际作用。
2、图像加载
对飞机添加尾部“突突突”喷气特效的手段其实很简单,就是在两张飞机图片之间来回切换显示。在下载得到的图片音效资源中,留心观察会发现其中有两张我方飞机的图片:“hero1”和“hero1”,这两张图片的不同之处就在为飞机尾部的喷气形状方面,试想如果在程序运行期间将这两张图片不停的切换显示,应该就能得到想要的那种尾部动态效果了。
首先,在我方飞机模块中加载这两张图片(之前已经加载过第一张了):
~~~
self.image1 = pygame.image.load("image/hero1.png") # 加载飞机图片1
self.image2 = pygame.image.load("image/hero2.png") # 加载飞机图片2
~~~
注意这里由于两张图片实际上是代表一个对象的,因此两张图片将来在显示时也共享同一位置,因此下面的self.rect(我方飞机位置)等属性不用更改。
3、图片切换
图片加载完成之后开始在主程序主进行切换绘制,试想如何让程序在前后两帧选择绘制不同的图像呢?通用的解决方案就是设置一个控制图片切换的布尔型标志位(switch_image),在每次程序运行中都将标志位进行取反,从而产生程序前后运行的差异。我们在main()函数中声明这个标志位并赋值:
~~~
switch_image = False # 控制飞机图片切换的标志位(用以模拟发动机喷火效果)
~~~
接下来在程序循环过程中,每次循环都将该标志位进行取反操作:
~~~
switch_image = not switch_image
~~~
接下来需要修改我方飞机的绘制操作,之前我们直接在每次循环中都使用blit()函数来绘制相同的飞机图片,在此我们将其修改为由标志位来控制的绘图操作:
~~~
if switch_image:
screen.blit(me.image1, me.rect) # 绘制我方飞机的两种不同的形式
else:
screen.blit(me.image2, me.rect)
~~~
OK,此时再运行程序应该就能看到我方飞机的喷气特效了。不过细心的朋友应该会觉得这个喷气效果抖动得有点太快了,每一帧都要切换一次,有点过于夸张,为了解决这个问题,我们设置一个延时计数器调节图片切换的速率(不在完全依赖帧数)
4、延时
延时是程序运行中一个很重要的属性,不仅仅在此处我们要通过延时来控制图片切换速度,到后面还要通过延时来控制子弹发射的速度、控制飞机损毁图片的打印速度等等。延时的实现可以说是一个最简单的计时器(与事件触发系统中的定时器time.set_timer()不同)。
首先我们在main函数中定义延时计数器delay并初始化,一般将其初始化为帧数,从而能够方便的与当前帧率联系在一起,此处初始化为60:
~~~
delay = 60 # 延时参数
~~~
然后在while()循环中,每循环一次将延时参数减一,减到零时再将其置为60:
~~~
if delay == 0:
delay = 60
delay -= 1
~~~
注意此时的delay和图片帧数已经相互关联了,即每播放一帧,delay就减一。
5、加延时的图片切换
设置完延时参数后,比如说我们希望每3帧切换一次图片,这时就需要修改switch_image的变换频率,使其在取反之前先咨询一下delay参数,决定本次循环需不需要进行图片切换:
~~~
if not delay % 3:
switch_image = not switch_image
~~~
运行程序,我们会发现图片尾气的切换变慢了,喷气效果比之前要好了一些,当然我们设置这个delay参数可不是仅仅为了让飞机的喷气好看点,后面还有很多重要的用途,ok这次博文就说到这里吧。