參考博客:https://blog.csdn.net/Rock1105/article/details/84141307
最近在做python的期末項目,需要實現這個功能,然后各種百度,一直在調bug,走了一些彎路,導致搞了接近兩個小時才搞出來,總結一下我遇到的問題以及解決方案。
一.實現效果
爆炸圖片有七張,所以爆炸效果看上去是動態的



2.效果實現
第一步:新建一個Bomb爆炸類
import pygame class Bomb(object): # 初始化爆炸 def __init__(self,ai_settings,scene): self.main_scene = scene # 加載爆炸資源 self.image = [pygame.image.load("picture/bomb-" + str(v) + ".png") for v in range(1, 8)] # 設置當前爆炸播放索引 self.index = 0 # 圖片爆炸播放間隔 self.interval = 20 self.interval_index = 0 # 爆炸位置 self.position = [0, 0] # 是否可見 self.visible = False # 設置爆炸播放的位置 def set_pos(self, x, y): self.position[0] = x self.position[1] = y # 爆炸播放 def action(self): # 如果爆炸對象狀態不可見,則不計算坐標 if not self.visible: return # 控制每一幀圖片的播放間隔 self.interval_index += 1 if self.interval_index < self.interval: return self.interval_index = 0 self.index = self.index + 1 if self.index >= len(self.image): self.index = 0 self.visible = False # 繪制爆炸 def draw(self): # 如果對象不可見,則不繪制 if not self.visible: return self.main_scene.blit(self.image[self.index], (self.position[0], self.position[1]))
第二步:在alien_invasion.py中進行修改:
#添加代碼: #導入Bomb類 from Bomb import Bomb # 創建爆炸對象 bomb = Bomb(ai_settings,screen) #修改代碼: # 刪除已消失的子彈 gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb) gf.update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb) gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button,introduce_button,bomb)
第三步:在game_function.py中進行修改:
#導入Bomb類 from Bomb import Bomb #修改代碼 def update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb): """更新子彈的位置,並刪除已消失的子彈""" # 更新子彈的位置 bullets.update() # 刪除已消失的子彈 for bullet in bullets.copy(): if bullet.rect.bottom <= 0: bullets.remove(bullet) check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb) def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb): # 檢查是否有子彈擊中了外星人 # 如果是這樣,就刪除相應的外星人和子彈 """ collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) if collisions: for aliens in collisions.values(): stats.score += ai_settings.alien_points * len(aliens) sb.prep_score() check_high_score(stats, sb) """ for bullet in bullets: # 檢查子彈與飛機的碰撞,及擊中飛機 collisions = pygame.sprite.groupcollide(aliens, bullets, True, True) if collisions: current_pos = pygame.Vector2(bullet.rect.x, bullet.rect.y) if bullet.rect.collidepoint(current_pos): bomb.position[0] = (bullet.rect.x - 20) bomb.position[1] = (bullet.rect.y - 40) bomb.visible = True if len(aliens) == 0: # 刪除現有的子彈, 加快游戲節奏,並新建一群外星人 bullets.empty() ai_settings.increase_speed() # 提高等級 stats.level += 1 sb.prep_level() create_fleet(ai_settings, screen, ship, aliens) def update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb): """ 檢查是否有外星人到達屏幕邊緣 然后更新外星人群中的所有外星人位置 """ bomb.action() check_fleet_edges(ai_settings, aliens) check_alien_bottom(ai_settings, screen, stats, sb, ship, aliens, bullets) aliens.update() # 檢測外星人和飛船之間的碰撞 if pygame.sprite.spritecollideany(ship, aliens): ship_hit(ai_settings, screen, stats, sb, ship, aliens, bullets) def update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button,introduce_button,bomb): """更新屏幕上的圖像,並切換到新屏幕""" # 每次循環時都重繪屏幕 screen.fill(ai_settings.bg_color) # 在飛船和外星人后面重繪所有子彈 for bullet in bullets.sprites(): bullet.draw_bullet() ship.blitme() aliens.draw(screen) # 繪制爆炸圖片 # # 繪制爆炸圖片 #self.bomb.draw() bomb.draw() # 顯示得分 sb.show_score() # 如果游戲處於非活動狀態,就繪制Play按鈕 if not stats.game_active: play_button.draw_button() introduce_button.drawintroduce_button() # 讓最近繪制的屏幕可見 pygame.display.flip()
三.總結
1.創建bomb對象,我們可以仿照ship類去寫
# 創建爆炸對象
bomb = Bomb(ai_settings,screen
2.bomb在哪使用?
我們繪制初場景時以及相關的事件檢測(碰撞檢測)
3.如何找到發生碰撞的坐標?
子彈打中外星人發生碰撞,我們要求碰撞位置,可以直接去求發生碰撞的子彈的位置,而碰撞子彈可以通過從子彈的group中遍歷找到,找到碰撞坐標后我們把bomb的visible設為True(即可視)
注明:collisions = pygame.sprite.groupcollide(aliens, bullets, True, True)這里引用了碰撞檢測函數
for bullet in bullets: # 檢查子彈與飛機的碰撞,及擊中飛機 collisions = pygame.sprite.groupcollide(aliens, bullets, True, True) if collisions: current_pos = pygame.Vector2(bullet.rect.x, bullet.rect.y) if bullet.rect.collidepoint(current_pos): bomb.position[0] = (bullet.rect.x - 20) bomb.position[1] = (bullet.rect.y - 40) bomb.visible = True
