2013-10-18 163 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