Pygmae都能很好的支持,具體支持的格式如下:
JPEG(Join Photograhpic Exper Group),極為常用,一般后綴名為.jpg或者.jpeg。數碼相機、網上的圖片基本都是這種格式。這是一種有損壓縮方式,盡管對圖片質量有些損壞,但對于減小文件尺寸非常棒。優點很多只是不支持透明。PNG(Portable Network Graphics)將會大行其道的一種格式,支持透明,無損壓縮。對于網頁設計,軟件界面設計等等都是非常棒的選擇!GIF 網上使用的很多,支持透明和動畫,只是只能有256種顏色,軟件和游戲中使用很少BMP Windows上的標準圖像格式,無壓縮,質量很高但尺寸很大,一般不使用PCXTGATIFLBM, PBMXPM對于Pygame而已,加載圖片就是pygame.image.load,給它一個文件名然后就還給你一個surface對象。盡管讀入的圖像格式各不相同,surface對象隱藏了這些不同。你可以對一個Surface對象進行涂畫、變形、復制等各種操作。事實上,屏幕也只是一個surface,pygame.display.set_mode就返回了一個屏幕surface對象。
一種方法就是剛剛說的pygame.image.load,這個surface有著和圖像相同的尺寸和顏色;另外一種方法是指定尺寸創建一個空的surface,下面的語句創建一個256×256像素的surface:
bland_surface = pygame.Surface((256, 256))如果不指定尺寸,那么就創建一個和屏幕一樣大小的。
你還有兩個參數可選,第一個是flags:
HWSURFACE – 類似于前面講的,更快!不過最好不設定,Pygmae可以自己優化。SRCALPHA – 有Alpha通道的surface,如果你需要透明,就要這個選項。這個選項的使用需要第二個參數為32~第二個參數是depth,和pygame.display.set_mode中的一樣,你可以不設定,Pygame會自動設的和display一致。不過如果你使用了SRCALPHA,還是設為32吧:
bland_alpha_surface = pygame.Surface((256, 256), flags=SRCALPHA, depth=32)轉換Surfaces
通常你不用在意surface里的具體內容,不過也許需要把這些surface轉換一下以獲得更高的性能,還記得一開始的程序中的兩句話嗎:
background = pygame.image.load(background_image_filename).convert()mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()第一句是普通的轉換,相同于display;第二句是帶alpha通道的轉換。如果你給convert或者conver_alpha一個surface對象作為參數,那么這個會被作為目標來轉換。
矩形對象(Rectangle Objects)
一般來說在制定一個區域的時候,矩形是必須的,比如在屏幕的一部分畫東西。在pygame中矩形對象極為常用,它的指定方法可以用一個四元素的元組,或者兩個二元素的元組,前兩個數為左上坐標,后兩位為右下坐標。
Pygame中有一個Rect類,用來存儲和處理矩形對象(包含在pygame.locals中,所以如果你寫了from pygame.locals import *就可以直接用這個對象了),比如:
my_rect1 = (100, 100, 200, 150)my_rect2 = ((100, 100), (200, 150))#上兩種為基礎方法,表示的矩形也是一樣的my_rect3 = Rect(100, 100, 200, 150)my_rect4 = Rect((100, 100), (200, 150))剪裁(Clipping)
通常游戲的時候你只需要繪制屏幕的一部分。比如魔獸上面是菜單,下面是操作面板,中間的小兵和英雄打的不可開交時候,上下的部分也是保持相對不動的。為了實現這一點,surface就有了一種叫裁剪區域(clipping area)的東西,也是一個矩形,定義了哪部分會被繪制,也就是說一旦定義了這個區域,那么只有這個區域內的像素會被修改,其他的位置保持不變,默認情況下,這個區域是所有地方。我們可以使用set_clip來設定,使用get_clip來獲得這個區域。
下面幾句話演示了如何使用這個技術來繪制不同的區域:
screen.set_clip(0, 400, 200, 600)draw_map()#在左下角畫地圖screen.set_clip(0, 0, 800, 60)draw_panel()#在上方畫菜單面板子表面(Subsurfaces)
Subsurface就是在一個Surface中再提取一個Surface,記住當你往Subsurface上畫東西的時候,同時也向父表面上操作。這可以用來繪制圖形文字,盡管pygame.font可以用來寫很不錯的字,但只是單色,游戲可能需要更豐富的表現,這時候你可以把每個字母(中文的話有些吃力了)各自做成一個圖片,不過更好的方法是在一張圖片上畫滿所有的字母。把整張圖讀入,然后再用Subsurface把字母一個一個“摳”出來,就像下面這樣:
my_font_image = Pygame.load("font.png")letters = []letters["a"] = my_font_image.subsurface((0,0), (80,80))letters["b"] = my_font_image.subsurface((80,0), (80,80))填充Surface
填充有時候可以作為一種清屏的操作,把整個surface填上一種顏色:
screen.fill((0, 0, 0))同樣可以提供一個矩形來制定填充哪個部分(這也可以作為一種畫矩形的方法)。
設置Surface的像素
我們能對Surface做的最基本的操作就是設置一個像素的色彩了,雖然我們基本不會這么做,但還是要了解。set_at方法可以做到這一點,它的參數是坐標和顏色,下面的小腳本會隨機的在屏幕上畫點:
#coding=utf-8'''Created on 2017年3月4日@author: zxt'''import pygamefrom pygame.locals import QUITfrom sys import exitfrom random import randintimport timepygame.init()screen = pygame.display.set_mode((640, 480), 0, 32)while True: for event in pygame.event.get(): if event.type == QUIT: pygame.display.quit() exit() screen.fill((255, 255, 255)) screen.lock() for i in xrange(100): rand_col = (randint(0, 255), randint(0, 255), randint(0, 255)) rand_pos = (randint(0, 639), randint(0, 479)) pygame.draw.rect(screen, rand_col, (rand_pos, (3, 3))) #screen.set_at(rand_pos, rand_col) time.sleep(0.01) screen.unlock() pygame.display.update()獲得Surface上的像素
set_at的兄弟get_at可以幫我們做這件事,它接受一個坐標返回指定坐標點上的顏色。不過記住get_at在對hardware surface操作的時候很慢,而全屏的時候總是hardware的,所以慎用這個方法!
鎖定Surface
當Pygame往surface上畫東西的時候,首先會把surface鎖住,以保證不會有其它的進程來干擾,畫完之后再解鎖。鎖和解鎖時自動發生的,所以有時候可能不那么有效率,比如上面的例子,每次畫100個點,那么就得鎖解鎖100次,現在我們把兩句注釋去掉,再執行看看是不是更快了(好吧,其實我沒感覺出來,因為現在的機器性能都不錯,這么點的差異還不太感覺的出來。不過請相信我~復雜的情況下會影響效率的)?
當你手動加鎖的時候,一定不要忘記解鎖,否則pygame有可能會失去響應。雖然上面的例子可能沒問題,但是隱含的bug是我們一定要避免的事情。
Blitting
blit的的中文翻譯給人摸不著頭腦的感覺,可以譯為位塊傳送(bit block transfer),其意義是將一個平面的一部分或全部圖象整塊從這個平面復制到另一個平面,下面還是直接使用英文。
blit是對表面做的最多的操作,我們在前面的程序中已經多次用到,不多說了;blit的還有一種用法,往往用在對動畫的表現上,比如下例通過對frame_no的值的改變,我們可以把不同的幀(同一副圖的不同位置)畫到屏幕上:
screen.blit(ogre, (300, 200), (100 * frame_no, 0, 100, 100))
新聞熱點
疑難解答