目标
- 使用 定時器 添加敵機
- 設計
類Enemy
01. 使用定時器添加敵機
運作 備課代碼,觀察 敵機的 出現規律:
- 遊戲啟動後,每隔 1 秒 會 出現一架敵機
- 每架敵機 向螢幕下方飛行,飛行 速度各不相同
- 每架敵機出現的 水準位置 也不盡相同
- 當敵機 從螢幕下方飛出,不會再飛回到螢幕中
1.1 定時器
- 在
中可以使用 pygame
來添加 定時器pygame.time.set_timer()
- 所謂 定時器,就是 每隔一段時間,去 執行一些動作
set_timer(eventid, milliseconds) -> None
-
可以建立一個 事件set_timer
- 可以在 遊戲循環 的 事件監聽 方法中捕獲到該事件
- 第 1 個參數 事件代号 需要基于常量
來指定pygame.USEREVENT
-
是一個整數,再增加的事件可以使用 USEREVENT
指定,依次類推...USEREVENT + 1
- 第 2 個參數是 事件觸發 間隔的 毫秒值
定時器事件的監聽
- 通過
可以擷取目前時刻所有的 事件清單pygame.event.get()
- 周遊清單 并且判斷
是否等于 event.type
,如果相等,表示 定時器事件 發生eventid
1.2 定義并監聽建立敵機的定時器事件
pygame
的 定時器 使用套路非常固定:
- 定義 定時器常量 ——
eventid
- 在 初始化方法 中,調用
方法 設定定時器事件set_timer
- 在 遊戲循環 中,監聽定時器事件
1) 定義事件
- 在
的頂部定義 事件常量plane_sprites.py
# 敵機的定時器事件常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
- 在
的 初始化方法 中 建立使用者事件PlaneGame
# 4. 設定定時器事件 - 每秒建立一架敵機
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
2) 監聽定時器事件
- 在
方法中增加以下代碼:__event_handler
def __event_handler(self):
for event in pygame.event.get():
# 判斷是否退出遊戲
if event.type == pygame.QUIT:
PlaneGame.__game_over()
elif event.type == CREATE_ENEMY_EVENT:
print("敵機出場...")
02. 設計 Enemy
類
Enemy
- 遊戲啟動後,每隔 1 秒 會 出現一架敵機
- 每架敵機 向螢幕下方飛行,飛行 速度各不相同
- 每架敵機出現的 水準位置 也不盡相同
- 當敵機 從螢幕下方飛出,不會再飛回到螢幕中
- 初始化方法
- 指定 敵機圖檔
- 随機 敵機的 初始位置 和 初始速度
- 重寫 update() 方法
- 判斷 是否飛出螢幕,如果是,從 精靈組 删除
2.1 敵機類的準備
- 在
建立 plane_sprites
繼承自 Enemy
GameSprite
- 重寫 初始化方法,直接指定 圖檔名稱
- 暫時 不實作 随機速度 和 随機位置 的指定
- 重寫
方法,判斷是否飛出螢幕update
class Enemy(GameSprite):
"""敵機精靈"""
def __init__(self):
# 1. 調用父類方法,建立敵機精靈,并且指定敵機的圖像
super().__init__("./images/enemy1.png")
# 2. 設定敵機的随機初始速度
# 3. 設定敵機的随機初始位置
def update(self):
# 1. 調用父類方法,讓敵機在垂直方向運動
super().update()
# 2. 判斷是否飛出螢幕,如果是,需要将敵機從精靈組删除
if self.rect.y >= SCREEN_RECT.height:
print("敵機飛出螢幕...")
2.2 建立敵機
- 在
,添加 敵機精靈組__create_sprites
- 敵機是 定時被建立的,是以在初始化方法中,不需要建立敵機
- 在
,建立敵機,并且 添加到精靈組__event_handler
- 調用 精靈組 的
方法可以 向精靈組添加精靈add
- 在
,讓 敵機精靈組 調用 __update_sprites
和 update
方法draw
- 修改
的 plane_main
方法__create_sprites
# 敵機組
self.enemy_group = pygame.sprite.Group()
- 修改
的 plane_main
方法__update_sprites
self.enemy_group.update()
self.enemy_group.draw(self.screen)
- 定時出現敵機
elif event.type == CREATE_ENEMY_EVENT:
self.enemy_group.add(Enemy())
2.3 随機敵機位置和速度
1) 導入子產品
- 在導入子產品時,建議 按照以下順序導入
1. 官方标準子產品導入
2. 第三方子產品導入
3. 應用程式子產品導入
- 修改
增加 plane_sprites.py
的導入random
import random
2) 随機位置
-
bottom = y + height
-
y = bottom - height
3) 代碼實作
- 修改 初始化方法,随機敵機出現 速度 和 位置
def __init__(self):
# 1. 調用父類方法,建立敵機精靈,并且指定敵機的圖像
super().__init__("./images/enemy1.png")
# 2. 設定敵機的随機初始速度 1 ~ 3
self.speed = random.randint(1, 3)
# 3. 設定敵機的随機初始位置
self.rect.bottom = 0
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
2.4 移出螢幕銷毀敵機
- 敵機移出螢幕之後,如果 沒有撞到英雄,敵機的曆史使命已經終結
- 需要從 敵機組 删除,否則會造成 記憶體浪費
檢測敵機被銷毀
-
内置方法會在對象被銷毀前調用,在開發中,可以用于 判斷對象是否被銷毀__del__
def __del__(self):
print("敵機挂了 %s" % self.rect)
代碼實作
- 判斷敵機是否飛出螢幕,如果是,調用
方法從所有組中删除kill()
def update(self):
super().update()
# 判斷敵機是否移出螢幕
if self.rect.y >= SCREEN_RECT.height:
# 将精靈從所有組中删除
self.kill()