2013-01-16 102 views
2

背景:我最近在xna上做了很多的學習。我一直在完善自己的遊戲結構,爲普通遊戲創建基本課程,閱讀一些文章,觀看一些視頻,閱讀我擁有的一些書。所以,在創建了一個好的遊戲結構之後,我轉向了實際的遊戲,一個平臺遊戲。我目前有普通的區塊和一名球員 - 問題出在球員之中。基礎平臺遊戲基於矩形的碰撞問題

問題/問題:與塊碰撞通常很好,但有時碰撞行爲很奇怪。 IE:一些玩家如何進入這個區域(通常是一個像素),這是一個很大的問題,因爲這可能會導致玩家在地圖上的某個位置進行推送。

玩家遊戲邏輯:玩家的移動是基於狀態的。這些州是「地面,跳躍和墜落」的統計員。現在,這個問題似乎處於下降狀態。有時候碰撞的工作是正確的,有時候玩家會在塊內部結束一個像素 - 這意味着如果玩家跳躍,他會立即被推到玩家之上的第一塊 - 不管距離有多遠。

碰撞邏輯:在墜落狀態下,玩家被重力推向地板。重力被每一幀的力量加入。在更改位置之前,將調用碰撞方法來檢查其運動範圍內的任何塊之間是否存在碰撞。現在,由於這是一個下降狀態,玩家正在向下移動,所以當它碰撞一個while循環時,每幀將玩家向下推動1個像素,直到它遇到該塊。就像備份一樣,有一個循環將球員從球場中推出。然後它將當前狀態設置爲接地。跳躍狀態遵循相同的理論。

下降狀態腳本:請閱讀以上解釋此代碼。

case PlayerState.Fall: 
    // falling sprite 
     mySpriteManager.mySpriteCurrent = mySpriteManager.mySpriteIndex["PlayerSprites/player_fall"]; 
    // fall velocity change 
     myVelocity.Y += myDforce; 

    if (Collision(otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight + myVelocity.Y)) 
    { 
     while(!Collision(otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight)) 
      myPosition.Y += 1; 
     while (Collision(otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight)) 
      myPosition.Y -= 1; 
     myVelocity.Y = 0; 
     myCurrentState = PlayerState.Ground; 
    } 
    else 
    { 
      myPosition.Y += myVelocity.Y; 
    } 
break; 

碰撞腳本:這個貫穿全固態對象,直到有衝突,如果有返回true。

private bool Collision(List<ObjWall> otWalls, float x1, float y1, float x2, float y2) 
{ 
    myBoundingBox.X = (int)Math.Ceiling(x1); 
    myBoundingBox.Y = (int)Math.Ceiling(y1); 
    myBoundingBox.Width = (int)Math.Ceiling(Math.Abs(x2 - x1)); 
    myBoundingBox.Height = (int)Math.Ceiling(Math.Abs(y2 - y1)); 
    foreach (ObjWall wall in otWalls) 
    { 
     if (Box.Intersects(wall.Box)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

變量說明:

myBoundingBox - 每一個正常的對象建立關閉此抽象類。所以,每個對象都有一個邊界矩形。

方框 - 是一個來自抽象對象類的特徵,它只是返回邊界矩形。

myVelocity - 是玩家的速度,這是一個Vector2,因爲漂浮物提供更清潔的外觀引力。

myDforce - 是一個以正向力改變yvelocity的float。我相信我應該讓它保持不變。

ObjectList - 這是一個運行所有普通對象邏輯幷包含所有可能在房間中的對象的列表的類。

myPosition - 這是抽象類提供的另一個受保護的變量,即普通對象從其中驅動。這是一個矢量2,所以它使用浮動。

有關代碼中的任何更多解釋,請詢問! 提前,感謝您的時間和幫助。 礁。

+2

你的Y位置在任何時候都不是整數?如果是這樣,你可能會有截斷問題。 – Oren

+0

不,它們是浮動的 - 並且在跌倒狀態期間每幀改變0.5(默認值myDforce) - 或跳轉狀態。那麼,我怎樣才能使數字儘可能精確(修正截斷)?鑄造也改變了數字?如果它被截斷,我會假設它。 IE(cast)4.4f會是4嗎? –

+0

當你「一個像素在」,它是一個X或Y像素?另外,「myPosition.X」和「myPosition.Y」在玩家中代表什麼? (即左上角/左下角/右下角等) – thudbutt

回答

0

您的第二次致電Collision當前僅檢查當前位置,然後向下移動播放器,無論該動作是否會導致碰撞。

我可以看到你應該用你的第三次碰撞處理這個碰撞並移動播放器備份,但從你的代碼中刪除一些複雜(略),你可以簡單地第二次調用碰撞檢查位置+ 1,如果屬實,則不移動播放器。

這消除了第三次調用Collision的需要,它匹配了第一次碰撞時大部分墜落時使用的邏輯(即,通過重力移動但不移動如果移動會與牆碰撞)以及減少您的錯誤可能發生的地方。

+0

Hello thudbutt,我明白你來自哪裏 - 是的,第三次調用看起來沒有必要,但在其他編程語言中,過去我也創建了一個類似的項目,要求使用此安全功能。它可以確保玩家遠離其落入時段的障礙物。你所說的與我過去使用的相似,但我發現自己在地板內。就像之前說過的那樣,這只是一個安全功能。 –