昨天咱們已經實現了這個遊戲的三個基本類。app
可是如今它仍是沒辦法作成一個適合玩的遊戲,畢竟只有一架敵機的遊戲是很乏味的。因此,咱們須要好多子彈,也須要好多敵機。dom
因此,咱們要建立list,這個list存放Bullet或者Enemy的實例。函數
以Bullet爲例:ui
bullet = [] #建立子彈 for i in range(6): bullet.append(Bullet()) ... for b in bullet:#移動子彈 b.move(time_passed_second) ... for b in bullet:#顯示子彈 screen.blit(b.image, (b.x, b.y))
咱們能夠用這樣的代碼替換咱們原來建立子彈,移動子彈和顯示子彈的部分。可是實際運行結果卻並無變化。這是爲何?spa
由於一個list的子彈都按照了一樣的方法建立和發射了,全部的子彈在同一時間發射了出去,同時到達了屏幕上方,而後又同時發射。這樣的效果和發射一發子彈是沒有區別的。因此咱們要讓它按照必定的時間間隔,一個個地發射。3d
另外,若是到了屏幕頂端就回頭了,從新發射的子彈和按時發射的子彈混在了一塊兒,打亂了發射節奏,因此子彈回收的方法也要更改。咱們能夠選擇每發子彈只寫它的發射,不寫它的回收,可是這樣每發射一發子彈就會建立一個空間,讀取一次圖片,這樣會消耗內存資源,通常都應該避免。rest
那麼咱們必須解決兩個問題,一個是定時發射,一個是回收子彈。code
Python有專門的time模塊,可是,在遊戲中,咱們原本就有幀率固定的循環,只要用一個計數器來計數,每隔多少個循環出發一次,就能夠實現定時效果。blog
好比說,咱們定義一個子彈發射的間隔interval_bullet,讓它遞增或者遞減,到達某個數後,就重置間隔,而且運行特定的程序,就可使子彈定時發射。隊列
若是要重複利用子彈,咱們可讓子彈自己多一個屬性,來代表這個子彈是否應該被激活,只有它是激活狀態,咱們去處理它的運動和顯示。
子彈自己是能夠重複利用的,咱們用一個循環隊列的結構來處理子彈的利用。
依照這樣的方法,咱們能夠修改Bullet類:
class Bullet(object): def __init__(self): self.x = 0 self.y = -100 self.speed = 600 self.image = pygame.image.load(bullet_image_filename).convert_alpha() self.active = False def move(self, passed_time_second): if self.y < 0: self.active = False else: self.y -= self.speed*passed_time_second def restart(self): self.active = True mouseX, mouseY = pygame.mouse.get_pos() self.x = mouseX - self.image.get_width()/2 self.y = mouseY - self.image.get_width()/2
添加了一個從新激活該子彈的方法restart(),還添加了一個數據屬性active來標記子彈自己是否被激活。而後,咱們把添加子彈,移動子彈,顯示子彈部分的代碼改爲這樣:
bullet = [] for i in range(6):#子彈總數量 bullet.append(Bullet()) interval_bullet = 25 #發射子彈的幀數間隔 index_bullet = 0 #初始化子彈座標 ... interval_bullet -= 1 if interval_bullet <= 0: interval_bullet = 25 bullet[index_bullet].restart() index_bullet = (index_bullet + 1) % 6 for b in bullet: if b.active: b.move(time_passed_second)#移動子彈 screen.blit(b.image, (b.x, b.y))#顯示子彈
結果就是這樣了:
子彈完成了之後,飛機還會遠麼?
你們能夠本身想想敵機應該怎麼去寫,敵機不一樣的是,先後的間隔應該有更多的隨機性。
我這裏就不給出一步步的指南了,把本身實現的代碼整個貼上來,也許你們有更好的控制方式,能夠一塊兒交流一下:
# -*- coding: utf8 -*- background_image_filename = 'background.png' mouse_image_filename = 'hero.png' bullet_image_filename = 'bullet.png' enemy_image_filename = 'enemy.png' #指定圖像文件名稱 import pygame #導入pygame庫 from sys import exit #向sys模塊借一個exit函數用來退出程序 from random import randint #引入隨機數 #定義一個Bullet類,封裝子彈的數據和方法 class Bullet(object): def __init__(self): self.x = 0 self.y = -100 self.speed = 600 self.image = pygame.image.load(bullet_image_filename).convert_alpha() self.active = False def move(self, passed_time_second): if self.y < 0: self.active = False else: self.y -= self.speed*passed_time_second def restart(self): self.active = True mouseX, mouseY = pygame.mouse.get_pos() self.x = mouseX - self.image.get_width()/2 self.y = mouseY - self.image.get_width()/2 class Enemy(object):#定義一個Enemy類,封裝敵機的數據和方法 def restart(self): self.x = randint(-30,400) self.y = randint(-100, -50) self.speed = randint(100,400) self.active = True def __init__(self): self.restart() self.active = False self.image = pygame.image.load(enemy_image_filename).convert_alpha() def move(self, passed_time_second): if self.y < 650: self.y += self.speed*passed_time_second else: self.active = False pygame.init() #初始化pygame,爲使用硬件作準備 screen = pygame.display.set_mode((480, 650), 0, 32) #建立了一個窗口 pygame.display.set_caption("PlaneFight!") #設置窗口標題 pygame.mouse.set_visible(False) background = pygame.image.load(background_image_filename).convert() mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha() #加載並轉換圖像 bullet = [] for i in range(6):#子彈總數量 bullet.append(Bullet()) interval_bullet = 25 #發射子彈的幀數間隔 index_bullet = 0 #初始化子彈座標 enemy = [] for i in range(10):#敵機總數量 enemy.append(Enemy()) interval_enemy = 100 #敵機出現的間隔 index_enemy = 0 #初始化敵機座標 clock = pygame.time.Clock() while True: #遊戲主循環 for event in pygame.event.get(): if event.type == pygame.QUIT: #接收到退出事件後退出程序 pygame.quit() exit() time_passed = clock.tick(100) time_passed_second = time_passed/1000.0 screen.blit(background, (0,0)) #將背景圖畫上去 x, y = pygame.mouse.get_pos() #得到鼠標位置 interval_bullet -= 1 if interval_bullet <= 0: interval_bullet = 25 bullet[index_bullet].restart()#重置子彈 index_bullet = (index_bullet + 1) % 6 #循環遞增 for b in bullet: if b.active: b.move(time_passed_second)#移動子彈 screen.blit(b.image, (b.x, b.y))#顯示子彈 interval_enemy -= 1 if interval_enemy <= 0: interval_enemy = randint(30,100) enemy[index_enemy].restart() #重置飛機 index_enemy = (index_enemy + 1) % 10 #循環遞增 for e in enemy: if e.active: e.move(time_passed_second) #移動敵機 screen.blit(e.image, (e.x, e.y)) #顯示敵機 x-= mouse_cursor.get_width() / 2 y-= mouse_cursor.get_height() / 2 #計算光標的左上角位置 #screen.blit(bullet.image, (bullet.x, bullet.y)) screen.blit(mouse_cursor, (x, y)) #把各個元素畫上去 pygame.display.update() #刷新一下畫面