寫完《The Nature of Code閱讀心得筆記——使用Python實作》 《The Nature of Code閱讀心得與Python實作》第一章之後,就照原書的建議,開始用程式來打造一個生態系統。
因為進度才到第一章,能用的東西不多,當然不可能寫出什麼太複雜的效果出來,所以就決定用第一章最後一個範例當基礎,先試著做出些簡單的效果來。雖然這些效果都很簡單,但可以變成以後製作比較複雜效果時的「零件」來使用,零件越多,打造出來的生態系統應該會越豐富。
第一章最後一個範例所呈現的效果,是一堆會跟著滑鼠游標跑的球。看著這些追逐著滑鼠游標的球,決定讓它們不再像貓想抓老鼠一樣,追著不是真的老鼠的滑鼠跑,而讓它們回歸身為球的初心,變成在畫面中跑來跑去,碰到邊邊會反彈的球。
程式很快就寫好了,一堆球也在畫面上跑來跑去。不過,有個地方卻怪怪的,有時候當球碰到左邊邊界反彈時,會有條橫跨畫面的黑色長條快速地閃了一下。除了這個奇怪的現象之外,其他一切都正常。這究竟是怎麼回事?
難道是程式哪裡有問題?看到奇怪的現象,第一個冒出來的念頭,當然就是懷疑自己寫的程式。
為了要找出可能的程式錯誤,先把球的數量減少到只剩一個,然後看看當球碰到左邊邊界時,各個數字如球的座標、速度、加速度等,有沒有不對勁的地方。結果發現,當球碰到左邊邊界而閃現黑色長條時,球的中心點x座標是負值。
看來這應該是pygame的bug,而不是自己寫的程式有問題。為了進一步證實這個猜測,重寫了一個單純只畫出圓球的程式,除了畫出不同位置的圓球之外,沒有任何其他作用,結果如下:
圖中由上而下,圓球中心的座標分別為
(0, 50)
(-0.99999, 100)
(-1.0, 150)
(-16, 200)
(-50, 250)
(-1, 300)
從這裡就可以看出來,當球心的x座標小於等於-1時,就會出現問題。另外,這些橫線的確是跟圓球有關,因為在畫球時,最後一個球的半徑,刻意設定成其他圓球的一半,而最下面的那條橫線,寬度也剛好是其他橫線的一半。
這個抓bug的過程,還真是挺像偵探辦案的過程,大膽假設,小心求證,推理、模擬驗證樣樣不可少。
確定這是pygame的bug之後,到pygame的github專案上查了一下。果然!已經有好幾個人提出同樣的問題了,看來新的版本出來時,應該就不會有這個問題了。
測試程式:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((640, 360))
frame_rate = pygame.time.Clock()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
pygame.draw.circle(screen, BLACK, (0, 50), 16)
pygame.draw.circle(screen, BLACK, (-0.99999, 100), 16)
pygame.draw.circle(screen, BLACK, (-1.0, 150), 16)
pygame.draw.circle(screen, BLACK, (-16, 200), 16)
pygame.draw.circle(screen, BLACK, (-50, 250), 16)
pygame.draw.circle(screen, BLACK, (-1, 300), 8)
pygame.display.update()
frame_rate.tick(60)