我的游戏中敌人类的碰撞无法正常运行。如何利用
pygame.sprite.spritecollideany
和 self.rect = temp_rect
为 Enemy 类创建碰撞?
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, target, walls):
super().__init__()
self.image = pygame.Surface((TILE_SIZE, TILE_SIZE))
self.image.fill(RED) # Enemy color is set to red
self.rect = self.image.get_rect(topleft=(x, y))
self.target = target # The player character to follow
self.walls = walls # Reference to the walls group
def update(self):
# Calculate the direction vector from the enemy to the player character
dx = self.target.rect.centerx - self.rect.centerx
dy = self.target.rect.centery - self.rect.centery
# Normalize the direction vector
distance = math.hypot(dx, dy)
if distance != 0:
dx /= distance
dy /= distance
# Adjust speed for smoother movement
speed = 1.7
dx *= speed
dy *= speed
# Calculate the new position
new_x = self.rect.x + dx
new_y = self.rect.y + dy
# Check for collisions with walls
temp_rect = self.rect.move(dx, dy)
if not pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
else:
# If there's a collision, try adjusting the direction
# Randomize direction change to avoid getting stuck in corners
if random.random() < 0.5:
dx = random.choice([-1, 0, 1])
dy = random.choice([-1, 0, 1])
else:
dx *= -1
dy *= -1
# Normalize the new direction vector
distance = math.hypot(dx, dy)
if distance != 0:
dx /= distance
dy /= distance
# Adjust speed for smoother movement
dx *= speed
dy *= speed
# Calculate the new position after collision
temp_rect = self.rect.move(dx, dy)
if not pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
看这部分:
temp_rect = self.rect.move(dx, dy)
if not pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
在这一部分,您尝试决定是否允许移动。
temp_rect
包含精灵的新位置,但是当您调用pygame.sprite.spritecollideany
时,您实际上并没有使用新位置进行碰撞检测,而是使用精灵的当前位置。因此将允许移动,并且精灵会移入墙壁。
您可以先移动精灵,然后进行碰撞检测,如果撞到墙壁,则撤消移动。
这部分也存在同样的问题:
# Calculate the new position after collision
temp_rect = self.rect.move(dx, dy)
if not pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
这是纠正此行为的版本(它仍然可以改进,尝试使用
pygame.Vector2
让您的生活更轻松):
def update(self):
# Calculate the direction vector from the enemy to the player character
dx = self.target.rect.centerx - self.rect.centerx
dy = self.target.rect.centery - self.rect.centery
# Normalize the direction vector
distance = math.hypot(dx, dy)
if distance != 0:
dx /= distance
dy /= distance
# Adjust speed for smoother movement
speed = 1.7
dx *= speed
dy *= speed
# Calculate the new position
new_x = self.rect.x + dx
new_y = self.rect.y + dy
# Check for collisions with walls
temp_rect = self.rect
self.rect = self.rect.move(dx, dy)
if pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
# If there's a collision, try adjusting the direction
# Randomize direction change to avoid getting stuck in corners
if random.random() < 0.5:
dx = random.choice([-1, 0, 1])
dy = random.choice([-1, 0, 1])
else:
dx *= -1
dy *= -1
# Normalize the new direction vector
distance = math.hypot(dx, dy)
if distance != 0:
dx /= distance
dy /= distance
# Adjust speed for smoother movement
dx *= speed
dy *= speed
# Calculate the new position after collision
temp_rect = self.rect
self.rect = self.rect.move(dx, dy)
if pygame.sprite.spritecollideany(self, self.walls):
self.rect = temp_rect
下一个问题是精灵试图进行的躲避是随机的。如果您使用更正后的代码,您会发现精灵仍然会卡在墙上,但它在最终绕过墙壁之前开始摇晃。精灵不会决定绕着墙走这条路或那条路。它会随机上/下/左/右移动。
您可以使用一些简单的寻路(如 A*)来找到到达玩家精灵的最佳路径。