如何实现“pygame.sprite.spritecollideany”来为 Enemy 类创建碰撞? [已关闭]

问题描述 投票:0回答:1

我的游戏中敌人类的碰撞无法正常运行。如何利用

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
python pygame game-development
1个回答
1
投票

看这部分:

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*)来找到到达玩家精灵的最佳路径。

© www.soinside.com 2019 - 2024. All rights reserved.