Python13_專案一 :外星人入侵遊戲04(重構check_event() 以及 使飛船發射子彈)
阿新 • • 發佈:2019-01-04
為了使程式碼模組化、結構化,我們將check_event()函式中的按鍵響應,重構為兩個函式:分別是check_keydown() 【響應按鍵】和 check_keyup() 【響應鬆開】。
重構後的程式碼如下:(此程式碼為本節部分程式碼,整體程式碼稍後,這段程式碼看看就好)
# 響應按鍵 03 def check_keydown(event, ai_settings, screen, ship, bullets): if event.key == pygame.K_RIGHT: # 向右移動飛船 ship.moving_right = True # ship.rect.centerx += 10 elif event.key == pygame.K_LEFT: # 向左移動飛船 # ship.rect.centerx -= 10 ship.moving_left = True # 響應鬆開 03 def check_keyup(event, ship): if event.key == pygame.K_RIGHT: ship.moving_right = False elif event.key == pygame.K_LEFT: ship.moving_left = False # 響應按鍵和滑鼠事件 def check_event(ai_setting, screen, ship, bullets): # 03 for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() elif i.type == pygame.KEYDOWN: check_keydown(i, ai_setting, screen, ship, bullets) # 重構 # 03 if i.key == pygame.K_RIGHT: # 03 # 向右移動飛船 # 03 ship.moving_right = True # 03 # ship.rect.centerx += 10 # 03 elif i.key == pygame.K_LEFT: # 03 # 向左移動飛船 # 03 # ship.rect.centerx -= 10 # 03 ship.moving_left = True elif i.type == pygame.KEYUP: check_keyup(i, ship) # 重構 # 03 if i.key == pygame.K_RIGHT: # 03 ship.moving_right = False # 03 elif i.key == pygame.K_LEFT: # 03 ship.moving_left = False
那麼接下來,就是要增加子彈。對於增加子彈,我們需要先在settings.py檔案中增加子彈的屬性。然後,寫一個bullet.py檔案,儲存Bullet類,為的是建立一個子彈的rect物件,並且能讓子彈從螢幕中繪製出來。具體檔案如下所示:
bullet.py程式碼如下所示:
import pygame from pygame.sprite import Sprite # 匯入精靈 # 一個對飛船發射的子彈進行管理的類 class Bullet(Sprite): def __init__(self,ai_setting,screen,ship): # 在飛船所處的位置建立一個子彈物件 super().__init__() # 初始化父類 2.7寫法super(Bullet,self).__init__() self.screen = screen # 在(0,0)處建立一個表示子彈的矩形,再設定正確的位置 # 我們建立了子彈的屬性rect 。子彈並非基於影象的,因此我們必須使用pygame.Rect()類從空白開始建立一個矩形 # 我們在(0, 0)處建立這個矩形,但接下來的兩行程式碼將其移到了正確的位置 self.rect = pygame.Rect(0,0,ai_setting.bullet_width,ai_setting.bullet_height) # 我們將子彈的centerx設定為飛船的rect.centerx 。 # 子彈應從飛船頂部射出,因此我們將表示子彈的rect的top屬性設定為飛船的rect的top屬性, # 讓子彈看起來像是從飛船中射出的 self.rect.centerx = ship.rect.centerx self.rect.top = ship.rect.top # 儲存用小數表示的子彈位置 self.y = float(self.rect.y) self.color = ai_setting.bullet_color self.speed = ai_setting.bullet_speed_factor # 向上移動子彈 def update(self, *args): # 更新表示子彈位置的小數值 self.y -= self.speed # 更新表示子彈位置的rect的位置 self.rect.y = self.y # 在螢幕上繪製子彈 def draw_bullet(self): # 函式draw.rect()使用儲存在self.color中的顏色填充表示子彈的rect佔據的螢幕部分 pygame.draw.rect(self.screen,self.color,self.rect)
然後附上更新後的其他.py檔案程式碼。
帶 03 標記的都是更新有關的!!!
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 設定飛船速度 # 03 設定子彈 self.bullet_speed_factor = 1 # 子彈速度 self.bullet_width = 3 # 子彈寬度 self.bullet_height = 15 # 子彈長度 self.bullet_color = 60,60,60 # 子彈顏色 self.bullet_allowed = 3 # 限制子彈數量為3
game_funtion.py
import sys
import pygame
from alien.bullet import Bullet # 03
# 響應按鍵 03
def check_keydown(event, ai_settings, screen, ship, bullets):
if event.key == pygame.K_RIGHT:
# 向右移動飛船
ship.moving_right = True
# ship.rect.centerx += 10
elif event.key == pygame.K_LEFT:
# 向左移動飛船
# ship.rect.centerx -= 10
ship.moving_left = True
# 03 建立一顆子彈,並將其加入到編組bullets中
elif event.key == pygame.K_SPACE:
if len(bullets) < ai_settings.bullet_allowed: # 限制三個子彈
# 玩家按空格鍵時,建立一顆新子彈(一個名為new_bullet 的Bullet 例項),
new_bullet = Bullet(ai_settings, screen, ship)
# 並使用方法add() 將其加入到編組bullets中
bullets.add(new_bullet)
# 響應鬆開 03
def check_keyup(event, ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
# 響應按鍵和滑鼠事件
def check_event(ai_setting, screen, ship, bullets): # 03
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
check_keydown(i, ai_setting, screen, ship, bullets) # 重構
# 03 if i.key == pygame.K_RIGHT:
# 03 # 向右移動飛船
# 03 ship.moving_right = True
# 03 # ship.rect.centerx += 10
# 03 elif i.key == pygame.K_LEFT:
# 03 # 向左移動飛船
# 03 # ship.rect.centerx -= 10
# 03 ship.moving_left = True
elif i.type == pygame.KEYUP:
check_keyup(i, ship) # 重構
# 03 if i.key == pygame.K_RIGHT:
# 03 ship.moving_right = False
# 03 elif i.key == pygame.K_LEFT:
# 03 ship.moving_left = False
def update_screen(ai_setting, screen, ship, bullets): # 更新螢幕上的影象,並切換到新螢幕
# 每次迴圈時都重繪螢幕
screen.fill(ai_setting.bg_color)
# 03 在飛船和外星人後面重繪所有子彈
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# 讓最近繪製的螢幕可見
pygame.display.flip()
# 03 更新子彈位置,並刪除已經消失的子彈
def update_bullet(bullets):
bullets.update() # 更新子彈位置
# 03 刪除已經消失,看不到的子彈
for bull in bullets.copy():
if bull.rect.bottom <= 0:
bullets.remove(bull)
print(len(bullets))
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
from pygame.sprite import Group # 03 pygame.sprite.Group 類類似於列表,但提供了有助於開發遊戲的額外功能
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)
# 03 匯入Group類並且建立一個Group例項,用於儲存子彈的編組
bullets = Group()
# 為讓程式響應事件,我們編寫一個事件迴圈,以偵聽事件,並根據發生的事件執行相應的任務。
while True: # 遊戲的主迴圈
# 02 for event in pygame.event.get(): # 監視鍵盤和滑鼠
# 02 if event.type == pygame.QUIT: #編寫一系列的if 語句來檢測並響應特定的事件
# 02 sys.exit() # 我們呼叫sys.exit() 來退出遊戲
gf.check_event(ai_set,screen,ship,bullets) # 02 03
ship.update() # 02
gf.update_bullet(bullets) # 03
# 03 bullets.update() # 03
# # 03 刪除已經消失,看不到的子彈
# for bull in bullets.copy():
# if bull.rect.bottom <= 0:
# bullets.remove(bull)
# print(len(bullets))
# 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,bullets) # 02 03
run_game()