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


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

一 添加Play按鈕

由於Pygame沒有內置創建按鈕的方法,我們創建一個Button類,用於創建帶標簽的實心矩形。你可以在游戲中使用這些代碼來創建任何按鈕。下面是Button類的第一部分,請將這個類保存為button.py代碼如下:

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)

代碼中已經注釋的很清楚了,不再做過多的介紹,這里重點說一下幾個點:

(1)導入了模塊pygame.font,它讓Pygame能夠將文本渲染到屏幕上。

(2)pygame.font.SysFont(None,48)指定使用什么字體來渲染文本。實參None讓Pygame使用默認字體,而48指定了文本的字號。

(3)方法prep_msg()接受實參self以及要渲染為圖像的文本(msg)。調用font.render()將存儲在msg中的文本轉換為圖像,然后將該圖像存儲在msg_image中。

(4)方法font.render()還接受一個布爾實參,該實參指定開啟還是關閉反鋸齒功能(反鋸齒讓文本的邊緣更平滑)

(5)screen.fill()來繪制表示按鈕的矩形,再調用screen.blit(),並向它傳遞一幅圖像以及與該圖像相關聯的rect對象,從而在屏幕上繪制文本圖像。

二 在屏幕繪制按鈕

在alien_invasion.py中添加標亮的代碼:

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)

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

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM