python游戏程序中游戏对象是什么_练习项目21:使用python制作游戏(下)
該樓層疑似違規(guī)已被系統(tǒng)折疊 隱藏此樓查看此樓
這一篇教程,我們來(lái)完成游戲的主程序模塊。
最終編寫完的游戲會(huì)有如下界面。
游戲界面匯總圖:
接下來(lái),根據(jù)上一篇教程的結(jié)構(gòu),我們編寫每一個(gè)類的代碼。
一、State類
從游戲界面匯總圖中,我們能夠看出,游戲中會(huì)有暫停狀態(tài)(除關(guān)卡界面之外的界面)和運(yùn)行狀態(tài)(關(guān)卡界面)。
State類就是將這兩個(gè)狀態(tài)進(jìn)行抽象,包括。
無(wú)論那個(gè)狀態(tài)都需要對(duì)退出游戲的指令進(jìn)行處理;
無(wú)論哪個(gè)狀態(tài)都要顯示界面內(nèi)容。
對(duì)于退出游戲指令的處理,我們需要定義一個(gè)處理方法;
而顯示內(nèi)容我們需要定義兩個(gè)方法,因?yàn)閮蓚€(gè)狀態(tài)的內(nèi)容顯示要有不同的處理。
示例代碼:
class State:
"""泛型游戲狀態(tài)類,可以處理事件并在給定的表面上顯示自身。"""
def handle(self, event):
"""處理退出事件。"""
if event.type == QUIT:
sys.exit()
if event.type == KEYDOWN and event.key == K_ESCAPE:
sys.exit()
def paused_display(self, screen):
"""暫停時(shí)顯示。"""
r = config.getint('Screen', 'red')
b = config.getint('Screen', 'blue')
g = config.getint('Screen', 'green')
screen.fill((r, b, g)) # 屏幕填充顏色
pygame.display.flip() # 刷新顯示屏幕
def display(self, screen): # 默認(rèn)不作處理,由子類Level重寫。
"""刷新顯示時(shí)。"""
pass
二、Level類
這個(gè)類繼承State類,主要對(duì)關(guān)卡運(yùn)行時(shí)進(jìn)行相應(yīng)的處理。
具體實(shí)現(xiàn)過(guò)程,大家可以通過(guò)注釋理解。
示例代碼:
class Level(State):
"""游戲等級(jí),用于計(jì)算共有多少敵機(jī)落下,移動(dòng)游戲?qū)ο笠约捌渌c游戲相關(guān)的邏輯任務(wù)。"""
def __init__(self, number=1):
"""初始化關(guān)卡的等級(jí)和游戲?qū)ο蟆?#34;""
self.number = number # 初始化關(guān)卡級(jí)別
self.remaining = config.getint('Level', 'pre_level') # 初始化關(guān)卡敵機(jī)數(shù)量
speed = config.getint('Speed', 'drop_speed') # 獲取設(shè)置文件中的敵機(jī)速度數(shù)值
speed += (self.number - 1) * config.getint('Speed', 'speed_increase') # 計(jì)算當(dāng)前關(guān)卡敵機(jī)速度數(shù)值
self.enemy = objects.Enemy(speed) # 創(chuàng)建敵方飛機(jī)游戲?qū)ο?/p>
self.plane = objects.Plane() # 創(chuàng)建己方飛機(jī)對(duì)象
self.sprites = pygame.sprite.RenderUpdates(self.enemy, self.plane) # 創(chuàng)建游戲?qū)ο蠹砑佑螒驅(qū)ο?/p>
def update(self, game):
"""關(guān)卡運(yùn)行,并進(jìn)行游戲結(jié)束或通過(guò)關(guān)卡的處理。"""
self.sprites.update() # 刷新游戲?qū)ο?/p>
if self.plane.touches(self.enemy): # 如果碰撞到敵方飛機(jī)
game.next_state = GameOver() # 變更狀態(tài)為游戲結(jié)束
elif self.enemy.landed: # 如果敵方飛機(jī)從屏幕底邊移出
self.enemy.reset() # 重置敵方飛機(jī)位置
self.remaining -= 1 # 敵機(jī)數(shù)量減少1架
if self.remaining == 0: # 如果敵機(jī)數(shù)量為0
game.next_state = LevelCleared(self.number) # 變更狀態(tài)為清空關(guān)卡
def display(self, screen):
"""關(guān)卡運(yùn)行時(shí)的屏幕顯示。"""
r = config.getint('Screen', 'red')
b = config.getint('Screen', 'blue')
g = config.getint('Screen', 'green')
screen.fill((r, b, g)) # 關(guān)卡運(yùn)行時(shí)為屏幕填充顏色
updates = self.sprites.draw(screen) # 繪制屏幕外觀
pygame.display.update(updates) # 刷新屏幕外觀
三、Paused類
這個(gè)類繼承自State類,是其它暫停狀態(tài)類的超類。
暫停狀態(tài)基本都是白色的屏幕和黑色的文字內(nèi)容。
當(dāng)然,也有例外。
歡迎界面做了兩種不同的方案,方案1只有一張圖片,方案2既有文字又有圖片。
根據(jù)這些情況,我們分析一下如何處理。
如果只有圖片直接繪制圖片;
如果只有文字則在屏幕中心繪制文字;
如果既有文字又有圖片,將圖片繪制在文字上方,間隔20像素。
具體實(shí)現(xiàn)過(guò)程,請(qǐng)大家參考代碼中的注釋理解。
示例代碼:
class Paused(State):
"""暫停游戲的狀態(tài),按任意鍵或點(diǎn)擊鼠標(biāo)退出暫停狀態(tài)。"""
next_state = None # 存儲(chǔ)下一個(gè)游戲狀態(tài)
finish = False # 記錄是否完成按鍵或鼠標(biāo)點(diǎn)擊
image = None # 存儲(chǔ)屏幕中顯示的圖片
text = '' # 存儲(chǔ)屏幕中顯示的文字
def handle(self, event):
"""處理按任意鍵繼續(xù)游戲。"""
State.handle(self, event)
if event.type in [MOUSEBUTTONDOWN, KEYDOWN]: # 如果捕獲鼠標(biāo)點(diǎn)擊和按鍵的事件
self.finish = True # 記錄完成操作
def update(self, game):
"""按任意鍵時(shí)進(jìn)入下一個(gè)游戲狀態(tài)。"""
if self.finish: # 如果按鍵或鼠標(biāo)點(diǎn)擊完成
game.next_state = self.next_state() # 將變量next_state中類的實(shí)例化,存入Game類進(jìn)行處理。
def paused_display(self, screen):
"""暫停時(shí)顯示的處理。"""
State.paused_display(self, screen) # 重載超類中的方法
font = pygame.font.SysFont('SimHei', config.getint('Screen', 'font_size')) # 設(shè)置使用系統(tǒng)字體(用于支持中文)
lines = self.text.strip().splitlines() # 獲取子類中設(shè)置的文字內(nèi)容并分行
height = len(lines) * font.get_linesize() # 計(jì)算文字高度
center, middle = screen.get_rect().center # 獲取屏幕中心坐標(biāo)值
top = middle - height // 2 # 計(jì)算顯示內(nèi)容中心點(diǎn)的y軸坐標(biāo)
if self.image: # 如果有圖片
image = pygame.image.load(self.image).convert_alpha() # 載入圖片
img_rect = image.get_rect() # 創(chuàng)建矩形
top += img_rect.height // 2 # 重新計(jì)算頂部y軸坐標(biāo)
if self.text: # 如果有文字
img_rect.midbottom = center, top - 20 # 設(shè)置圖片位置為中心且底邊與文字頂部間隔20像素。
else: # 否則
img_rect.center = center, middle # 設(shè)置圖片中心點(diǎn)為屏幕中心點(diǎn)
screen.blit(image, img_rect) # 屏幕填充圖片
antialias = True # 設(shè)置抗鋸齒(平滑文字)
black = 0, 0, 0 # 設(shè)置文字顏色
for line in lines:
text = font.render(line.strip(), antialias, black) # 創(chuàng)建單行文字對(duì)象
txt_rect = text.get_rect() # 創(chuàng)建矩形
txt_rect.midtop = center, top # 設(shè)置文字顯示位置
screen.blit(text, txt_rect) # 屏幕填充文字
top += font.get_linesize() # 逐行下移文字位置
pygame.display.flip() # 刷新屏幕顯示
四、Paused類的子類(StartUp、Info、LevelCleared、GameOver)
這幾個(gè)子類都比較簡(jiǎn)單,主要是定義暫停狀態(tài)下屏幕中顯示的內(nèi)容。
其中,略有不同的是LevelCleared類,在這個(gè)類中要進(jìn)行下一個(gè)關(guān)卡的實(shí)例化。
另外,為了能夠方便更換歡迎界面的方案,在配置文件(config.ini)中我們新增一項(xiàng)配置內(nèi)容。
示例代碼:
[Welcome]
skin = 1
各個(gè)Paused類的子類實(shí)現(xiàn),大家可以根據(jù)下方代碼中的注釋理解。
示例代碼:
class Info(Paused):
"""游戲信息。"""
next_state = Level # 將類存入變量,以便在Paused類中實(shí)例化。
text = '''控制移動(dòng)你的飛機(jī),
不要被敵機(jī)撞到它。'''
class StartUp(Paused):
"""進(jìn)入游戲。"""
next_state = Info # 將類存入變量,以便在Paused類中實(shí)例化。
if config.getint('Welcome', 'skin'): # 讀取配置文件中歡迎界面的方案設(shè)置
text = ''
image = config.get('Image', 'welcome')
else:
text = '老司機(jī)開(kāi)飛機(jī)'
image = config.get('Image', 'plane')
class LevelCleared(Paused):
"""游戲過(guò)關(guān)。"""
def __init__(self, number):
"""過(guò)關(guān)信息。"""
self.number = number # 獲取當(dāng)前關(guān)卡級(jí)別
self.text = '''恭喜闖過(guò)第 %d 關(guān),
點(diǎn)擊繼續(xù)下一關(guān)。''' % self.number
def next_state(self):
"""創(chuàng)建下一關(guān)卡。"""
return Level(self.number + 1) # 返回下移關(guān)卡的對(duì)象
class GameOver(Paused):
"""游戲結(jié)束。"""
next_state = Level # 將類存入變量,以便在Paused類中實(shí)例化。
text = '游戲結(jié)束!'
五、Game類
這個(gè)類負(fù)責(zé)處理游戲的整個(gè)運(yùn)行過(guò)程。
class Game:
"""負(fù)責(zé)主事件循環(huán)的游戲?qū)ο?#xff0c;完成在不同狀態(tài)間切換的任務(wù)。"""
def __init__(self):
"""初始化。"""
self.state = None # 初始化當(dāng)前狀態(tài)
self.next_state = StartUp() # 初始化下一個(gè)狀態(tài)為開(kāi)始游戲的狀態(tài)
def run(self):
"""運(yùn)行游戲。"""
pygame.init() # 游戲初始化
flag = 0 # 記錄是否全屏的標(biāo)志
if config.getint('Screen', 'full_screen'): # 如果配置文件中設(shè)置為全屏
flag = FULLSCREEN # 標(biāo)志設(shè)置為全屏
screen_size = (config.getint('Screen', 'width'), config.getint('Screen', 'height')) # 讀取配置文件中的屏幕尺寸設(shè)置
screen = pygame.display.set_mode(screen_size, flag) # 設(shè)置屏幕外觀模式
pygame.display.set_caption('老司機(jī)開(kāi)飛機(jī)') # 設(shè)置游戲窗口標(biāo)題(非全屏?xí)r顯示)
pygame.mouse.set_visible(False) # 隱藏鼠標(biāo)指針顯示
while True:
pygame.time.Clock().tick(200) # 設(shè)置每秒幀數(shù)
if self.state != self.next_state: # 如果有新的游戲狀態(tài)
self.state = self.next_state # 切換到新的狀態(tài)
self.state.paused_display(screen) # 屏幕中顯示暫停狀態(tài)的內(nèi)容(切換狀態(tài)會(huì)進(jìn)入暫停狀態(tài))
for event in pygame.event.get(): # 獲取事件
self.state.handle(event) # 處理事件
self.state.update(self) # 游戲?qū)ο蟮漠?dāng)前狀態(tài)內(nèi)容刷新
self.state.display(screen) # 屏幕中顯示刷新后的狀態(tài)內(nèi)容
到這里,我們就完成了這個(gè)項(xiàng)目所有代碼的編寫。
大家可以運(yùn)行程序,查看一下是否能夠正確執(zhí)行。
示例代碼:
if __name__ == '__main__':
game = Game()
game.run()
本節(jié)練習(xí)源代碼:【點(diǎn)此下載】
總結(jié)
以上是生活随笔為你收集整理的python游戏程序中游戏对象是什么_练习项目21:使用python制作游戏(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 佳禾智能是华为供应商吗 提供华为的耳机产
- 下一篇: 两分硬币多重