1. 程式人生 > >Python12_專案一 :外星人入侵遊戲03(重構run_game() 且 在限制範圍內左右移動飛船)

Python12_專案一 :外星人入侵遊戲03(重構run_game() 且 在限制範圍內左右移動飛船)

為了更好地將程式碼模組化,我們將遊戲的主迴圈重構為兩個函式:

check_event() 和 update_screen(),並且,將他們封裝到game_function.py檔案中

其中,監視鍵盤和滑鼠事件的操作我們叫做check_event(),實時更新螢幕的操作我們叫update_screen()

如下圖所示:

然後附上game_function.py檔案的程式碼:

import sys
import pygame


def check_event(ship):          # 響應按鍵和滑鼠事件
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            sys.exit()

        elif i.type == pygame.KEYDOWN:
            if i.key == pygame.K_RIGHT:
                # 向右移動飛船
                ship.moving_right = True
                # ship.rect.centerx += 10
            elif i.key == pygame.K_LEFT:
                # 向左移動飛船
                # ship.rect.centerx -= 10
                ship.moving_left = True

        elif i.type == pygame.KEYUP:
            if i.key == pygame.K_RIGHT:
                ship.moving_right = False
            elif i.key == pygame.K_LEFT:
                ship.moving_left = False


def update_screen(ai_setting,screen,ship):      # 更新螢幕上的影象,並切換到新螢幕
    # 每次迴圈時都重繪螢幕
    screen.fill(ai_setting.bg_color)
    ship.blitme()
    # 讓最近繪製的螢幕可見
    pygame.display.flip()

 對於在限制範圍內的左右移動,首先要解決的是左右移動問題,我們要在ship.py的Shi類中設定一個移動標誌

self.moving_right = False

當然,上述程式碼,只是往右移動的標誌,預設為False。當鍵盤摁下→鍵時,改變為True,這個程式碼在上面的check_event()函式中得以體現。然後回到ship.py寫移動飛船的函式update(),更新飛船的center值,使其可以移動作為飛船的rect物件。說起來,比較抽象,還是在下面附上更新後的程式碼。

再附上geng更新後的alien_invasion.py、ship.py、settings.py程式碼。

特別注意:凡是帶02的地方,都是與更新有關的地方!!!

alien_invasion.py更新程式碼:

# 02 import sys
import pygame
from alien.settings import Setting      # 01
from alien.ship import Ship             # 01
import alien.game_function as gf        # 02


def run_game():          # 初始化遊戲,並且建立一個螢幕物件
    pygame.init()        # 初始化背景設定,讓Pygame能夠正確地工作
    # 01 screen = pygame.display.set_mode((1200, 800))     # 建立一個名為screen 的顯示視窗,括號裡是元組!!!
    # 01                                                   # 這個遊戲的所有圖形元素都將在其中繪製
    ai_set = Setting()                                     # 因為匯入類而做了程式碼替換
    screen = pygame.display.set_mode(
        (ai_set.screen_width,ai_set.screen_height)
    )
    # 01 bg_color = (230,230,230)         # 設定背景顏色

    pygame.display.set_caption('外星人入侵')
    # 建立一艘飛船物件
    ship = Ship(ai_set,screen)

    # 為讓程式響應事件,我們編寫一個事件迴圈,以偵聽事件,並根據發生的事件執行相應的任務。
    while True:  # 遊戲的主迴圈
        # 02 for event in pygame.event.get():    # 監視鍵盤和滑鼠
        # 02     if event.type == pygame.QUIT:   #編寫一系列的if 語句來檢測並響應特定的事件
        # 02         sys.exit()                  # 我們呼叫sys.exit() 來退出遊戲
        gf.check_event(ship)    # 02
        ship.update()           # 02
        # 01screen.fill(bg_color)                # 每次迴圈都重繪螢幕
        # 02 screen.fill(ai_set.bg_color)
        # 02 ship.blitme()                       # 呼叫blitme函式,使飛船出現
        # 02 pygame.display.flip()               # 讓最近繪製的螢幕可見
        gf.update_screen(ai_set,screen,ship)     # 02

run_game()

ship.py更新程式碼:

import pygame


class Ship():
    def __init__(self,ai_setting,screen):         # 初始化飛船,並設定初始位置
        self.screen = screen
        self.ai_setting = ai_setting              # 02
        # 載入飛船影象並獲取其外接矩形
        self.img = pygame.image.load('D:\\python\\PyCharm 2016.3.2\\project\\alien\\fei.bmp')
        self.rect = self.img.get_rect()           # 我們使用get_rect() 獲取相應surface的屬性rect
        self.screen_rect = self.screen.get_rect()

        # 將每艘新飛船放在螢幕底部中央
        # 要將遊戲元素居中,可設定相應rect 物件的屬性center 、centerx 或centery 。
        self.rect.centerx = self.screen_rect.centerx
        # 要讓遊戲元素與螢幕邊緣對齊,可使用屬性top 、bottom 、left 或right ;
        # 要調整遊戲元素的水平或垂直位置,可使用屬性x 和y ,它們分別是相應矩形左上角的 x 和 y 座標。
        self.rect.bottom = self.screen_rect.bottom
        # 在飛船的屬性center中儲存小數數值
        self.center = float(self.rect.centerx)     # 小數形式的位移可以更好的控制飛船移動

        # 移動標誌,# 02
        # 飛船不動時,標誌moving_right將為False 。
        # 玩家按下右箭頭鍵時,我們將這個標誌設定為True ;而玩家鬆開時,我們將這個標誌重新設定為False
        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False

    # 根據移動標誌,移動飛船 # 02
    def update(self):
        if self.moving_right and self.rect.right < self.screen_rect.right:      # 控制飛船移動的左右範圍
            # 02 self.rect.centerx += 1
            # 02 更新飛船的center值,而不是rect
            self.center += self.ai_setting.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            # 02 self.rect.centerx -= 1
            self.center -= self.ai_setting.ship_speed_factor

        # 根據self.center更新rect物件
        self.rect.centerx = self.center

    # 我們定義了方法blitme() ,它根據self.rect 指定的位置將影象繪製到螢幕上
    # 在指定位置繪製飛船
    def blitme(self):
        self.screen.blit(self.img,self.rect)    # 把img這個surface物件貼到rect的位置

 settings.py更新程式碼:

class Setting():            # 儲存《外星人入侵》中所有的設定類
    def __init__(self):     # 初始化遊戲設定
        self.screen_width = 1200        # 螢幕設定
        self.screen_height = 800
        self.bg_color = (230,230,230)

        self.ship_speed_factor = 1.5    # 02 設定飛船速度