1

我正在开发一个基本的 pygame,但我不确定我想把它带到哪里。所以到目前为止,我只研究基本的机制。

我遇到的问题是我需要让敌人的精灵向玩家精灵移动。我已经弄清楚了基本的矢量,但是由于精灵沿着矢量移动,它们越接近目标也会减慢速度。

这是我的代码的片段。

#Enemy Mechanics
for enemy in enemy_list:
    pygame.draw.rect(screen, green, (enemy.rect.x, enemy.rect.y-5, enemy.Health/4, 3), 0)
    pygame.draw.rect(screen, green, (enemy.rect.x, enemy.rect.y-5, 25, 3), 1)

    ppos = pPlayer.rect.x, pPlayer.rect.y
    epos = enemy.rect.x, enemy.rect.y
    etarget = epos[1] - ppos[1], epos[0] - ppos[0]

    enemy.rect.x -= etarget[1]/20 #This is the problem
    enemy.rect.y -= etarget[0]/20


#Bullet Mechanics
for bullet in bullet_list:
    mpos = pygame.mouse.get_pos()
    bpos = bullet.rect.x, bullet.rect.y
    target = bpos[1] - mpos[1], bpos[0] - mpos[0]
    dist = math.sqrt(((bpos[0] - mpos[0])**2) + ((bpos[1] - mpos[1])**2))

    bullet.rect.x -= target[1]/20
    bullet.rect.y -= target[0]/20

    if dist < 30:
        bExplode(bullet.rect.x, bullet.rect.y)
        blist.remove(bullet)
        bullet.kill()

    enemy_hit_list = (pygame.sprite.spritecollide(bullet, enemy_list, False))
    for enemy in enemy_hit_list:
        enemy.Health -= 25
        print(enemy.Health)
        if enemy.Health <= 0:
            enemy_list.remove(enemy)
            all_sprites_list.remove(enemy)

        bullet_list.remove(bullet)
        all_sprites_list.remove(bullet)
        blist.remove(bullet)

如您所见,我一直将向量除以 20,因为它可以将它们减慢到合理的速度,但它们也会在达到目标之前停止。我需要帮助使精灵以恒定的速度向玩家移动。

4

1 回答 1

1

您的代码意味着敌人总是移动到目标的 1/20。您希望他们向同一方向移动 1 个固定大小的步长。

这里的答案是对你的向量进行归一化——也就是说,使用与距离向量方向相同的单位向量,而不是直接使用距离向量。

简单的方法就是将向量除以其长度。为了得到向量的长度,这就是勾股定理

所以:

def vector_length(x, y):
    return math.sqrt(x*x + y*y)

def normalize_vector(x, y):
    norm = vector_length(x, y)
    return x/norm, y/norm

target = normalize_vector(bpos[1] - mpos[1], bpos[0] - mpos[0])

这使得子弹以每时间单位 1 个空间单位(例如,每帧像素)移动。如果您希望它们走得更快或更慢,只需以相同的单位定义子弹速度并乘以它:

bullet.rect.x -= target[1] * BULLET_SPEED 
bullet.rect.y -= target[0] * BULLET_SPEED 

事实上,你已经在做大部分事情了,只是没有使用它:

dist = math.sqrt(((bpos[0] - mpos[0])**2) + ((bpos[1] - mpos[1])**2))

因此,如果您发现它更清楚,只需将接下来的两行更改为:

bullet.rect.x -= target[1] / dist * BULLET_SPEED
bullet.rect.y -= target[0] / dist * BULLET_SPEED
于 2013-06-11T19:18:32.143 回答