前言:
BOSS系列的日志,建議在看了前面的入門知識後再看,沒有一定的基礎,這些看起來會很累。精靈組的層管理,确實太強大了。
pygame提供了精靈sprite這個類來管理遊戲的各個元素。例如子彈、飛機、爆炸效果(一連串動态圖檔)……等都可以是一個精靈,所有的精靈預設都在同一個層 0 層裡。文檔裡說明:You can set the default layer through kwargs using 'default_layer' and an integer for the layer. The default layer is 0.
為什麼要用層這個概念來編寫呢?
1.預設方式下,pygame繪制的順序是精靈添加的順序,例如先加載背景,再加載飛機,再加載子彈,那麼繪制的順序就是背景、飛機、子彈。如果先加載飛機、子彈,再加載背景,那麼你将隻能看到背景圖。
很多軟體裡都有層這個概念,例如photoshop。pygame裡的層号用數字表示,1、2、3、4……層,也可以是負數。層号越高,優先級越高,例如把背景層設定為 -1,飛機為 1,子彈為 2,那麼不管你什麼繪圖順序,子彈擁有在場景的頂層,不會被背景遮擋。
2.單個的精靈隻能存在單張image,當向用動态的飛機,動态的子彈時,隻能編寫不是精靈的單獨的類或者函數實作。維護起來很麻煩。而用層來管理就很輕松了。
3.既然pygame提供了層管理的這個概念,何不好好用用。
4.cocos2d 的python版裡,也專門用了層來管理,好東西值得借鑒。
下面開始建構遊戲的基本架構。
用類來寫,可讀性、維護性比單個程式好很多,是以大緻思路如下:
setting.py :遊戲設定的基本檔案,螢幕的寬度,高度,尺寸,要加載基本子產品,要用到的簡化定義,簡化的層的定義等
main.py :遊戲的架構,包括初始,繪制,更新,碰撞檢查,事件檢查
bullet.py : 基本的子彈的實作,包括飛行位置的計算,起點位置的設定,飛機的速度和角度,還是子彈圖檔的設定
animation.py:動态圖像的實作類
lifebar.py: 動态生命條的顯示
bossbullet: BOSS子彈的實作,BOSS的子彈當然與衆不同,動态子彈(用animation實作),不同的圖像
boss.py:BOSS的實作,動态的圖像,多變的飛行方式,多變的子彈動态圖像,多變的發射方式,自帶生命條。
先來搭架構:
from setting import *
class MainScene(object):
#初始化
def __init__(self):
pygame.mixer.pre_init()
pygame.init()
pygame.mixer.init()
pygame.font.init()
# pygame.mouse.set_visible(False)
self.scene = pygame.display.set_mode((SCENEWIDTH, SCENEHEIGHT), 1, 32)
pygame.display.set_caption("自學飛機大戰--精靈版")
#繪制各個元素
def draw(self):
allgroup.draw(self.scene)
def update(self):
allgroup.update()
def collideEvent(self):
pass
#處理鍵盤和滑鼠相應
def handleEvent(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pass
elif event.key == pygame.K_p: # print layer information in console
print("=========================")
print("-----Spritelist---------")
print("------------------------")
print("toplayer:", allgroup.get_top_layer())
print("bottomlayer:", allgroup.get_bottom_layer())
print("layers;", allgroup.layers())
print("=========================")
def runScene(self):
pygame.mixer.music.load('music/bgm.mp3')
pygame.mixer.music.play(-1)
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
self.draw()
self.update()
self.collideEvent()
self.handleEvent()
pygame.display.flip()
if __name__ == "__main__":
play = MainScene()
play.runScene()
else:
print("i was imported by", __name__)
setting.py的代碼如下:
import pygame
from sys import exit
import random
vect = pygame.math.Vector2
FPS = 60
#define sprite groups. Do this before creating sprites
textgroup = pygame.sprite.Group()
backgroundgroup = pygame.sprite.Group()
menugroup =pygame.sprite.Group()
bossgroup = pygame.sprite.Group()
bossbulletgroup = pygame.sprite.LayeredUpdates()
bulletgroup = pygame.sprite.Group()
# only the allgroup draws the sprite, so i use LayeredUpdates() instead Group()
# more sophisticated, can draw sprites in layers
allgroup = pygame.sprite.LayeredUpdates()
SCENEWIDTH = 520
SCENEHEIGHT = 850
SCENERECT = pygame.sprite.Rect(0,0,SCENEWIDTH,SCENEHEIGHT)
用allgroup 來管理所有的精靈。用bossbulletgroup 來管理BOSS的子彈。
運作一下,出現一個遊戲界面,因為還沒加載背景圖,目前螢幕黑色。