pygame飞机大战用精灵组(sprite)的层(layer)编写(十一)BOSS觉得都5G时代了,自动导航不能少。

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

运行效果如下:

猜你喜欢

转载自blog.csdn.net/hailler1119/article/details/88957528
今日推荐