国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

2015/11/6用Python寫游戲,pygame入門(6):控制大量的對象

2019-11-14 16:55:31
字體:
來源:轉載
供稿:網友

昨天我們已經實現了這個游戲的三個基本類。

但是現在它還是沒辦法做成一個適合玩的游戲,畢竟只有一架敵機的游戲是很乏味的。所以,我們需要好多子彈,也需要好多敵機。

所以,我們要創建list,這個list存放Bullet或者Enemy的實例。

以Bullet為例:

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))

我們可以用這樣的代碼替換我們原來創建子彈,移動子彈和顯示子彈的部分。但是實際運行結果卻并沒有變化。這是為什么?

因為一個list的子彈都按照了同樣的方法創建和發射了,所有的子彈在同一時間發射了出去,同時到達了屏幕上方,然后又同時發射。這樣的效果和發射一發子彈是沒有區別的。所以我們要讓它按照一定的時間間隔,一個個地發射。

另外,如果到了屏幕頂端就回頭了,重新發射的子彈和按時發射的子彈混在了一起,打亂了發射節奏,所以子彈回收的方法也要更改。我們可以選擇每發子彈只寫它的發射,不寫它的回收,但是這樣每發射一發子彈就會創建一個空間,讀取一次圖片,這樣會消耗內存資源,一般都應該避免。

那么我們必須解決兩個問題,一個是定時發射,一個是回收子彈。


 

Python有專門的time模塊,但是,在游戲中,我們本來就有幀率固定的循環,只要用一個計數器來計數,每隔多少個循環出發一次,就可以實現定時效果。

比如說,我們定義一個子彈發射的間隔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()/2class 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 = Falsepygame.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()    #刷新一下畫面


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 滁州市| 毕节市| 铜山县| 讷河市| 亳州市| 射阳县| 拜泉县| 营山县| 德州市| 雷波县| 鄂托克前旗| 栾川县| 汝城县| 汝南县| 津市市| 乐陵市| 额济纳旗| 和政县| 宜宾市| 汽车| 望谟县| 徐州市| 浮梁县| 岫岩| 西安市| 阜南县| 宜兴市| 五原县| 青岛市| 临海市| 柞水县| 盐边县| 德化县| 赤峰市| 东乌| 方山县| 乌拉特前旗| 靖江市| 抚远县| 石河子市| 休宁县|