BOSS瞄準了半天發射,可都被英雄躲過去了,心裡不爽,看到電商的廣告,感覺5G是個好東西,先搞個自動導航吧。
其實在上一篇中的millse類已經具有導航功能了,5G手機已經有了,差的是信号,那麼現在加入信号。
在 boss.py的fire_missle()函數的最前面,在發射飛彈前,先判斷是否已經有飛彈了,如果有了,那麼讓重新定位就行
for hero in herogroup:
hero_pos = vect(hero.rect.centerx, hero.rect.centery)
for gmissle in bossmisslegroup:
gmissle.set_target_coordinate(hero_pos)
這麼一來,螢幕上所有的飛彈就跟着英雄飛機的心髒走了。
不過跟蹤飛彈也想實作動态圖檔,pygame的圖檔旋轉功能有點麻煩,動态圖的旋轉就涉及到多張圖檔的旋轉,需要多張圖檔的原始圖。是以要建立一個類來實作。該類繼承至Missle,完整代碼如下
from setting import *
from animation import *
from missle import *
class GuidedMissle(Missle):
# class GuidedMissle(pygame.sprite.Sprite):
def __init__(self,group):
self._layer = 5
self.groups = allgroup,group
pygame.sprite.Sprite.__init__(self,self.groups)
self.animation = Animation()
self.images = self.animation.load_image('images/missle/gmissle.png',
60, 93, 1, 2)
#必不可少的兩條代碼
self.image = self.images[0].convert_alpha()
self.rect = self.image.get_rect()
#初設速度、角度
self.x_speed = 0.00
self.y_speed = 2.00
self.speed = 5
self.damage = 3
self.angle = 0
# 初始化階段指派,以後這個original圖檔坐标、方向都是不變的,self.image是變化的。
# sprite 顯示的是self.image
self.original = self.image.convert_alpha()
def update(self):
"""更新飛彈位置
旋轉圖像,計算x,y方向速度
計算更新後的坐标點
超出螢幕自動從所有精靈組删除
"""
self.original = self.animation.get_current_image()
#記錄原有中心,複雜轉換的圖像,轉換後中心為原中心
original_center = self.rect.center
#rotate後,original還是保持不變的,包括角度和坐标點,變的是self.image
#self.image得到的是轉變後的圖像和圖像的坐标,該坐标是(0,0,width,height)轉角度angle後的坐标
#不是目前位置的坐标。是以還得給轉變後的圖像的坐标重新指派。
self.image = pygame.transform.rotate(self.original, 90 - self.angle).convert_alpha()
self.rect.center = original_center
self.mask = pygame.mask.from_surface(self.image)
#用臨時變量來進行degree和 radian 之間的轉換
angle = self.angle * math.pi / 180
self.x_speed = self.speed * math.cos(angle)
self.y_speed = self.speed * math.sin(angle)
self.rect.x += self.x_speed
self.rect.y += self.y_speed
#當目标在飛彈到達之前沒了,改何去何從??
#在主函數裡,尋找下一個目标,如果沒目标,往太空飛,飛出螢幕後自毀
if not self.rect.colliderect(SCENERECT):
self.kill()
在boss.py 裡添加fire_guided_missle()函數
def fire_guided_missile(self,interval = 2000):
self.gmissleinterval = interval
for hero in herogroup:
hero_pos = vect(hero.rect.centerx, hero.rect.centery)
for gmissle in bossGMgroup:
gmissle.set_target_coordinate(hero_pos)
current_time = pygame.time.get_ticks()
pass_time = current_time - self.gmissle_start_time
if pass_time < self.gmissleinterval:
return
self.gmissle_start_time = current_time
gmissle = GuidedMissle(bossGMgroup)
boss_fire_pos = vect(self.rect.midbottom[0],
self.rect.midbottom[1] - 100)
pos_x = boss_fire_pos.x - gmissle.rect.width // 2
pos_y = boss_fire_pos.y
gmissle.set_pos(pos_x, pos_y)
gmissle.set_target_coordinate(hero_pos)
在update()函數裡發射。
self.fire_missle()
在setting.py 添加
bossGMgroup = pygame.sprite.Group()
boss.py完整代碼如下:
from setting import *
from animation import *
from lifebar import *
from bossbullet import *
from missle import *
from guidedmissle import *
class BossPlane(pygame.sprite.Sprite):
def __init__(self):
self._layer = 2
self.groups = allgroup, bossgroup
pygame.sprite.Sprite.__init__(self, self.groups)
#設定飛機動态圖像
self.animation = Animation()
self.images = self.animation.load_images('images/boss/boss0_', 0, 4,
'.png')
self.image = self.images[1]
self.mask = pygame.mask.from_surface(self.image)
# 飛機矩形
self.rect = self.image.get_rect()
self.bullet_speed = 4
self.x_speed = 2
self.y_speed = 2
#預設移動方式
self.motion_type = 1
# 飛機子彈發射間隔 毫秒
self.firetype = 0
self.bullettype = 0
self.bulletinterval = 200
self.missleinterval = 500
self.gmissleinterval = 2000
# 飛機子彈發射目前時間
self.bullet_start_time = pygame.time.get_ticks()
self.missle_start_time = pygame.time.get_ticks()
self.gmissle_start_time = pygame.time.get_ticks()
self.HP = 500
self.HPFULL = 500
lifebar = Lifebar(self)
def update(self):
# self.HP -= 1
if self.HP <= 0:
self.kill()
#更新飛機目前圖像
if random.randint(0, 50) == 1:
self.motion_type = random.randint(0, 1)
self.x_speed = random.randint(-2, 3)
self.y_speed = random.randint(-3, 2)
self.image = self.animation.get_current_image()
if self.motion_type == 0:
if self.rect.x + self.rect.width > SCENEWIDTH or self.rect.x < 0:
self.x_speed = -self.x_speed
# self.rect.y += self.y_speed
self.rect.x += self.x_speed
elif self.motion_type == 1:
if self.rect.x + self.rect.width > SCENEWIDTH or self.rect.x < 0:
self.x_speed = -self.x_speed
if self.rect.y + self.rect.height > SCENEHEIGHT // 1.3 or self.rect.y < 0:
self.y_speed = -self.y_speed
self.rect.x += self.x_speed
self.rect.y += self.y_speed
self.fire_bullet(
random.randint(0, 8), random.randint(0, 12),
random.randint(500, 2000))
self.fire_missle()
self.fire_guided_missile()
def fire_guided_missile(self, interval=2000):
self.gmissleinterval = interval
for hero in herogroup:
hero_pos = vect(hero.rect.centerx, hero.rect.centery)
for gmissle in bossGMgroup:
gmissle.set_target_coordinate(hero_pos)
current_time = pygame.time.get_ticks()
pass_time = current_time - self.gmissle_start_time
if pass_time < self.gmissleinterval:
return
self.gmissle_start_time = current_time
gmissle = GuidedMissle(bossGMgroup)
boss_fire_pos = vect(self.rect.midbottom[0],
self.rect.midbottom[1] - 100)
pos_x = boss_fire_pos.x - gmissle.rect.width // 2
pos_y = boss_fire_pos.y
gmissle.set_pos(pos_x, pos_y)
gmissle.set_target_coordinate(hero_pos)
def fire_missle(self, interval=500):
self.missleinterval = interval
current_time = pygame.time.get_ticks()
pass_time = current_time - self.missle_start_time
if pass_time < self.missleinterval:
return
self.missle_start_time = current_time
for hero in herogroup:
missle = Missle(bossmisslegroup)
hero_pos = vect(hero.rect.centerx, hero.rect.centery)
boss_fire_pos = vect(self.rect.midbottom[0],
self.rect.midbottom[1] - 100)
pos_x = boss_fire_pos.x - missle.rect.width // 2
pos_y = boss_fire_pos.y
missle.set_pos(pos_x, pos_y)
missle.set_target_coordinate(hero_pos)
def fire_bullet(self, firetype=0, bullettype=0, interval=500):
#時間判斷,不到發射間隔,不射
self.bulletinterval = interval
current_time = pygame.time.get_ticks()
pass_time = current_time - self.bullet_start_time
if pass_time < self.bulletinterval:
return
self.bullet_start_time = current_time
self.firetype = firetype
self.bullettype = bullettype
#boss 子彈的發射位置當然是下部中心
boss_fire_pos = vect(self.rect.midbottom[0],
self.rect.midbottom[1] - 100)
#單顆子彈
if firetype == 0:
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x - bullet.rect.width // 2
pos_y = boss_fire_pos.y
bullet.set_pos(pos_x, pos_y)
# 兩個
elif firetype == 1:
interval = -self.rect.width // 4
for v in range(0, 2):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x - bullet.rect.width // 2 + interval
pos_y = boss_fire_pos.y
bullet.set_pos(pos_x, pos_y)
interval = self.rect.width // 4
#三個
elif firetype == 2:
interval = -self.rect.width // 4
for v in range(0, 3):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x - bullet.rect.width // 2 + interval
pos_y = boss_fire_pos.y
bullet.set_pos(pos_x, pos_y)
interval += self.rect.width // 4
# 向下30度角
elif firetype == 3:
for angle in range(75, 106, 10):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x
pos_y = boss_fire_pos.y
bullet.set_speed(self.bullet_speed, angle)
bullet.set_pos(pos_x, pos_y)
#向下 60度角
elif firetype == 4:
for angle in range(60, 121, 10):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x
pos_y = boss_fire_pos.y
bullet.set_speed(self.bullet_speed, angle)
bullet.set_pos(pos_x, pos_y)
#向下 90度角
elif firetype == 5:
for angle in range(45, 136, 10):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x
pos_y = boss_fire_pos.y
bullet.set_speed(self.bullet_speed, angle)
bullet.set_pos(pos_x, pos_y)
#向下 180度
elif firetype == 6:
for angle in range(0, 181, 10):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x
pos_y = boss_fire_pos.y
bullet.set_speed(self.bullet_speed, angle)
bullet.set_pos(pos_x, pos_y)
#360度
elif firetype == 7:
for angle in range(0, 360, 10):
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x
pos_y = boss_fire_pos.y
bullet.set_speed(self.bullet_speed, angle)
bullet.set_pos(pos_x, pos_y)
#一頓亂射
else:
n = random.randint(10, 50)
for v in range(0, n):
if random.randint(0, 4) == 1:
bullet = BossBullet()
bullet.set_bullet_type(bullettype)
pos_x = boss_fire_pos.x - bullet.rect.width // 2
pos_y = boss_fire_pos.y
bullet.set_pos(pos_x + random.randint(-200, 200),
pos_y + random.randint(-100, 100))
運作效果如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csUTRU1EeJhlWzh3VhhGaywEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcucTMzAzNxIjMxADNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)