Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使敌人的精灵在移动时发生碰撞而不是啮合在一起_Python_Pygame_Sprite_Collision - Fatal编程技术网

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

Python 如何使敌人的精灵在移动时发生碰撞而不是啮合在一起,python,pygame,sprite,collision,Python,Pygame,Sprite,Collision,编辑:请不要再提那只鸟和一个摇滚游戏相撞的事了,我的问题是离他不远。我让玩家能够在我的游戏中碰撞而不穿过墙壁,但代码不会转移到僵尸身上。僵尸不会相互碰撞和摩擦,它们只是相互滑动,成为一个整体。请阅读我下面的解释0: self.rect.right=block.rect.left elif self.rect.x0: self.rect.bottom=block.rect.top 其他: self.rect.top=block.rect.bottom 这是整个僵尸代码,当前冲突代码位于底部,从b

编辑:请不要再提那只鸟和一个摇滚游戏相撞的事了,我的问题是离他不远。我让玩家能够在我的游戏中碰撞而不穿过墙壁,但代码不会转移到僵尸身上。僵尸不会相互碰撞和摩擦,它们只是相互滑动,成为一个整体。请阅读我下面的解释0: self.rect.right=block.rect.left elif self.rect.x<0: self.rect.left=block.rect.right 如果自校正y>0: self.rect.bottom=block.rect.top 其他: self.rect.top=block.rect.bottom
这是整个僵尸代码,当前冲突代码位于底部,从
block\u hit\u list=
开始。任何关于如何纠正这一点或解释冲突编码工作原理的见解都将不胜感激

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

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

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

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


这能让你找到解决办法吗?

对不起,不行,我的问题与那一个大不相同。仍在寻求帮助,谢谢!好吧,那么,这对我来说更清楚了;很抱歉那么,您希望最后一块代码做什么呢?这意味着,如果有什么东西与我相撞,我应该依偎在它身边,并肩而行。这让我觉得所有的僵尸都会形成一大块僵尸。你是说它们重叠和合并了吗?你试过跟踪那个循环的控制和数据流吗?有多少次点击,当你移动通过区块时,坐标会发生什么变化?最重要的是,何时调用“更新”?它是只在玩家身上调用,还是在每个僵尸身上依次调用?如果是针对每一个僵尸,问题是你只治疗了一对僵尸,而不是一次治疗所有僵尸。“自我”僵尸会依次针对每个联系人僵尸进行调整,这意味着只有最后一个僵尸才算数——“自我”僵尸可以自由重叠block_hit_列表中的任何其他僵尸。@Prune啊,我明白了,所以我不希望僵尸依偎在一起,我只希望它们不能互相移动——我希望它们是“坚实的“对象。更新功能在整个主循环中调用,以便僵尸在游戏中不断跟随玩家。如果要修改我的代码,使其按我想要的方式工作,那么做什么是一件好事?@Prune和上面的代码确实会使它们聚集在一起,当我删除代码时,它们会相互重叠,看起来就像我的代码一样,当它们彼此接触时,僵尸会跳个不停,这有点痉挛。我当然很感谢你的反馈,但看起来我仍在寻找。我能提供任何其他信息来帮助你提出建议吗?你可以具体说明你想要什么。您最初发布的代码会依次将一个被触摸的僵尸移开另一个僵尸,但只保留最小的更改以避免列表中的最后一个僵尸。我答案中的代码在所有触摸僵尸周围绘制一个矩形,然后将“自我”僵尸移动到一个方便的角对角触摸。如果你想要真实的运动,你需要从大众的角度更彻底地思考。例如,如果四个僵尸包围并挤压你的“更新”列表中的第一个僵尸,那一个应该怎么做?你的代码和我的代码都不能处理这种情况:你的代码通过重叠另一个僵尸,忽略其他两个僵尸,让他远离最后一个周围的僵尸。我把他传送到他们的射程之外。如果想要逼真的运动,则需要重新设计调用“更新”的块。例如,确定一个起点,让那个僵尸占据他的位置。从那里向外工作,将每个僵尸调整到附近的位置,该位置不会与“声称”的僵尸冲突,但允许与任何其他僵尸重叠。继续,直到所有僵尸都认领。好吧,我想这样做:当一个僵尸进入另一个僵尸的路径时,我希望僵尸继续向玩家移动,但不要让他们彼此移动。我希望他们彼此摩擦,但不要融合在一起,就像现实生活中的两个人相遇一样。他们没有占据相同的物理空间,他们只是彼此相遇,对吗?因此,我希望僵尸在相互碰撞时,在聚集并移动到同一位置时相互摩擦,但不要占据相同的物理空间。这是一个更好的开始。现在你必须做出决定:你是否要一次移动一个僵尸,在进入下一个僵尸之前解决冲突;或者你想把它们全部移动然后再移动r
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 = 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)