【问题标题】:Pygame - Prevent Sprite OverlapPygame - 防止精灵重叠
【发布时间】:2013-10-18 18:01:55
【问题描述】:

我会让这个简短而简单。在横向滚动游戏中,我有一个用户控制的精灵和一个用作地形的精灵。环境精灵类,理论上可以是地板、天花板或墙壁,具体取决于它的位置以及玩家从哪个方向与之碰撞,需要做一件事:击退玩家。

如果玩家与环境精灵的顶部发生碰撞,玩家将停留在顶部边框上。如果玩家跳跃并与环境精灵的底部发生碰撞,他们将停止向上移动并开始下落。逻辑对吗?

我想不通。我的第一个解决方案有望说明我的问题(不是实际代码,只是问题区域):

if player.rect.bottom > environment.rect.top:
    player.rect.bottom = environment.rect.top - 1
if player.rect.top < environment.rect.bottom:
    player.rect.top = environment.rect.bottom + 1
if player.rect.right > environment.rect.left:
    etc.
    etc.
    etc.

这在某些时候可以正常工作,但在角落处会变得非常狡猾,因为每次重叠超过 1px 意味着玩家的两个或多个侧面实际上一次与环境精灵发生碰撞。简而言之,这就是我尝试过的每个解决方案都面临的问题。

我已经潜伏在每一个主题、教程、视频、博客、指南、常见问题解答和帮助网站上,我可以在 google 上合理甚至不合理地找到,但我不知道。当然,这是某人以前解决过的问题-我知道,我已经看到了。我正在寻找建议,可能是一个链接,只是任何可以帮助我克服我只能假设是我找不到的简单解决方案的东西。

如何重新计算碰撞精灵相对于所有方向的位置?

奖励:我也实施了重力 - 或者至少是一个几乎恒定的向下力。以防万一。

【问题讨论】:

    标签: python pygame sprite


    【解决方案1】:

    您的解决方案非常接近。由于您使用 Pygame 的 rects 来处理碰撞,我将为您提供最适合它们的方法。

    假设一个 sprite 将与另一个 sprite 重叠多少是不太安全的。在这种情况下,您的碰撞分辨率假设您的精灵之间有一个像素(可能更好地称为“单位”)重叠,而实际上听起来您得到的还不止这些。我猜你的玩家精灵不会一次移动一个单位。

    然后你需要做的是确定你的玩家与障碍物相交的确切单位数量,并将他向后移动这么多:

    if player.rect.bottom > environment.rect.top:
        # Determine how many units the player's rect has gone below the ground.
        overlap = player.rect.bottom - environment.rect.top
        # Adjust the players sprite by that many units. The player then rests
        # exactly on top of the ground.
        player.rect.bottom -= overlap
        # Move the sprite now so that following if statements are calculated based upon up-to-date information.
    if player.rect.top < environment.rect.bottom:
        overlap = environment.rect.bottom - player.rect.top
        player.rect.top += overlap
        # Move the sprite now so that following if statements are calculated based upon up-to-date information.
    # And so on for left and right.
    

    这种方法应该适用于凸角和凹角。只要您只需要担心两个轴,独立解决每个轴都会为您提供所需的(只要确保您的玩家无法进入他不适合的区域)。考虑这个简短的例子,玩家 P 在角落与环境 E 相交:

    Before collision resolution:
    --------
    | P  --|------     ---  <-- 100 y
    |    | |     | <-- 4px
    -----|--  E  |     ---  <-- 104 y
         |       |
         ---------
          ^
         2px
         ^ ^
      90 x 92 x
    
    Collision resolution:
    player.rect.bottom > environment.rect.top is True
    overlap = 104 - 100 = 4
    player.rect.bottom = 104 - 4 = 100
    
    player.rect.right > environment.rect.left is True
    overlap = 92 - 90 = 2
    player.rect.right = 92 - 2 = 90
    
    After collision resolution:
    --------
    |  P   |
    |      |
    ---------------- <-- 100 y
           |       |
           |    E  |
           |       |
           ---------
           ^
          90 x
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多