基于pygame的射击小游戏制作(四)击杀外星人
在本篇文章中,主要學習射擊子彈時外星人消失,達到擊殺外星人的效果
一、編程思路
1.1擊殺
我們需要在碰撞發生后讓外星人立即消失,故在更新子彈的位置后檢測碰撞。我們創建一個字典,這個字典的每一個鍵都是一顆子彈,而相應的鍵值則包含擊中的外星人。sprite.groupcollide()將每顆子彈的rect與每個rect比較。每當有子彈和外星人的rect重疊時,判斷其被子彈擊中,groupcollide()就在返回字典中添加一個鍵-值對。
game_functions.py
緊接著在alien_invasion.py的while循環中加入該方法
# 開始游戲主循環 while True: gf.check_events(ai_settings, screen, ship, bullets) ship.update() gf.update_bullets(aliens, bullets) gf.update_aliens(ai_settings, aliens) gf.update_screen(ai_settings, screen, ship, aliens, bullets)此時的運行效果如下:
1.2產生新外星人
要在所有外星人被消滅之后再產生新的一群外星人,我們需要檢查aliens編組是否為空,如果為空,就調用empty()刪除所有元素,從而刪除現有的子彈,再調用creat_fleet(),產生一群新的外星人
def update_bullets(ai_settings, screen, ship, aliens, bullets):--snip--# 檢查是否有子彈擊中了外星人# 如果是,就刪除相應的子彈和外星人collisions = pygame.sprite.groupcollide(bullets, aliens,True, True)if len(aliens) == 0:# 刪除現有的子彈并新建一群外星人?bullets.empty()create_fleet(ai_settings, screen, ship, aliens)1.3 重構update_bullets()
把處理子彈和外星人碰撞的代碼已到一個獨立的函數中,避免該函數過長。
def update_bullets(ai_settings, screen, ship, aliens, bullets):"""更新子彈的位置,刪除已消失的子彈"""#更新子彈位置bullets.update()# 刪除已經消失的子彈for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)check_bullet_alien_collisions(ai_settings, screen,ship, aliens, bullets)1.4 結束游戲
在外星人與飛船碰撞時或者外星人到達屏幕底端就結束游戲。首先我們要檢測外星人與飛船是否碰撞,調用方法spritecollideany(),它檢查編組中的外星人是否發生碰撞,找到與飛船碰撞的外星人后就停止遍歷編組。
# 檢測外星人和飛船之間的碰撞if pygame.sprite.spritecollideany(ship, aliens):print("Ship hit!!!")新建一個GameStats.py,通過跟蹤游戲的統計信息來記錄飛船被撞了多少次,reset_stats()中初始化大部分統計信息,然后在__init__中調用,有外星人撞到飛船時,我們將余下的飛船數減1,創建一群新的外星人,并將飛船重新放置到屏幕底端中央,并暫停0.5秒。
game_stats.py
game_functions.py
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):"""響應被外星人撞到的飛船"""if stats.ships_left > 0:#將ships_left減1stats.ships_left -= 1#清空外星人列表和子彈列表aliens.empty()bullets.empty()#創建新的外星人create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()#暫停sleep(0.5)else:stats.game_active = Falsecheck_aliens_bottom()在外星人到達屏幕底端時像外星人碰撞飛船一樣做出響應
def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):"""檢查是否有外星人到達"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飛船被撞到一樣進行處理ship_hit(ai_settings, stats, screen, ship, aliens, bullets)break在game_stats.py的init方法里加入游戲活動狀態game_active = True,可以在玩家生命次數用完時game_active = False 結束游戲。
二、源程序
alien_invasion.py
import sys #退出游戲 import pygame #包含開發所需功能 from settings import Settings from ship import Ship from alien import Alien import game_functions as gf from pygame.sprite import Group from game_stats import GameStates def run_game():# 初始化背景設置pygame.init()ai_settings = Settings()# 創建游戲窗口screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")"""創建一艘飛船"""ship = Ship(ai_settings, screen)"""創建一個外星人"""alien = Alien(ai_settings, screen)"""創建一個用于存儲子彈的編組"""bullets = Group()aliens = Group()#創建外星人群gf.create_fleet(ai_settings,screen, ship, aliens)"""設置背景色"""bg_color = (230,230,230)"""存儲游戲統計信息"""stats = GameStates(ai_settings)"""游戲主循環"""while True:"""監視鍵鼠事件"""gf.check_events(ai_settings, screen, ship, bullets)if stats.game_active:ship.update()#print(len(bullets))gf.update_bullets(ai_settings, screen, ship, aliens, bullets)gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)gf.update_screen(ai_settings, screen, ship, aliens, bullets)run_game()game_stats.py
class GameStates():"""跟蹤游戲的統計信息"""def __init__(self, ai_settings):"""初始化統計信息"""self.ai_settings = ai_settingsself.reset_stats()#游戲剛啟動時處于活動狀態self.game_active = Truedef reset_stats(self):"""初始化在游戲運行期間可能變化的統計信息"""self.ships_left = self.ai_settings.ship_limitgame_functions.py
import sys import pygame from bullet import Bullet from alien import Alien from time import sleepdef check_events(ai_settings, screen, ship, bullets):#鍵鼠響應for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings, screen, ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event, ship) def check_keydown_events(event, ai_settings, screen, ship, bullets):"""響應按鍵"""if event.key == pygame.K_RIGHT:# 向右移動飛船ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings, screen, ship, bullets)elif event.key == pygame.K_q:sys.exit()def check_keyup_events(event, ship):if event.key == pygame.K_RIGHT:ship.moving_right = Falseelif event.key == pygame.K_LEFT:ship.moving_left = Falsedef update_screen(ai_settings, screen, ship, aliens, bullets):#更新屏幕圖像# 每次循環時都重繪屏幕screen.fill(ai_settings.bg_color)#在飛船和外星人后面重繪所有子彈for bullets in bullets.sprites():bullets.draw_bullet()ship.blitme()aliens.draw(screen)# 讓最近繪制的屏幕可見pygame.display.flip() # 不斷更新屏幕def check_bullet_alien_collisions(ai_settings, screen,ship, aliens, bullets):#檢查是否有子彈擊中了外星人#若擊中,刪除相應的子彈和外星人collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)if len(aliens) == 0:#刪除現有的子彈并新建一群外星人bullets.empty()create_fleet(ai_settings, screen, ship, aliens)def update_bullets(ai_settings, screen, ship, aliens, bullets):"""更新子彈的位置,刪除已消失的子彈"""#更新子彈位置bullets.update()# 刪除已經消失的子彈for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)check_bullet_alien_collisions(ai_settings, screen,ship, aliens, bullets)def fire_bullet(ai_settings, screen, ship, bullets):"""如果還沒有達到限制,就發射一顆子彈"""# 創建一顆子彈,并將其加入到編組bulletsif len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)def create_fleet(ai_settings, screen,ship , aliens):"""創建外星人群"""#創建一個外星人,并計算一行可以容納多少個外星人#外星人間距為外星人寬度alien = Alien(ai_settings, screen)number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)number_rows = get_number_rows(ai_settings, ship.rect.height,alien.rect.height)#創建外星人群for row_number in range(number_rows):for alien_number in range(number_aliens_x):#創建第一個外星人并加入當前行create_alien(ai_settings, screen, aliens,alien_number, row_number)def get_number_aliens_x(ai_settings, alien_width):"""計算每行可容納多少個外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_aliens_x = int(available_space_x / (2 * alien_width))return number_aliens_xdef create_alien(ai_settings, screen, aliens, alien_number , row_number):"""創建一個外星人并將其放在當前行"""alien = Alien(ai_settings, screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def get_number_rows(ai_settings, ship_height, alien_height):"""計算屏幕可以容納多少行外星人"""available_space_y = (ai_settings.screen_height -(3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef check_fleet_edges(ai_settings, aliens):"""外星人到達邊緣時采取相應的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings, aliens)breakdef change_fleet_direction(ai_setting, aliens):"""將整群外星人下移,并改變他們的方向"""for alien in aliens.sprites():alien.rect.y += ai_setting.fleet_drop_speedai_setting.fleet_direction *= -1def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):"""檢查是否有外星人位于屏幕邊緣,并更新整群外星人的位置"""check_fleet_edges(ai_settings, aliens)aliens.update()#檢測外星人和飛船之間的碰撞if pygame.sprite.spritecollideany(ship, aliens):ship_hit(ai_settings, stats, screen, ship, aliens, bullets)""""檢查是否到達地端"""check_aliens_bottom(ai_settings, stats, screen, ship,aliens, bullets)def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):"""響應被外星人撞到的飛船"""if stats.ships_left > 0:#將ships_left減1stats.ships_left -= 1#清空外星人列表和子彈列表aliens.empty()bullets.empty()#創建新的外星人create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()#暫停sleep(0.5)else:stats.game_active = Falsedef check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):"""檢查是否有外星人到達"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飛船被撞到一樣進行處理ship_hit(ai_settings, stats, screen, ship, aliens, bullets)break三、運行效果
總結
以上是生活随笔為你收集整理的基于pygame的射击小游戏制作(四)击杀外星人的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分页插件PageHelper的使用方法
- 下一篇: 什么叫做项目孵化_蓝莓孵化营12进5争夺