Python 項目實踐一(外星人入侵小遊戲)第五篇

接着上節的繼續學習,在本章中,咱們將結束遊戲《外星人入侵》的開發。咱們將添加一個Play按鈕,用於根據須要啓動遊戲以及在遊戲結束後重啓遊戲。咱們還將修改這個遊戲,使其在玩家的等級提升時加快節奏,並實現一個記分系統。python

一 添加Play按鈕

因爲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)

還有好多要寫,但實在寫不下去了,明天再寫吧!休息休息!

相關文章
相關標籤/搜索