????
目錄一奇钞、
一游戲背景
1.1 實(shí)現(xiàn)思路分析
1.2 設(shè)計(jì)背景類
1.3 背景精靈的實(shí)現(xiàn)
二奢驯、敵機(jī)出場(chǎng)
2.1 定時(shí)器
2.2 定義并監(jiān)聽創(chuàng)建敵機(jī)的定時(shí)器事件
2.3 設(shè)計(jì) Enemy 類
2.4 敵機(jī)類的準(zhǔn)備
2.5 創(chuàng)建敵機(jī)
2.6 隨機(jī)敵機(jī)位置和速度
2.7 移出屏幕銷毀敵機(jī)
一、游戲背景
1.1 實(shí)現(xiàn)思路分析
游戲啟動(dòng)后供填,背景圖像會(huì)連續(xù)不斷地向下方移動(dòng)泡一,實(shí)際上在采取了背景交替滾動(dòng)的實(shí)現(xiàn)思路创夜,在在 視覺(jué)上 產(chǎn)生英雄的飛機(jī)不斷向上方飛行的錯(cuò)覺(jué) —— 在很多跑酷類游戲中常用的套路
實(shí)現(xiàn)思路分析.png
解決辦法
- 創(chuàng)建兩張背景圖像精靈
- 第
1
張 完全和屏幕重合 - 第
2
張?jiān)?屏幕的正上方
- 第
- 兩張圖像 一起向下方運(yùn)動(dòng)
self.rect.y += self.speed
- 當(dāng) 任意背景精靈 的
rect.y >= 屏幕的高度
說(shuō)明已經(jīng) 移動(dòng)到屏幕下方 - 將 移動(dòng)到屏幕下方的這張圖像 設(shè)置到 屏幕的正上方
rect.y = -rect.height
1.2 設(shè)計(jì)背景類
設(shè)計(jì)背景類.png
-
初始化方法
- 直接指定 背景圖片
-
is_alt
判斷是否是另一張圖像-
False
表示 第一張圖像兰吟,需要與屏幕重合 -
True
表示 另一張圖像通惫,在屏幕的正上方
-
-
update() 方法
- 判斷 是否移動(dòng)出屏幕,如果是混蔼,將圖像設(shè)置到 屏幕的正上方履腋,從而實(shí)現(xiàn) 交替滾動(dòng)
繼承 如果父類提供的方法,不能滿足子類的需求:
- 派生一個(gè)子類
- 在子類中針對(duì)特有的需求惭嚣,重寫父類方法遵湖,并且進(jìn)行擴(kuò)展
1.3 背景精靈的實(shí)現(xiàn)
- 在
plane_sprites
新建Background
繼承自GameSprite
class Background(GameSprite):
"""游戲背景精靈"""
def __init__(self, is_alt = False):
super().__init__("./images/background.png")
if is_alt:
self.rect.y = - self.rect.height
def update(self):
super().update()
if self.rect.y >= SCREEN_RECT.height:
self.rect.y = - self.rect.height
- 在
plane_main.py
中顯示背景精靈
- 在
__create_sprites
方法中創(chuàng)建 精靈 和 精靈組 - 在
__update_sprites
方法中,讓 精靈組 調(diào)用update()
和draw()
方法
def __create_sprites(self):
# 創(chuàng)建背景精靈和精靈組
bg = Background()
bg1 = Background(True)
self.back_group = pygame.sprite.Group(bg,bg1)
def __update_sprites(self):
self.back_group.update()
self.back_group.draw(self.screen)
二晚吞、敵機(jī)出場(chǎng)
2.1 定時(shí)器
- 在
pygame
中可以使用pygame.time.set_timer()
來(lái)添加 定時(shí)器 - 所謂 定時(shí)器奄侠,就是 每隔一段時(shí)間,去 執(zhí)行一些動(dòng)作
set_timer(eventid, milliseconds) -> None
-
set_timer
可以創(chuàng)建一個(gè) 事件 - 可以在 游戲循環(huán) 的 事件監(jiān)聽 方法中捕獲到該事件
- 第 1 個(gè)參數(shù) 事件代號(hào) 需要基于常量
pygame.USEREVENT
來(lái)指定-
USEREVENT
是一個(gè)整數(shù)载矿,再增加的事件可以使用USEREVENT + 1
指定,依次類推...
-
- 第 2 個(gè)參數(shù)是 事件觸發(fā) 間隔的 毫秒值
定時(shí)器事件的監(jiān)聽
- 通過(guò)
pygame.event.get()
可以獲取當(dāng)前時(shí)刻所有的 事件列表 -
遍歷列表 并且判斷
event.type
是否等于eventid
烹卒,如果相等闷盔,表示 定時(shí)器事件 發(fā)生
2.2 定義并監(jiān)聽創(chuàng)建敵機(jī)的定時(shí)器事件
pygame
的 定時(shí)器 使用套路非常固定:
- 定義 定時(shí)器常量 ——
eventid
- 在 初始化方法 中,調(diào)用
set_timer
方法 設(shè)置定時(shí)器事件 - 在 游戲循環(huán) 中旅急,監(jiān)聽定時(shí)器事件
1) 定義事件
- 在
plane_sprites.py
的頂部定義 事件常量
# 敵機(jī)的定時(shí)器事件常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
- 在
PlaneGame
的 初始化方法 中 創(chuàng)建用戶事件
# 4. 設(shè)置定時(shí)器事件 - 每秒創(chuàng)建一架敵機(jī)
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
2) 監(jiān)聽定時(shí)器事件
- 在
__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("敵機(jī)出場(chǎng)...")
2.3 設(shè)計(jì) Enemy 類
- 游戲啟動(dòng)后逢勾,每隔 1 秒 會(huì) 出現(xiàn)一架敵機(jī)
- 每架敵機(jī) 向屏幕下方飛行,飛行 速度各不相同
- 每架敵機(jī)出現(xiàn)的 水平位置 也不盡相同
- 當(dāng)敵機(jī) 從屏幕下方飛出藐吮,不會(huì)再飛回到屏幕中
設(shè)計(jì) Enemy 類.png
-
初始化方法
- 指定 敵機(jī)圖片
- 隨機(jī) 敵機(jī)的 初始位置 和 初始速度
- 重寫 update() 方法
- 判斷 是否飛出屏幕溺拱,如果是,從 精靈組 刪除
2.4 敵機(jī)類的準(zhǔn)備
- 在
plane_sprites
新建Enemy
繼承自GameSprite
- 重寫 初始化方法谣辞,直接指定 圖片名稱
- 暫時(shí) 不實(shí)現(xiàn) 隨機(jī)速度 和 隨機(jī)位置 的指定
- 重寫
update
方法迫摔,判斷是否飛出屏幕,移出屏幕則銷毀敵機(jī)
class Enemy(GameSprite):
"""敵機(jī)精靈"""
def __init__(self):
# 1. 調(diào)用父類方法泥从,創(chuàng)建敵機(jī)精靈句占,并且指定敵機(jī)的圖像
super().__init__("./images/enemy1.png")
# 2. 設(shè)置敵機(jī)的隨機(jī)初始速度
self.speed = random.randint(1,3)
# 3. 設(shè)置敵機(jī)的隨機(jī)初始位置
self.rect.bottom = 0
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
def update(self):
# 1. 調(diào)用父類方法,讓敵機(jī)在垂直方向運(yùn)動(dòng)
super().update()
# 2. 判斷是否飛出屏幕躯嫉,如果是纱烘,需要將敵機(jī)從精靈組刪除
if self.rect.y >= SCREEN_RECT.height:
print("敵機(jī)飛出屏幕")
self.kill()
def __del__(self):
print("敵機(jī)掛了 %s" % self.rect)
2.5 創(chuàng)建敵機(jī)
- 在
__create_sprites
杨拐,添加 敵機(jī)精靈組- 敵機(jī)是 定時(shí)被創(chuàng)建的,因此在初始化方法中擂啥,不需要?jiǎng)?chuàng)建敵機(jī)
- 在
__event_handler
哄陶,創(chuàng)建敵機(jī),并且 添加到精靈組- 調(diào)用 精靈組 的
add
方法可以 向精靈組添加精靈
- 調(diào)用 精靈組 的
- 在
__update_sprites
哺壶,讓 敵機(jī)精靈組 調(diào)用update
和draw
方法
2.6 隨機(jī)敵機(jī)位置和速度
1) 導(dǎo)入模塊
- 在導(dǎo)入模塊時(shí)屋吨,建議 按照以下順序?qū)?/li>
1. 官方標(biāo)準(zhǔn)模塊導(dǎo)入
2. 第三方模塊導(dǎo)入
3. 應(yīng)用程序模塊導(dǎo)入
- 修改
plane_sprites.py
增加random
的導(dǎo)入
import random
2) 隨機(jī)位置
圖片.png
使用 pygame.Rect
提供的 bottom
屬性,在指定敵機(jī)初始位置時(shí)变骡,會(huì)比較方便
bottom = y + height
y = bottom - height
3) 代碼實(shí)現(xiàn)
- 修改 初始化方法离赫,隨機(jī)敵機(jī)出現(xiàn) 速度 和 位置
def __init__(self):
# 1. 調(diào)用父類方法,創(chuàng)建敵機(jī)精靈塌碌,并且指定敵機(jī)的圖像
super().__init__("./images/enemy1.png")
# 2. 設(shè)置敵機(jī)的隨機(jī)初始速度 1 ~ 3
self.speed = random.randint(1, 3)
# 3. 設(shè)置敵機(jī)的隨機(jī)初始位置
self.rect.bottom = 0
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
2.7 移出屏幕銷毀敵機(jī)
檢測(cè)敵機(jī)被銷毀
-
__del__
內(nèi)置方法會(huì)在對(duì)象被銷毀前調(diào)用渊胸,在開發(fā)中,可以用于 判斷對(duì)象是否被銷毀
def __del__(self):
print("敵機(jī)掛了 %s" % self.rect)
- 判斷敵機(jī)是否飛出屏幕台妆,如果是翎猛,調(diào)用
kill()
方法從所有組中刪除
def update(self):
super().update()
# 判斷敵機(jī)是否移出屏幕
if self.rect.y >= SCREEN_RECT.height:
# 將精靈從所有組中刪除
self.kill()
游戲背景和敵機(jī)出場(chǎng)效果圖.gif