關於這個問題,我最先想到的就是炸彈的使用方式是鍵盤按壓式,還是敲擊鍵盤式,(即key_pressed 或 KEYDOWN)。那麼現在你可以想想這裏有沒有弄錯了。
後來我發現確實是用了KEYDOWN的方法,還是出現這種狀況,那我就開始思考問題究竟出現在哪?
if not pause:
if event.type == pg.KEYDOWN: #全屏炸彈
if event.key== pg.K_SPACE and bomb_count > 0:
bomb_count -= 1
bomb_sound.play()
print('go on')
for each in groups:
if each.rect.bottom > 0:
each.alive = False
在這裏我就想到一個簡單方便檢測bug的方法,我在我要檢測錯誤的地方加上一條print語句,其中的內容並不重要,重要的是看print語句有沒有被執行,或者執行了幾次。(也可以寫成print(bomb_count),這樣可以直觀的看到炸彈數量的減少,而且是由這段代碼引起的)
結果卻如圖所示,go on 被打印了多次???
這時我就要思考了,爲什麼一個KEYDOWN的事件會背執行這麼多次??
這裏我就想到, 有沒有可能是因爲敵機爆炸的動畫延時了大概12幀左右導致的?但是我隨機就發現,我的if判斷語句好像沒有聯繫到敵機是否爆炸(即enemy.alive == False或者True),所以這個猜想是不太可能成立的。
於是我只能重新讀自己寫的又臭又長的代碼,自我感覺好像沒問題,這時我實在沒辦法,我就思考會不會是語句之間順序的問題???
我把前面那段代碼提到最前面,就像這樣:
while running:
for event in pg.event.get():
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸彈
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
然後我震驚的發現,再次按空格鍵,炸彈居然沒有再減少到 0 。這麼說就是語句順序出現了問題,於是我重新讀自己的代碼,原來未修改的錯誤代碼如下:
while running:
for event in pg.event.get():
if me.life == 0:
running = False
elif event.type == pg.QUIT:
pg.quit() #這個必須在sys.quit前面,否則程序衝突
sys.exit()
elif event.type == SUPPLY: #補給發放
supply_sound.play()
if random.choice([True,False]):
bo_supply.reset()
else:
bu_supply.reset()
elif event.type == pg.MOUSEBUTTONDOWN: #鼠標點擊切換暫停
if event.button == 1 and pause_rect.collidepoint(event.pos):
pause = not pause
elif event.type == pg.MOUSEMOTION:
if pause_rect.collidepoint(event.pos):
if pause:
pause_image = resume_pressed_image
else:
pause_image = pause_pressed_image
else:
if pause:
pause_image = resume_nor_image
else:
pause_image = pause_nor_image
screen.blit(bg,(0,0)) #把屏幕重新繪製,防止暫停偷看屏幕
if not pause: #遊戲暫停
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸彈
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
key_pressed = pg.key.get_pressed() #獲得哪些按鍵被長按
if key_pressed[pg.K_w] or key_pressed[pg.K_UP]: #遊戲操作
me.moveUp()
if key_pressed[pg.K_s] or key_pressed[pg.K_DOWN]:
me.moveDown()
if key_pressed[pg.K_a] or key_pressed[pg.K_LEFT]:
me.moveLeft()
if key_pressed[pg.K_d] or key_pressed[pg.K_RIGHT]:
me.moveRight()
仔細地讀一讀,不難發現screen.blit(if not pause這句也是)這一語句居然和for event這一語句的遞進關係處於同一級!這就表明當程序執行到這時前面的for event in pg.event.get()語句中的event已經結束了,那麼我的空格鍵事件當然不會再正常執行。
於是解決方法就出來了,我們只需要把空格的那段語句提前到screen.blit語句前面就好了,但是要注意的是我們這裏有暫停功能的,那麼暫停後,你總不能按爆炸吧。因此還要在前面加上一句if not pause:即可。
部分正確代碼:
elif not pause:
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸彈
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
screen.blit(bg,(0,0)) #把屏幕重新繪製,防止暫停偷看屏幕
if not pause: #遊戲暫停
key_pressed = pg.key.get_pressed() #獲得哪些按鍵被長按
if key_pressed[pg.K_w] or key_pressed[pg.K_UP]: #遊戲操作
me.moveUp()
if key_pressed[pg.K_s] or key_pressed[pg.K_DOWN]:
me.moveDown()
if key_pressed[pg.K_a] or key_pressed[pg.K_LEFT]:
me.moveLeft()
if key_pressed[pg.K_d] or key_pressed[pg.K_RIGHT]:
me.moveRight()
總結:寫代碼的經驗還是太少,相對於這種複製大型一點的代碼,語句的邏輯混亂就出現了,看來我還是要再多加練習。。。