【问题标题】:Collision detection for 2D platformer2D 平台游戏的碰撞检测
【发布时间】:2020-03-01 16:10:50
【问题描述】:

我正在开发平台游戏,我想与平台进行基本的碰撞,遗憾的是仍然无法正确完成。玩家移动计算如下:

velocity += acceleration
position += velocity + 0.5 * acceleration

所有变量都是具有xy 值的向量。这按预期工作,问题在于碰撞。我的规则是:

  • 降落在平台上时停止跌落。
  • 从平台运行时开始跌落。
  • 在跳跃过程中碰到平台时停止向上移动。
  • 撞墙时停止向一侧移动,但可以向相反方向移动。

检查底部是否与平台碰撞非常简单,但棘手的部分是检测哪一侧与平台碰撞并能够为玩家设置适当的位置。

我试图从每一侧检测角落和中间,但由于我的速度不是每帧 1 像素,所以有时玩家会很快掉下来并且也被检测到一边。

检测哪一侧发生碰撞的好方法是什么?

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    我有几个类似平台游戏的 javascript 游戏,这就是我实现碰撞的方式:

    1.落地时停止坠落: 你可以给你的精灵一个矩形作为边界区域,然后使用 Pygames 内置的 Rect 类来检测交集。当您的精灵碰撞框(矩形)和平台矩形(另一个矩形)之间发生这种交集时,您可以将玩家 Y 速度设置为 0。

    2。跑出平台时开始跌倒。 我通常有一个专门用于重力的变量,并且简单地不断将其应用于精灵以将其向下推。这样,当你不再与平台相交后,它就会向下坠落。

    3.在跳跃过程中撞到平台时停止向上移动: 和相交前一样,只是在矩形碰撞后将 Y 速度设置为 0,并让玩家因为恒定的重力而坠落。

    4.撞墙时停止向一侧移动,但可以向相反方向移动: 同样的,但这次将 X 速度设置为 0。 (如果你被困在墙上,你总是可以将 X 设置为大于 0 以推动你重新开始游戏)

    另外请注意,如果您只想在精灵碰到平台的某个边缘时做某事,您可以创建一个与精灵的侧面对齐的矩形。例如,如果我想查看某些东西是否与我的精灵的左侧相交,我可以使用 - 高度:相同高度 - 宽度:1 - x: x + 宽度 - y: 相同的 y

    关于矩形的文档: https://www.pygame.org/docs/ref/rect.html

    【讨论】:

    • 我明白这一点,但问题是(例如下降):如果我的速度太高,我的播放器矩形会移动,比如说每秒 10px,因此它可能会在帧内发生碰撞,其中平台内已经有 5 个像素。我必须决定,是否应该将它放在顶部或波纹平台上(跌落或跳跃)。
    • 您可以随时尝试预测未来,或者您的 Sprite 下一步将移动到哪里。例如,检查它是否相交,或者如果您将当前的 velY 和 velX 应用于它,它是否相交。
    • @PavelŠtěrba 我发现this 回答解决了提到的速度问题。这可能对这个答案有帮助。我要在我自己的游戏中检查一下
    【解决方案2】:

    这里的代码可以帮助检测您何时可以从平台跳转:

    self.rect.y += 2
    platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    self.rect.y -= 2
    
    # If it is ok to jump, set our speed upwards
    if len(platform_hit_list) > 0:
        velocity += acceleration
        position += velocity + 0.5 * acceleration
    

    然后是检测你跌落到平台上的代码:

    if self.rect.y >= constants.SCREEN_HEIGHT and self.change_y >= 0:
        self.change_y = 0
        self.rect.y = constants.SCREEN_HEIGHT
    

    最后是碰撞代码:

    block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    for block in block_hit_list:
        # If we are moving right,
        # set our right side to the left side of the item we hit
        if self.change_x > 0:
            self.rect.right = block.rect.left
        elif self.change_x < 0:
            # Otherwise if we are moving left, do the opposite.
            self.rect.left = block.rect.right
    
    # Move up/down
    velocity += acceleration
    position += velocity + 0.5 * acceleration
    
    # Check and see if we hit anything
    block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    for block in block_hit_list:
    
        # Reset our position based on the top/bottom of the object.
        if self.change_y > 0:
            self.rect.bottom = block.rect.top
        elif self.change_y < 0:
            self.rect.top = block.rect.bottom
    
        # Stop our vertical movement
        self.change_y = 0
    

    希望这一切都将有助于以某种方式为您提供所需的答案。请注意,这些块是指平台,并将检查给定列表中的每个平台,我使用矩形,因为它是检查碰撞的最佳方法之一。至于 change_x 和 change_y ,它只是存储玩家移动量的变量。

    【讨论】:

      猜你喜欢
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      相关资源
      最近更新 更多