用Pygame和Python做遊戲-從入門到精通(5)

pythontab發表於2012-12-20

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

這次開始是真正的遊戲程式設計,以前都是基礎的基礎啊。

電腦遊戲總是傾向於影像化的,儘量的要看得到聽得到(現在的技術基本還侷限於這兩個感官),遊戲開發者會花無數的力氣在影像上,提升影像效果是遊戲開發永恆的話題。這幾次主要講述遊戲中的視覺。

畫素的威力

湊近顯示器,你能看到影像是由一個一個點構成,這就是畫素。至於螢幕解析度的意義,也就不用多說了吧,一個1280×1024的顯示器,有著1310720個畫素,一般的32為RGB系統,每個畫素可以顯示16.7百萬種顏色(可以看我的另一篇一張白紙可以承載多少重的文章),我們可以寫一個小程式來顯示這麼多的顏色~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pygame
pygame.init()
 
screen = pygame.display.set_mode((640, 480))
 
all_colors = pygame.Surface((4096,4096), depth=24)
 
for r in xrange(256):
    print r+1, "out of 256"
    x = (r&15)*256
    y = (r>>4)*256
    for g in xrange(256):
        for b in xrange(256):
            all_colors.set_at((x+g, y+b), (r, g, b))
 
pygame.image.save(all_colors, "allcolors.bmp")

執行可能有些慢,你應該等生成bmp影像檔案,開啟看看效果吧(其實就是我剛剛提到的博文裡的圖片)。

色彩的威力

色彩是一個很有趣的話題,比如把藍色和黃色混合產生綠色,事實上你可以用紅黃藍混合出所有的顏色(光學三原色),電腦螢幕上的三原色是紅綠藍(RGB),要想更深刻的理解這個東西,你得學習一下(就看看李濤的PhotoShop講座吧,VeryCD上有下的,講的還是很清楚的)~

稍有點經驗的影像設計者應該看到RGB的數值就能想象出大概的顏色,我們來用一個Python指令碼加強這個認識。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python
import pygame
from pygame.locals import *
from sys import exit
 
pygame.init()
 
screen = pygame.display.set_mode((640, 480), 0, 32)
 
def create_scales(height):
    red_scale_surface = pygame.surface.Surface((640, height))
    green_scale_surface = pygame.surface.Surface((640, height))
    blue_scale_surface = pygame.surface.Surface((640, height))
    for x in range(640):
        c = int((x/640.)*255.)
        red = (c, 0, 0)
        green = (0, c, 0)
        blue = (0, 0, c)
        line_rect = Rect(x, 0, 1, height)
        pygame.draw.rect(red_scale_surface, red, line_rect)
        pygame.draw.rect(green_scale_surface, green, line_rect)
        pygame.draw.rect(blue_scale_surface, blue, line_rect)
    return red_scale_surface, green_scale_surface, blue_scale_surface
 
red_scale, green_scale, blue_scale = create_scales(80)
 
color = [127, 127, 127]
 
while True:
 
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
 
    screen.fill((0, 0, 0))
 
    screen.blit(red_scale, (0, 00))
    screen.blit(green_scale, (0, 80))
    screen.blit(blue_scale, (0, 160))
 
    x, y = pygame.mouse.get_pos()
 
    if pygame.mouse.get_pressed()[0]:
        for component in range(3):
            if y > component*80 and y < (component+1)*80:
                color[component] = int((x/639.)*255.)
        pygame.display.set_caption("PyGame Color Test - "+str(tuple(color)))
 
    for component in range(3):
        pos = ( int((color[component]/255.)*639), component*80+40 )
        pygame.draw.circle(screen, (255, 255, 255), pos, 20)
 
    pygame.draw.rect(screen, tuple(color), (0, 240, 640, 240))
 
    pygame.display.update()

這個程式稍稍有點難度了,而且用到了一些沒講到的知識(pygame.draw),我們以後會介紹,現在無所謂。在這個例子裡,你可以用滑鼠移動三個白點,代表了三原色的量,下面就是不同混合得到的結果,在標題上你可以看到RGB三個數值。

當我們有了一個顏色,比如說一顆流星劃過天際,那麼那個時候它是個“火球般的橘黃色”,不過一旦它著地了,它就會滅掉,慢慢變暗,如何能找到比這個“火球般的橘黃色”更暗的顏色?

顏色的縮放

“縮放顏色”並不是一種合適的說法,它的準確意義就是上面所說的把顏色變亮或者變暗。一般來說,把顏色的RGB每一個數值乘以一個小於1的正小數,顏色看起來就會變暗了(記住RGB都是整數所以可能需要取整一下)。我們很容易可以寫一個縮放顏色的函式出來,我就不贅述了。

很自然的可以想到,如果乘以一個大於1的數,顏色就會變亮,不過同樣要記住每個數值最多255,所以一旦超過,你得把它歸為255!使用Python的內建函式min,你可以方便的做到這事情,也不多說了。如果你乘的數字偏大,顏色很容易就為變成純白色,就失去了原來的色調。而且RGB也不可能是負數,所以謹慎選擇你的縮放係數!

顏色的混合

很多時候我們還需要混合顏色,比如一個殭屍在路過一個火山熔岩坑的時候,它會由綠色變成橙紅色,再變為正常的綠色,這個過程必須表現的很平滑,這時候我們就需要混合顏色。

我們用一種叫做“線性插值(linear interpolation)”的方法來做這件事情。為了找到兩種顏色的中間色,我們將這第二種顏色與第一種顏色的差乘以一個0~1之間的小數,然後再加上第一種顏色就行了。如果這個數為0,結果就完全是第一種顏色;是1,結果就只剩下第二種顏色;中間的小數則會皆有兩者的特色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env python
 
import pygame
from pygame.locals import *
from sys import exit
 
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
 
color1 = (221, 99, 20)
color2 = (96, 130, 51)
factor = 0.
 
def blend_color(color1, color2, blend_factor):
    r1, g1, b1 = color1
    r2, g2, b2 = color2
    r = r1 + (r2 - r1) * blend_factor
    g = g1 + (g2 - g1) * blend_factor
    b = b1 + (b2 - b1) * blend_factor
    return int(r), int(g), int(b)
 
while True:
 
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
 
    screen.fill((255,255,255))
 
    tri = [ (0, 120), (639, 100), (639, 140) ]
    pygame.draw.polygon(screen, (0, 255, 0), tri)
    pygame.draw.circle(screen, (0, 0, 0), (int(factor * 639.0), 120), 10)
 
    x, y = pygame.mouse.get_pos()
    if pygame.mouse.get_pressed()[0]:
        factor = x / 639.0
        pygame.display.set_caption("Pygame Color Blend Test - %.3f" % factor)
 
    color = blend_color(color1, color2 , factor)
    pygame.draw.rect(screen, color, (0, 240, 640, 240))
 
    pygame.display.update()

在這裡例子裡,移動小球你能看到下方的顏色在“火球橙”和“殭屍綠”之間漸變,更改程式碼裡的color1和color2,你能看到任意兩種顏色漸變的過程!

今天主要說明了畫素和色彩,很簡單,但確實是要點,多寫寫程式試試,好好理解理解吧!


相關文章