HTML5 2D平臺遊戲開發#11斜坡物理

  在遊戲中會經常遇到斜坡地形,比如衆所周知的魂鬥羅,角色可以在坡上移動和跳躍:

斜坡在2D遊戲中很常見,處理起來也較爲棘手。最初我打算用分離軸定律來實現,在建立了一個物理模型之後:

發現上坡時沒什麼問題,但下坡時有比較明顯的彈跳,這並不是預期的結果,因爲我想讓物體「粘」在坡上。產生這個問題的根本原因是物體的運動分爲兩個階段,

首先是水平方向的移動,最後是垂直方向的移動:

如果X軸和Y軸的速度沒有一定的方式關聯起來,就會產生跳躍問題。根據力的平行四邊形法則,物體的運行軌跡應該像這樣(以向右下坡爲例):

 

接下來要做的工作就是計算出xspeedyspeed

爲了簡單起見,先將斜坡統一設置成45°,即等邊直角三角形,此時只需要將Y軸速度設置爲與X軸速度相同即可。

由上圖可以發現,當x與y相等時,角色會貼着斜坡下降,而如果x軸的速度比y軸快,角色就會脫離斜坡,此時再加上y軸的重力加速度,將會出現上述跳躍的效果。

當然這裏不是說跳躍就是錯誤的,有些遊戲也會需要這種效果,只是在當前場景下讓角色「粘」在坡上更符合需求。

 

任意角度的斜坡速度處理

  45°斜坡只是理想情況,實際上開發者可能要面對各種角度的斜坡,這裏的「各種角度」是指小於90°,因爲等於90°就相當於一面牆了。現在假設角色要在斜坡上移動的距離爲distance(一般將其賦值爲角色的水平速度speedX),那麼其水平分量爲

vx = Math.cosθ * distance;

然後令

vy = vx;

即可得出在斜坡上速度的水平和垂直分量。由於現在的水平速度是平時速度的分量,所以在斜坡上移動的速度比在平地時要慢一些。

如果不記得三角函數,可以通過下圖複習一下:

上述方法都是在θ角已知的情況下展開討論的,如果不知道θ角也沒關係,它可以通過斜面的法線與垂直方向的夾角計算出來。

至此角色在下坡時跳躍的問題已經有了初步的解決方案。

 

現在還有一個關鍵問題需要解決,就是判斷角色何時處於斜坡上,在斜坡上的水平移動使角色有一段時間是脫離斜坡的,必須讓程序知道這個階段的角色仍處於斜坡之上而不是離開了。

//Pseudocode
function checkCollision() {
    player.onSlope = false;

    if(checkPlayerOnSlope()) {
        player.onSlope = true;
    } 

    if(player.onSlope) {
        vy = vx = Math.cosθ * distance;

        //計算角色在斜坡上的座標...
    }   
}

爲實現上面僞代碼中的checkPlayerOnSlope這個方法,需要做一些額外的準備工作。

 

光線投射法

  光線投射法(RayCasting)是一種遊戲中常見的碰撞檢測手段。可以想象成一個點朝某個方向發出光線,直到光線擊中或穿過待測目標。在光線投射過程中,如果記錄下其穿過的Tiles,就會得到一個結果集,用這個結果集來分析判斷角色所處的位置。現在假設某條光線穿過的區域如下圖所示:

藍色線段所佔的區域用紅色表示,但還不夠精確,預期得到的結果應該像這樣:

這裏需要用到Bresenham畫線算法(Bresenham's line algorithm)。計算機在畫一條直線時,是通過像素來表現的,當像素點密集後,肉眼就看不出來了。

(圖片來自wikipedia)

將該線段上所有點的座標計算出來,觀察其位於哪個Tiles內,最後就能得到線段經過的Tiles集合。

 

現在爲角色的腳部添加3條光線:

如果其中一條經過的Tiles有斜坡,那就說明角色位於斜坡上。

 

斜坡物理

  當角色位於斜坡上與在平地時不一樣,應該忽略重力以及其它方向上的力的影響,否則會干擾其「粘」在斜坡上。角色位於斜坡上的y座標很容易根據下圖求出:

A點的y座標爲BA'。左右移動時,根據角色的x座標即可求出對應的y座標slopeY,並一直令

player.y = slopeY;

直到離開斜坡。

在斜坡上忽略重力影響並不意味着角色不能進行跳躍,觸發跳躍時讓角色強制離地即可。

 

更新日誌

  2017/04/09  更新角色跳躍

  2017/04/21  更新角色衝刺

  2017/05/01  更新角色狀態機

  2017/05/16  更新角色攻擊動畫

  2017/05/22  更新角色移動攻擊動畫

  2017/05/24  更新角色跳躍攻擊動畫

  2017/06/04  更新地圖繪製

  2017/06/22  更新攝像機、長距離衝刺

  2017/07/01  更新指令技

  2017/07/06  更新蓄力技

       2017/07/12  更新wall jump

       2017/10/13  更新斜坡地形 

轉載於:https://www.cnblogs.com/undefined000/p/platformer-slope-physics.html