Pygame三角学:跟斜边?

zzo*_*oop 2 python pygame trigonometry

Enemy班上有一个叫做的方法huntPlayer.它需要一个玩家对象p.这里是:

def huntPlayer(self, p):   
  if self.dist2p < 200:
    self.hunting = True
    if p.x > self.rect.x:
      self.rect.x += self.speed #this is a constant at value 1
    elif p.x < self.rect.x:
      self.rect.x -= self.speed
    else:
      self.rect.x += 0
    if p.y > self.rect.y:
      self.rect.y += self.speed
    elif p.y < self.rect.y:
      self.rect.y -= self.speed 
    else:
      self.rect.y += 0
  else:
    self.rect.x += 0
    self.rect.y += 0
Run Code Online (Sandbox Code Playgroud)

敌人随机放置在一个2d俯卧平原周围,他们随机漫游这个平原.我已经计算出这是最短的距离到播放器=斜边Enemy.dist2p-当dist2p值<200的敌人将朝向玩家移动,p.xp.y分别.

我上面的解决方案很粗糙,因此我的问题是敌人在x或y轴上同样移动1个位置,导致每个轴的对角线移动,然后沿着轴滑动直到它到达玩家.(播放器位于中心屏幕附近的固定位置.)

你能帮助我修复huntPlayer方法/算法,让敌人跟随玩家的斜边路径,而不是x/y轴的最快路径吗?

编辑:如果您需要我可能遗漏的任何进一步信息,请告诉我.

Ted*_*man 6

在斜边上移动很可能要求你的对象在y轴或x轴上每帧移动少于一个像素,并且因为rects只能保持整数,所以你需要一个新的属性position,它包含浮点精度中精灵的位置.您可以使用pygame.math.Vector2有用的方法创建向量,例如normalize()添加,减去,乘以其他向量等.

假设您已经创建了一个属性self.position = pygame.math.Vector2(0, 0)(或者您希望它开始的任何位置),您可以执行以下操作:

def hunt_player(self, player):
    player_position = pygame.math.Vector2(player.rect.topleft)
    direction = player_position - self.position
    velocity = direction.normalize() * self.speed

    self.position += velocity
    self.rect.topleft = self.position
Run Code Online (Sandbox Code Playgroud)

通过用敌人的位置减去玩家的位置,你将获得一个从敌人指向玩家的向量.如果我们想将方向向量添加到我们的位置,我们会立即传送给玩家.相反,我们将矢量标准化(使其长度为1像素)并乘以我们的速度属性.新创建的矢量将是一个向量,指向具有我们速度长度的玩家.

完整的例子

import pygame
pygame.init()


SIZE = WIDTH, HEIGHT = 720, 480
FPS = 60
BACKGROUND_COLOR = pygame.Color('white')

screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()


class Hunter(pygame.sprite.Sprite):

    def __init__(self, position):
        super(Hunter, self).__init__()

        self.image = pygame.Surface((32, 32))
        self.image.fill(pygame.Color('red'))
        self.rect = self.image.get_rect(topleft=position)
        self.position = pygame.math.Vector2(position)
        self.speed = 2

    def hunt_player(self, player):
        player_position = player.rect.topleft
        direction = player_position - self.position
        velocity = direction.normalize() * self.speed

        self.position += velocity
        self.rect.topleft = self.position

    def update(self, player):
        self.hunt_player(player)


class Player(pygame.sprite.Sprite):

    def __init__(self, position):
        super(Player, self).__init__()

        self.image = pygame.Surface((32, 32))
        self.image.fill(pygame.Color('blue'))
        self.rect = self.image.get_rect(topleft=position)

        self.position = pygame.math.Vector2(position)
        self.velocity = pygame.math.Vector2(0, 0)
        self.speed = 3

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.velocity.x = -self.speed
        elif keys[pygame.K_RIGHT]:
            self.velocity.x = self.speed
        else:
            self.velocity.x = 0

        if keys[pygame.K_UP]:
            self.velocity.y = -self.speed
        elif keys[pygame.K_DOWN]:
            self.velocity.y = self.speed
        else:
            self.velocity.y = 0

        self.position += self.velocity
        self.rect.topleft = self.position

player = Player(position=(350, 220))
monster = Hunter(position=(680, 400))
running = True
while running:

    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    player.update()
    monster.update(player)

    screen.fill(BACKGROUND_COLOR)
    screen.blit(player.image, player.rect)
    screen.blit(monster.image, monster.rect)

    pygame.display.update()
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述