You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame中敌人碰撞墙体时出现瞬移问题求助

问题描述

游戏中敌人移动逻辑正常,但与墙体碰撞时会出现瞬移现象。已删除僵尸旋转等可能影响该问题的代码,仍未找到问题根源。

Enemy类代码:

class Enemy(pygame.sprite.Sprite):
    def __init__(self, position):
        super().__init__(enemy_group, all_sprites_group)
        self.position = pygame.math.Vector2(position) 
        self.zombie_speed = 2 

        self.image = pygame.image.load("zombieAssets/skeleton-idle_0.png").convert_alpha()
        self.image = pygame.transform.rotozoom(self.image, 0, 0.35)
        self.base_zombie_image = self.image

        self.base_zombie_rect = self.base_zombie_image.get_rect(center = position)
        self.rect = self.base_zombie_rect.copy()

        self.velocity = pygame.math.Vector2()

    def hunt_player(self):  
        player_position = player.base_player_rect.center
        distance_to_player = player_position - self.position
        try:
            self.velocity = distance_to_player.normalize() * self.zombie_speed
            self.position += self.velocity

            self.base_zombie_rect.centerx = self.position.x
            self.check_collision("horizontal")

            self.base_zombie_rect.centery = self.position.y
            self.check_collision("vertical")

            self.rect.center = self.base_zombie_rect.center
        except:
            return

    def check_collision(self, direction):
        for sprite in obstacles_group:
            if sprite.rect.colliderect(self.base_zombie_rect):
                if direction == "horizontal":
                    if self.velocity.x > 0:
                        self.base_zombie_rect.right = sprite.rect.left
                    if self.velocity.x < 0:
                        self.base_zombie_rect.left = sprite.rect.right
                
                if direction == "vertical":
                    if self.velocity.y < 0:
                        self.base_zombie_rect.top = sprite.rect.bottom
                    if self.velocity.y > 0:
                        self.base_zombie_rect.bottom = sprite.rect.top
            
    def update(self):
        self.hunt_player()
问题根源与修复方案

问题出在碰撞修正后没有同步更新self.position:每次先更新self.position并赋值给base_zombie_rect,碰撞时只调整了base_zombie_rect的位置,但self.position还是碰撞前的错误坐标。下一次循环时,错误的self.position又会把base_zombie_rect拉回原位,视觉上就表现为瞬移。

修复步骤:

  1. 在每次碰撞修正后,把base_zombie_rect的当前坐标同步回self.position
  2. 用elif替换碰撞判断里的if,避免重复触发不必要的条件

修改后的核心方法代码:

def hunt_player(self):  
    player_position = player.base_player_rect.center
    distance_to_player = player_position - self.position
    try:
        self.velocity = distance_to_player.normalize() * self.zombie_speed
        self.position += self.velocity

        self.base_zombie_rect.centerx = self.position.x
        self.check_collision("horizontal")
        # 同步水平碰撞后的位置到self.position
        self.position.x = self.base_zombie_rect.centerx

        self.base_zombie_rect.centery = self.position.y
        self.check_collision("vertical")
        # 同步垂直碰撞后的位置到self.position
        self.position.y = self.base_zombie_rect.centery

        self.rect.center = self.base_zombie_rect.center
    except:
        return

def check_collision(self, direction):
    for sprite in obstacles_group:
        if sprite.rect.colliderect(self.base_zombie_rect):
            if direction == "horizontal":
                if self.velocity.x > 0:
                    self.base_zombie_rect.right = sprite.rect.left
                elif self.velocity.x < 0:
                    self.base_zombie_rect.left = sprite.rect.right
            elif direction == "vertical":
                if self.velocity.y < 0:
                    self.base_zombie_rect.top = sprite.rect.bottom
                elif self.velocity.y > 0:
                    self.base_zombie_rect.bottom = sprite.rect.top

修改后self.position会始终和碰撞修正后的base_zombie_rect坐标保持一致,瞬移问题就能解决。

内容的提问来源于stack exchange,提问作者juba1029

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:40:42