通過之前的任務,我們已經能夠實現小飛機在屏幕上自由移動了,這次博客的任務是是的我們的小飛機看起來更有靈性——尾部噴氣特效的繪制。
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這次博文就說到這里吧。