用Python和Pygame寫遊戲-從入門到精通(Sprite篇)

發表於2015-12-24

這又是Pygame教程系列的一個——OVA篇,類似於py2exe篇一樣,額外寫的,也許不是pygame遊戲開發必須的東西,但是知道了絕對大有裨益。因此友情大放送~

看pygame模組介紹的時候,細心的人會發現有一個pygame.sprite模組,而在講動畫的時候,雖然引入了精靈這個概念,卻沒有使用這個模組。在官方文件上也說了,這個模組是輕量級的,在遊戲開發中也未必要使用。講解動畫的時候為了避免太多新東西,直接把一個surface畫來畫去,難道沒有人覺得不和諧麼:)我們這次試著使用Sprite把動畫變的更簡單一些(不過這裡沒有使用GameObjects,兩者結合更健康~)。

“sprite”,中文翻譯“精靈”,在遊戲動畫一般是指一個獨立運動的畫面元素,在pygame中,就可以是一個帶有影象(Surface)和大小位置(Rect)的物件。 精靈特別適合用在OO語言中,比如Python。

pygame.sprite.Sprite是pygame精靈的基類,一般來說,你總是需要寫一個自己的精靈類繼承一下它然後加入自己的程式碼。舉個例子:

 

那一大堆的字串,相信懂Python的人會明白的,不明白的請去查閱一下base64編碼和Python對應的StringIO、base64庫。我這裡使用這種方法而不是直接讀取檔案,只是想告訴大家pygame.image.load方法不僅僅可以讀取檔案,也可以讀取檔案物件。是不是感覺一下子思路開闊了?Python那麼多方便的檔案物件,以後遊戲的資原始檔就可以不用一一獨立放出來了,使用zipfile,我們很容易就可以把資原始檔打包起來,這樣看起來我們的遊戲可就專業多了~這是後話,以後有機會再講。

而本例沒有直接畫一個圓,而是使用用了顏色混合的方法,這樣可以畫出有立體感的球體,效果如下圖。而上面一大堆的字串,其實就是那個球體的影象檔案編碼以後的東西。這個和本教程沒啥大聯絡,請自行學習光與色的知識……

但是但是,看了上面的程式碼大家一定會有意見了,這樣感覺比直接用Surface寫的程式碼還多啊!一點好處都沒有的樣子。確實會有這樣的錯覺,但是一個球看不出好處來,多個球呢?我們就可以這麼寫了:

我就不給出完整程式碼和效果圖了,請大家自己試驗。

不過光這樣還不足以體現sprite的好處,sprite最大的優勢在於動畫,這裡就需要用一下update方法,舉一個例子,把第一個程式,從33行開始換成下面的程式碼:

我們可以看到小球歡快的運動起來,碰到邊界就會彈回來,這才是sprite類的真正用處。每一個Sprite類都會有各自的速度屬性,每次呼叫update都會各自更新自己的位置,主迴圈只需要update+blit就可以了,至於各個小球到底在一個怎樣的狀態,完全可以不在意。不過精靈的魅力還是不僅在此,上面的程式碼中我們把每個精靈加入一個列表,然後分別呼叫每個精靈的update方法,太麻煩了!使用pygame.sprite.Group類吧,建立它的一個例項balls,然後用add方法把精靈加入,然後只需要呼叫balls.update(args..)就可以了,連迴圈的不用寫。同樣的使用balls.draw()方法,你可以讓pygame只重繪有變化的部分。請嘗試使用(記住還有一個balls.clear()方法,實際寫一下就知道這個方法用來幹嘛了)。

儘管我們已經說了很多,也著實領略到了精靈的好處,但故事還沒有結束,pygame.sprite有著層與碰撞的概念。層的引入是因為Group預設是沒有次序的,所以哪個精靈覆蓋哪個精靈完全就不知道了,解決方法嘛,使用多個Group、使用OrderedUpdates,或者使用LayeredUpdates,至於具體使用方法,相信如果您需要用到的時候,已經到相當的高度了,隨便看看文件就明白了,我就不多說了;而碰撞,又是一個無底洞啊,下次有機會再講吧~

相關文章