如何使敌人精灵在移动时发生碰撞而不啮合在一起



编辑:请不要再向我提及鸟与岩石碰撞的游戏,我的问题远不及他的。在我的游戏中,我让玩家能够与墙壁碰撞而不是穿过墙壁,但代码不会转移到僵尸身上。僵尸不会相互碰撞和摩擦,它们只是滑到彼此身上,成为一个方块。请阅读下面我的解释<3

所以我正在制作一款pygame游戏,当玩家射击僵尸时,僵尸会向玩家移动(我知道,是原创的,对吧?)但是,我必须检测僵尸相互碰撞的代码并不能以任何实际的方式工作,没有它,僵尸只是向玩家移动,并结合成一个僵尸块。我该如何修改僵尸的代码,让它们在靠近吃掉我的大脑时不会互相靠近?

class Enemy(pygame.sprite.Sprite):
    def __init__(self, color):
        super().__init__()
        self.image = pygame.Surface([20, 20])
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.pos_x = self.rect.x = random.randrange(35, screen_width - 35)
        self.pos_y = self.rect.y = random.randrange(35, screen_height - 135)
        # How Zombies move towards player
    def update(self):
        zombie_vec_x = self.rect.x - player.rect.x
        zombie_vec_y = self.rect.y - player.rect.y
        vec_length = math.sqrt(zombie_vec_x ** 2 + zombie_vec_y ** 2)
        zombie_vec_x = (zombie_vec_x / vec_length) * 1 # These numbers determine
        zombie_vec_y = (zombie_vec_y / vec_length) * 1 # zombie movement speed
        self.pos_x -= zombie_vec_x
        self.pos_y -= zombie_vec_y
        self.rect.x = self.pos_x
        self.rect.y = self.pos_y

        block_hit_list = pygame.sprite.spritecollide(self, sprites_list, False)
        for block in block_hit_list:
            if self.rect.x > 0:
                self.rect.right = block.rect.left
            elif self.rect.x < 0:
                self.rect.left = block.rect.right
            elif self.rect.y > 0:
                self.rect.bottom = block.rect.top
            else:
                self.rect.top = block.rect.bottom

这是整个僵尸代码,当前的碰撞代码在底部,从block_hit_list =开始。任何关于如何纠正这一点或解释如何碰撞编码工作的见解将非常感激!

我不是100%确定代码细节,因为您没有详细描述您的坐标系统。然而,主要的一点是,你必须找到一个安全的地方,让当前的僵尸移动,一个没有其他僵尸的地方。这真的需要你从最受限制的区域到最不受限制的区域。你能把僵尸按空间顺序排序吗?也许从左下到右上遍历僵尸列表?

考虑到这一点,每个僵尸都必须检查关于所有的其他僵尸的位置,而不仅仅是依次为其他僵尸让路。你必须更全面地考虑x和y方向。我认为这可以很好地工作,取决于移动速度(僵尸可以走一步超过僵尸宽度的一半吗?)

    block_hit_list = pygame.sprite.spritecollide(self, sprites_list, False)
    if self.rect.x > 0:
        self.rect.right = min(block.rect.left for block in block_hit_list)
    else:
        self.rect.left = max(block.rect.right for block in block_hit_list)
    if self.rect.y > 0:
        self.rect.bottom = min(block.rect.top for block in block_hit_list)
    else:
        self.rect.top = max(block.rect.bottom for block in block_hit_list)

注意,我处理的是两个坐标,而不是一个——我假设僵尸可以对角线移动。我不确定我是否在你的坐标系中正确地匹配了方向:如果self.rect.x> 0,我想要大多数正面僵尸的左边缘吗?我不知道在坐标系中是左>右还是上>下。请根据需要进行测试和调整。

同时,请在每个分支中临时插入跟踪打印语句:至少显示前后的x/y坐标。

这会让你走向解决方案吗?

最新更新