用python寫遊戲 - 從入門到精通16

pythontab發表於2013-01-30

所謂3D,說到底就是利用透視原理,在2D的畫面上創造出有縱深錯覺(說白了也就是近大遠小)的畫面而已,畢竟,螢幕是平的,怎麼可能真的畫出距離呢?換句話說,計算機3D的本質還是2D,只不過額外多了很多東西。


在純pygame中,我們畫3D畫面就是透過計算在2D影像上畫一些大小不一的東西:)

距離的魔法

我們看現實中的東西,和我們看畫面上的東西,最大差別在於能感受現實物體的距離。而距離的產生,則是因為我們雙眼看到的東西是不同的,兩眼交替閉合,你會發現眼前的東西左右移動。一隻眼睛則很難正確的判斷距離,雖然比上眼睛還是能感覺到遠近,但更精細一點,比如很難把線穿過針眼。


我們在3D畫面上繪圖的時候,就要遵循這個規律,看看下面的程式碼。

import pygame
from pygame.locals import *
from random import randint
   
class Star(object):
   
    def __init__(self, x, y, speed):
   
        self.x = x
        self.y = y
        self.speed = speed
   
def run():
   
    pygame.init()
    screen = pygame.display.set_mode((640, 480)) #, FULLSCREEN)
   
    stars = []
   
    # 在第一幀,畫上一些星星
    for n in xrange(200):
   
        x = float(randint(0, 639))
        y = float(randint(0, 479))
        speed = float(randint(10, 300))
        stars.append( Star(x, y, speed) )
   
    clock = pygame.time.Clock()
   
    white = (255, 255, 255)
   
    while True:
   
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            if event.type == KEYDOWN:
                return
   
        # 增加一顆新的星星
        y = float(randint(0, 479))
        speed = float(randint(10, 300))
        star = Star(640., y, speed)
        stars.append(star)
   
        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000.
   
        screen.fill((0, 0, 0))
   
        # 繪製所有的星
        for star in stars:
   
            new_x = star.x - time_passed_seconds * star.speed
            pygame.draw.aaline(screen, white, (new_x, star.y), (star.x+1., star.y))
            star.x = new_x
   
        def on_screen(star):
            return star.x > 0
   
        # 星星跑出了畫面,就刪了它
        stars = filter(on_screen, stars)
   
        pygame.display.update()
   
if __name__ == "__main__":
    run()


這裡你還可以把FULLSCREEN加上,更有感覺。

這個程式給我的畫面,發揮一下你的想象,不是一片宇宙麼,無數的星雲穿梭,近的速度更快,遠的則很慢。而實際上看程式碼,我們只是畫了一些長短不同的線而已!雖然很簡單,還是用了不少不少python的技術,特別是函數語言程式設計的(小)技巧。不過強大的你一定沒問題:)但是pygame的程式碼,沒有任何沒講過的,為什麼這樣就能有3D的效果了?感謝你的大腦,因為它知道遠的看起來更慢,所以這樣的錯覺就產生了。

理解3D空間

3D空間的事情,基本就是立體幾何的問題,高中學一半應該就差不多理解了,這裡不多講了。你能明白下圖的小球在(7, 5, 10)的位置,換句話說,如果你站在原點,面朝Z軸方向。那麼小球就在你左邊7,上面5,前面10的位置。這就夠了~

用python寫遊戲 - 從入門到精通16

使用3D向量

我們已經學習了二維向量來表達運動,在三維空間內,當然要使用三維的向量。其實和二維的概念都一樣,加減縮放啥的,這裡就不用三個元素的元組列表先演練一番了,直接祭出我們的gameobjects神器吧!

from gameobjects.vector3 import *
A = Vector3(6, 8, 12)
B = Vector3(10, 16, 12)
print "A is", A
print "B is", B
print "Magnitude of A is", A.get_magnitude()
print "A+B is", A+B
print "A-B is", A–B
print "A normalized is", A.get_normalized()
print "A*2 is", A * 2


執行一下看看結果吧,有些無趣?確實,光數字沒法展現3D的美啊,下一次,讓我們把物體在立體空間內運動起來。


相關文章