[英]How to make an enemy follow the player in pygame?
我制作了游戏的一部分。 它运行良好,但我想在我的游戏中添加敌人。 到目前为止,我在 pygame 精灵中添加了敌人的图像。
但是如何让敌人跟随玩家呢? 我试过这样做,但它只是让敌人的形象直接出现在玩家面前:
def moveEnemy(self):
enemies.rect.x = player.rect.x
enemies.rect.y = player.rect.y
all_sprites_list.add(enemies)
enemies_list.add(enemies)
我认为这会使敌人的形象跟随玩家。 相反,它只是与玩家的图像重叠。
我虽然阅读了许多 pygame 精灵示例,但示例中说用敌人.rect.x enemies.rect.x = -5
或周围的东西替换敌人.rect.x enemies.rect.x = player.rect.x
player.rect.x。 我也试过这个,但它只是向上移动图像而不是跟随玩家。
我必须制定一个方程式吗? 如果是这样我不知道该怎么做。
如何让敌人移动,同时让它跟随玩家? 有人可以帮我解决这个问题吗?
任何帮助,将不胜感激。
你需要通过改变敌人的位置来减少敌人和玩家之间的距离。 这可以通过找到它们位置之间的差异,然后使用该向量计算归一化(单位长度)方向向量来完成。 这样,通过将敌人的速度乘以方向向量来改变敌人的位置。
一种方法是向Enemy
类添加如下所示的方法。 数学运算可以使用内置的math
模块或pygame.math
模块来完成。 后者还支持 2D Vector2
类,因此实际使用它可能会更好。
import math
import pygame
from pygame.locals import *
class Enemy(object):
...
def move_towards_player(self, player):
# Find direction vector (dx, dy) between enemy and player.
dx, dy = player.rect.x - self.rect.x, player.rect.y - self.rect.y
dist = math.hypot(dx, dy)
dx, dy = dx / dist, dy / dist # Normalize.
# Move along this normalized vector towards the player at current speed.
self.rect.x += dx * self.speed
self.rect.y += dy * self.speed
# Same thing using only pygame utilities
def move_towards_player2(self, player):
# Find direction vector (dx, dy) between enemy and player.
dirvect = pygame.math.Vector2(player.rect.x - self.rect.x,
player.rect.y - 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)
您将需要添加检查以确定敌方对象是否会越过,从而在玩家移动这个距离时击中沿途的玩家,并做出相应的反应。 提示:只要移动的量——速度矢量的长度,即物体的速度——大于或等于它们之间的距离,就会发生碰撞。
在高层次上,您需要计算从敌人到玩家的向量。 方向向量的x
和y
分量如下所示:
enemies.rect.x - player.rect.x
enemies.rect.y - player.rect.y
然后将方向的倍数添加到敌人位置,使其向玩家移动。
但是:您会注意到,当玩家和敌人相距较远时,该向量的幅度会很大,而当他们靠得较近时,幅度会很小。 因此,为了避免敌人以超快的速度移动,您可以将方向向量归一化并乘以速度s
以保持控制。
在这里, px
和py
是敌人跟随/追逐的对象的位置(全局)。
class Enemy(object):
def __init__(self,x,y): # initial position
self.x = x
self.y = y
def move(self, speed=5): # chase movement
# Movement along x direction
if self.x > px:
self.x -= speed
elif self.x < px:
self.x += speed
# Movement along y direction
if self.y < py:
self.y += speed
elif self.y > py:
self.y -= speed
如果需要,您也可以自定义沿 x 和 y 方向的速度。
一个非常简单的方法是
if x_player > x_enemy:
x_enemy = x_enemy + 0.1
if x_player < x_enemy:
x_enemy = x_enemy - 0.1
if y_player > y_enemy:
y_enemy = y_enemy + 0.1
if y_player < y_enemy:
y_enemy = y_enemy - 0.1
显然,将变量更改为您正在使用的变量并更改您正在更改 x 和 y 的值以更改敌人移动的速度。
让敌人跟随玩家需要一些数学知识。 我建议使用pygame.math.Vector2
进行计算。
计算敌人( follower_x
, follower_y
)到玩家( player_x
, player_y
)的欧几里得距离以及从敌人到玩家的单位方向向量。 单位向量可以通过将方向向量除以距离或通过归一化( normalize()
)方向向量来计算:
target_vector = Vector2(player_x, player_y)
follower_vector = Vector2(follower_x, follower_y)
distance = follower_vector.distance_to(target_vector)
direction_vector = target_vector - follower_vector
if distance > 0:
direction_vector /= distance
定义一个精确的step_distance
并沿着从敌人到玩家的方向向量在精灵的方向上移动
if distance > 0:
new_follower_vector = follower_vector + direction_vector * step_distance.
定义玩家和敌人之间的minimum_distance
和maximum_distance
。 最小距离可以为 0,最大距离可以很大:
minimum_distance = 0
maximum_distance = 10000
使用这个最小值和最大值来限制敌人的移动:
min_step = max(0, distance - maximum_distance)
max_step = distance - minimum_distance
敌人的移动速度可以恒定
VELOCITY = 5
step_distance = min(max_step, max(min_step, VELOCITY))
或用插值因子平滑:
LERP_FACTOR = 0.05
step_distance = min_step + (max_step - min_step) * LERP_FACTOR
最小的例子:
repl.it/@Rabbid76/PyGame-FollowMouseSmoothly
import pygame
VELOCITY = 5
LERP_FACTOR = 0.05
minimum_distance = 25
maximum_distance = 100
def FollowMe(pops, fpos):
target_vector = pygame.math.Vector2(*pops)
follower_vector = pygame.math.Vector2(*fpos)
new_follower_vector = pygame.math.Vector2(*fpos)
distance = follower_vector.distance_to(target_vector)
if distance > minimum_distance:
direction_vector = (target_vector - follower_vector) / distance
min_step = max(0, distance - maximum_distance)
max_step = distance - minimum_distance
#step_distance = min(max_step, max(min_step, VELOCITY))
step_distance = min_step + (max_step - min_step) * LERP_FACTOR
new_follower_vector = follower_vector + direction_vector * step_distance
return (new_follower_vector.x, new_follower_vector.y)
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
follower = (100, 100)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
player = pygame.mouse.get_pos()
follower = FollowMe(player, follower)
window.fill(0)
pygame.draw.circle(window, (0, 0, 255), player, 10)
pygame.draw.circle(window, (255, 0, 0), (round(follower[0]), round(follower[1])), 10)
pygame.display.flip()
pygame.quit()
exit()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.