《零基礎入門學習Python》筆記 第095講:Pygame:飛機大戰6
今天繼續飛機大戰的開發,遊戲每30秒就隨機下放一個補給包,可能是超級子彈或者全屏炸彈。
補給包有自己的圖片(如下圖),也有自己的運行軌跡(由上而下)
因此,我們可以單獨寫一個模塊來實現:命名為supply
-
#supply.py
-
import pygame
-
from random import *
-
-
class Bullet_Supply(pygame.sprite.Sprite):
-
def __init__(self, bg_size):
-
pygame.sprite.Sprite.__init__(self)
-
-
self.image = pygame.image.load("images/bullet_supply.png").convert_alpha()
-
self.rect = self.image.get_rect()
-
self.width, self.height = bg_size[0], bg_size[1]
-
self.rect.left, self.rect.bottom = \
-
randint(0, self.width - self.rect.width), -100 #水平方向随机,垂直方向-100
-
self.speed = 5
-
self.active = False
-
self.mask = pygame.mask.from_surface(self.image)
-
-
def move(self):
-
if self.rect.top < self.height:
-
self.rect.top += self.speed
-
else:
-
self.active = False
-
-
def reset(self):
-
self.active = True
-
self.rect.left, self.rect.bottom = \
-
randint(0, self.width - self.rect.width), -100
-
-
class Bomb_Supply(pygame.sprite.Sprite):
-
def __init__(self, bg_size):
-
pygame.sprite.Sprite.__init__(self)
-
-
self.image = pygame.image.load("images/bomb_supply.png").convert_alpha()
-
self.rect = self.image.get_rect()
-
self.width, self.height = bg_size[0], bg_size[1]
-
self.rect.left, self.rect.bottom = \
-
randint(0, self.width - self.rect.width), -100
-
self.speed = 5
-
self.active = False
-
self.mask = pygame.mask.from_surface(self.image)
-
-
def move(self):
-
if self.rect.top < self.height:
-
self.rect.top += self.speed
-
else:
-
self.active = False
-
-
def reset(self):
-
self.active = True
-
self.rect.left, self.rect.bottom = \
-
randint(0, self.width - self.rect.width), -100
接下來我們在main 模塊中實現這個補給包:
實例化補給包並這只補給包發放定時器,定時器每30秒觸發一次。
-
# 每30秒发放一个补给包
-
bullet_supply = supply.Bullet_Supply(bg_size)
-
bomb_supply = supply.Bomb_Supply(bg_size)
-
SUPPLY_TIME = USEREVENT
-
pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
-
#响应补给包事件
-
elif event.type == SUPPLY_TIME:
-
supply_sound.play()
-
if choice([True, False]):
-
bomb_supply.reset()
-
else:
-
bullet_supply.reset()
-
# 绘制全屏炸弹补给并检测是否获得
-
if bomb_supply.active:
-
bomb_supply.move()
-
screen.blit(bomb_supply.image, bomb_supply.rect)
-
if pygame.sprite.collide_mask(bomb_supply, me):
-
get_bomb_sound.play()
-
if bomb_num < 3:
-
bomb_num += 1
-
bomb_supply.active = False
-
-
# 绘制超级子弹补给并检测是否获得
-
if bullet_supply.active:
-
bullet_supply.move()
-
screen.blit(bullet_supply.image, bullet_supply.rect)
-
if pygame.sprite.collide_mask(bullet_supply, me):
-
get_bullet_sound.play()
-
#发射超级子弹
-
bullet_supply.active = False
接下來有個細節問題,就是遊戲運行起來之後,當我們按暫停時,背景音樂還存在,而且還會聽到補給發放的聲音,因為補給發放是在事件觸發那裡寫的,而暫停管的是下面的主邏輯部分,這就導致了一個問題,因為用戶暫停,是希望遊戲真正的安靜下來。
-
elif event.type == MOUSEBUTTONDOWN:
-
if event.button == 1 and paused_rect.collidepoint(event.pos):
-
paused = not paused
-
if paused:
-
pygame.time.set_timer(SUPPLY_TIME, 0)
-
pygame.mixer.music.pause()
-
pygame.mixer.pause()
-
else:
-
pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
-
pygame.mixer.music.unpause()
-
pygame.mixer.unpause()
好了,接下來我們來講講超級子彈,當我們接收到超級子彈補給的時候,子彈由原來的單髮變成了雙發,子彈的速度相對也會提高一些。
我們先在bullet 模塊中添加一個Bullet2 類
-
class Bullet2(pygame.sprite.Sprite):
-
def __init__(self, position):
-
pygame.sprite.Sprite.__init__(self)
-
-
self.image = pygame.image.load("images/bullet2.png").convert_alpha()
-
self.rect = self.image.get_rect()
-
self.rect.left, self.rect.top = position
-
self.speed = 14
-
self.active = False
-
self.mask = pygame.mask.from_surface(self.image)
-
-
def move(self):
-
self.rect.top -= self.speed
-
-
if self.rect.top < 0:
-
self.active = False
-
-
def reset(self, position):
-
self.rect.left, self.rect.top = position
-
self.active = True
超級子彈的使用時長為18秒,過了這個時間,就自動變為普通子彈。
因此我們需要一個超級子彈的定時器,另外,我們還需要一個變量來表示子彈的類型。
-
# 超级子弹定时器
-
DOUBLE_BULLET_TIME = USEREVENT + 1
-
-
# 标志是否使用超级子弹
-
is_double_bullet = False
然後生成超級子彈
-
# 生成超级子弹
-
bullet2 = []
-
bullet2_index = 0
-
BULLET2_NUM = 8
-
for i in range(BULLET2_NUM//2):
-
bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery)))
-
bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery)))
然後響應事件
-
#响应超级子弹事件
-
elif event.type == DOUBLE_BULLET_TIME:
-
is_double_bullet = False
-
pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)
-
# 绘制超级子弹补给并检测是否获得
-
if bullet_supply.active:
-
bullet_supply.move()
-
screen.blit(bullet_supply.image, bullet_supply.rect)
-
if pygame.sprite.collide_mask(bullet_supply, me):
-
get_bullet_sound.play()
-
#发射超级子弹18秒
-
is_double_bullet = True
-
pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
-
bullet_supply.active = False
然後修改發射子彈部分
-
# 发射子弹
-
if not(delay % 10):
-
bullet_sound.play()
-
if is_double_bullet:
-
bullets = bullet2
-
bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))
-
bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery))
-
bullet2_index = (bullet2_index + 2) % BULLET2_NUM
-
else:
-
bullets = bullet1
-
bullets[bullet1_index].reset(me.rect.midtop)
-
bullet1_index = (bullet1_index + 1) % BULLET1_NUM
0 留言:
發佈留言