敌人跟随中间玩家

时间:2019-08-05 09:37:18

标签: python pygame

敌人在屏幕上方产生并试图跟随屏幕中间的玩家,但是当它靠近玩家时,游戏崩溃并显示错误,而不是游戏结束。

如何通过敌人类的update()方法而不是窗口的高度,宽度(而不是600325)传递玩家坐标。

我想让敌人跟随玩家,并在玩家外部随机位置附近而不是仅从屏幕上方生成敌人,以及如何随着分数的增加而增加敌人。

我得到的错误是:

dirvect.normalize()
ValueError: Can't normalize Vector of length Zero

以下代码属于敌人类别:

class Mob(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load('enemy.png').convert_alpha()
        self.image = pg.transform.smoothscale(pg.image.load('enemy.png'), (33, 33))
        self.image_orig = self.image.copy()
        self.radius = int(29 * .80 / 2)
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(width - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speed = 4
        self.rot = 0
        self.rot_speed = 5
        self.last_update = pg.time.get_ticks()

    def rotate(self):
        now = pg.time.get_ticks()
        if now - self.last_update > 50:
            self.last_update = now
            self.rot = (self.rot + self.rot_speed) % 360
            new_image = pg.transform.rotozoom(self.image_orig, self.rot, 1)
            old_center = self.rect.center
            self.image = new_image
            self.rect = self.image.get_rect()
            self.rect.center = old_center

    def update(self):
        self.rotate()
        dirvect = pg.math.Vector2(600 - self.rect.x,
                                  325 - self.rect.y)
        dirvect.normalize()
    # Move along this normalized vector towards the player at current speed.
        dirvect.scale_to_length(self.speed)
        self.rect.move_ip(dirvect)
        if self.rect.top > height + 10 or self.rect.left < -25 or self.rect.right > width + 20:
            self.rect.x = random.randrange(width - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speed = random.randrange(1, 4)

以下是添加敌人的方法:

    for i in range(5):
        m = Mob()
        all_sprites.add(m)
        mobs.add(m)
 score = 0

如果这有助于播放器类的代码:

class Rotator(pg.sprite.Sprite):
    def __init__(self, screen_rect):
        pg.sprite.Sprite.__init__(self)
        self.screen_rect = screen_rect
        self.master_image = pg.image.load('spaceship.png').convert_alpha()
        self.master_image = pg.transform.smoothscale(pg.image.load('spaceship.png'), (33, 33))
        self.radius = 12
        self.image = self.master_image.copy()
        self.rect = self.image.get_rect(center=[width / 2, height / 2])
        self.delay = 10
        self.timer = 0.0
        self.angle = 0
        self.distance = 0
        self.angle_offset = 0

    def get_angle(self):
        mouse = pg.mouse.get_pos()
        offset = (self.rect.centerx - mouse[0], self.rect.centery - mouse[1])
        self.angle = math.degrees(math.atan2(*offset)) - self.angle_offset
        old_center = self.rect.center
        self.image = pg.transform.rotozoom(self.master_image, self.angle, 1)
        self.rect = self.image.get_rect(center=old_center)
        self.distance = math.sqrt((offset[0] * offset[0]) + (offset[1] * offset[1]))

    def update(self):
        self.get_angle()
        self.display = 'angle:{:.2f} distance:{:.2f}'.format(self.angle, self.distance)
        self.dx = 1
        self.dy = 1
        self.rect.clamp_ip(self.screen_rect)

    def draw(self, surf):
        surf.blit(self.image, self.rect)

    def shoot(self, mousepos):
        dx = mousepos[0] - self.rect.centerx
        dy = mousepos[1] - self.rect.centery
        if abs(dx) > 0 or abs(dy) > 0:
            bullet = Bullet(self.rect.centerx, self.rect.centery, dx, dy)
            all_sprites.add(bullet)
            bullets.add(bullet)

1 个答案:

答案 0 :(得分:0)

此错误是引起原因的,因为dirvect的长度为零。请注意,Unit vector的长度为1,并且通过将矢量除以其长度来计算单位矢量。

在计算单位向量之前,请检查向量的长度。使用length_squared()来获得向量的平方Euclidean length,这比通过lenght()来获取长度要快,因为省去了昂贵的平方根运算:

if vectdirvect.length_squared() > 0:
    vectdirvect = vectdirvect.normalize() 

还要注意,normalize()用于计算单位向量,但不将结果存储到“自身”中,而是通过返回值返回结果。


使用scale_to_length()时也会发生类似的问题,因为scale_to_length()必须先计算单位向量,然后才能将向量缩放到给定的长度:

if dirvect.length_squared() > 0:
    dirvect.scale_to_length(self.speed)