2013-10-18 52 views
1

我会做这个简短。在侧面滚动游戏中,我有一个用户控制的精灵和一个用作地形的精灵。环境小精灵级别在理论上可以是地板,天花板或墙壁,具体取决于它的位置以及玩家与之碰撞的方向,需要做一件事:击退玩家。Pygame - 防止雪碧重叠

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

我找不出来。我的第一个解决方案希望说明我的问题(而不是实际的代码,只是问题区域):

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. 

这正常一些的时间,但在拐角处得到真正狡猾becase的超过1px的每一个重叠意味着两个或两个以上玩家的双方实际上是一次碰撞环境精灵。简而言之,这是我尝试过的每个解决方案都面临的问题。

我已经潜伏了每一个线程,教程,视频,博客,指南,常见问题和帮助网站我可以合理甚至无理地在谷歌上找到,我不知道。这肯定是有人以前提到过的 - 我知道,我已经看到了。我正在寻找建议,可能是一个链接,只是任何事情来帮助我克服我只能假设的一个简单的解决方案,我找不到。

你如何重新计算任何方向的碰撞精灵的位置?

奖励:我也实施了重力 - 或者至少有一个接近恒定的向下的力量。如果它很重要。

回答

2

您与您的解决方案非常接近。既然你使用Pygame的rects来处理碰撞,我会为你提供最适合他们的方法。

假设一个精灵将与另一个精灵重叠多少是不安全的。在这种情况下,您的冲突解决方案假设您的精灵之间有一个像素(可能更好称为“单位”)重叠,实际上它听起来像是您获得的不仅仅是这些。我猜你的玩家精灵一次不会移动一个单位。

你需要做的又是什么决定了你的球员已经相交的障碍单位的确切数量,以及招他回来那么多:

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