接着上節的繼續學習,在本章中,咱們將結束遊戲《外星人入侵》的開發。咱們將添加一個Play按鈕,用於根據須要啓動遊戲以及在遊戲結束後重啓遊戲。咱們還將修改這個遊戲,使其在玩家的等級提升時加快節奏,並實現一個記分系統。python
因爲Pygame沒有內置建立按鈕的方法,咱們建立一個Button類,用於建立帶標籤的實心矩形。你能夠在遊戲中使用這些代碼來建立任何按鈕。下面是Button類的第一部分,請將這個類保存爲button.py代碼以下:ide
import pygame.font class Button() : def __init__(self,ai_settings,screen,msg): #初始化按鈕的屬性 self.screen=screen self.screen_rect=screen.get_rect() #設置按鈕的尺寸和其餘屬性 self.width,self.height=200,50 self.button_color=(0,255,0) self.text_color = (255,255,255) self.font = pygame.font.SysFont(None,48) #建立按鈕的rect對象,並使其居中 self.rect = pygame.Rect(0,0,self.width,self.height) self.rect.center = self.screen_rect.center #按鈕的標籤只須要建立一次 self.prep_msg(msg) def prep_msg(self,msg): #講msg渲染爲圖像,並使其在按鈕上居中 self.msg_image = self.font.render(msg,True,self.text_color,self.button_color) self.msg_image_rect = self.msg_image.get_rect() self.msg_image_rect.center = self.rect.center def draw_button(self): #繪製一個用顏色填充的按鈕,再繪製文本 self.screen.fill(self.button_color,self.rect) self.screen.blit(self.msg_image,self.msg_image_rect)
代碼中已經註釋的很清楚了,再也不作過多的介紹,這裏重點說一下幾個點:oop
(1)導入了模塊pygame.font,它讓Pygame可以將文本渲染到屏幕上。學習
(2)pygame.font.SysFont(None,48)指定使用什麼字體來渲染文本。實參None讓Pygame使用默認字體,而48指定了文本的字號。字體
(3)方法prep_msg()接受實參self以及要渲染爲圖像的文本(msg)。調用font.render()將存儲在msg中的文本轉換爲圖像,而後將該圖像存儲在msg_image中。spa
(4)方法font.render()還接受一個布爾實參,該實參指定開啓仍是關閉反鋸齒功能(反鋸齒讓文本的邊緣更平滑)3d
(5)screen.fill()來繪製表示按鈕的矩形,再調用screen.blit(),並向它傳遞一幅圖像以及與該圖像相關聯的rect對象,從而在屏幕上繪製文本圖像。對象
在alien_invasion.py中添加標亮的代碼:blog
import pygame from pygame.sprite import Group from settings import Settings from game_stats import GameStats from ship import Ship import game_functions as gf from button import Button def run_game(): # Initialize pygame, settings, and screen object. pygame.init() ai_settings = Settings() screen = pygame.display.set_mode( (ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") #建立play按鈕 play_button = Button(ai_settings,screen,"Play") # Create an instance to store game statistics. stats = GameStats(ai_settings) # Set the background color. bg_color = (230, 230, 230) # Make a ship, a group of bullets, and a group of aliens. ship = Ship(ai_settings, screen) bullets = Group() aliens = Group() # Create the fleet of aliens. gf.create_fleet(ai_settings, screen, ship, aliens) # Start the main loop for the game. while True: gf.check_events(ai_settings, screen, ship, bullets) if stats.game_active: ship.update() 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, stats, ship, aliens, bullets,play_button) run_game()
修改update_screen(),以便在遊戲處於非活動狀態時顯示Play按鈕:遊戲
def update_screen(ai_settings, screen,stats, ship, aliens, bullets,play_button):
"""Update images on the screen, and flip to the new screen."""
# Redraw the screen, each pass through the loop.
screen.fill(ai_settings.bg_color)
# Redraw all bullets, behind ship and aliens.
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)
if not stats.game_active :
play_button.draw_button()
# Make the most recently drawn screen visible.
pygame.display.flip()
運行效果以下:
爲在玩家單擊Play按鈕時開始新遊戲,需在game_functions.py中添加以下代碼,以監視與這個按鈕相關的鼠標事件:
def check_events(ai_settings, screen, stats,play_button,ship, bullets): """Respond to keypresses and mouse events.""" 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) elif event.type == pygame.MOUSEBUTTONDOWN : mouse_x,mouse_y = pygame.mouse.get_pos() check_play_button(stats,play_button,mouse_x,mouse_y) def check_play_button(stats,play_button,mouse_x,mouse_y) : #在玩家點擊play按鈕時開始遊戲 if play_button.rect.collidepoint(mouse_x,mouse_y) : stats.game_active = True
注意一下幾點:
(1)不管玩家單擊屏幕的什麼地方,Pygame都將檢測到一個MOUSEBUTTONDOWN事件,但咱們只關心這個遊戲在玩家用鼠標單擊Play按鈕時做出響應。
(2)使用了pygame.mouse.get_pos(),它返回一個元組,其中包含玩家單擊時鼠標的x和y座標。
(3)使用collidepoint()檢查鼠標單擊位置是否在Play按鈕的rect內,若是是這樣的,咱們就將game_active設置爲True,讓遊戲就此開始!
四 重置遊戲,將按鈕切換到非活動狀態以及隱藏光標
前面編寫的代碼只處理了玩家第一次單擊Play按鈕的狀況,而沒有處理遊戲結束的狀況,由於沒有重置致使遊戲結束的條件。爲在玩家每次單擊Play按鈕時都重置遊戲,須要重置統計信息、刪除現有的外星人和子彈、建立一羣新的外星人,並讓飛船居中。
def check_events(ai_settings, screen, stats,play_button,ship,aliens, bullets): """Respond to keypresses and mouse events.""" 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) elif event.type == pygame.MOUSEBUTTONDOWN : mouse_x,mouse_y = pygame.mouse.get_pos() check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y) def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y) : #在玩家點擊play按鈕時開始遊戲 button_clicked=play_button.rect.collidepoint(mouse_x,mouse_y) if button_clicked and not stats.game_active : #隱藏光標 pygame.mouse.set_visible(False) #重置遊戲信息 stats.reset_stats() stats.game_active = True #清空外星人列表和子彈列表 aliens.empty() bullets.empty() #建立一羣新的外星人,並讓飛船居中 create_fleet(ai_settings,screen,ship,aliens) ship.center_ship()
注意一下幾點:
(1),Play按鈕存在一個問題,那就是即使Play按鈕不可見,玩家單擊其原來所在的區域時,遊戲依然會做出響應。遊戲開始後,若是玩家不當心單擊了Play按鈕原來所處的區域,遊戲將從新開始!爲修復這個問題,可以讓遊戲僅在game_active爲False時纔開始!
button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y) if button_clicked and not stats.game_active:
(2)爲讓玩家可以開始遊戲,咱們要讓光標可見,但遊戲開始後,光標只會添亂。在遊戲處於活動狀態時讓光標不可見,遊戲結束後,咱們將從新顯示光標,讓玩家可以單擊Play按鈕來開始新遊戲。
def check_play_button(ai_settings, screen, stats, play_button, ship, aliens,bullets, mouse_x, mouse_y): """在玩家單擊Play按鈕時開始新遊戲""" button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y) if button_clicked and not stats.game_active: # 隱藏光標 pygame.mouse.set_visible(False)
還有好多要寫,但實在寫不下去了,明天再寫吧!休息休息!