iT邦幫忙

0

{CMoney戰鬥營} 的第七週 # 勉強堪用(?)的重力系統

本週的目標是要讓橫向卷軸中的角色可以左右移動及跳躍, 在沒有碰到場景物件時自由落體, 碰到牆壁時被阻擋在牆的一側。

在限定所有物件的形狀都是沒有對座標軸旋轉的長方體時,可以使用簡單的AABB碰撞盒來檢測是否碰撞

private boolean isCollision(GameObj obj) {
            if (this.left() > obj.right()) return false;
            if (this.right() < obj.left()) return false;
            if (this.top() > rect.bottom()) return false;
            if (this.bottom() < rect.top()) return false;
            return true;
        }

為了讓角色有越掉越快, 需要讓角色的速度每次更新一個定值

private void update(){
    velocity.offsetY(Gravity) // y 軸速度每次增加
    offsetX = velocity(x);
    offsetY = velocity(y)
}

為了讓角色合理的被場景物件阻擋, 要和場景物件判定碰撞, 並因碰撞結果設定角色位置和歸零速度

原本的AABB碰撞僅依據物件的位置獲得是否碰撞的結果,
因此需要知道物件的速度, 才會知道是與場景的哪個邊碰撞,

再者, 因為與頂點接觸時會判定為碰撞, 將使角色在行走在互相連接的下一塊底板時,
無法判定與下一塊地板的頂點碰撞是"牆壁或地板", 因此將角色碰撞後的位置設定在地板的上緣之上(1 單位)

actor.update();
        for (int i = 0; i < gameObjects.size(); i++) {
            GameObject obj = gameObjects.get(i);
            if (actor.isCollision(obj)) {
                actor.preMove();
                actor.moveY();
                if (actor.isCollision(obj)) { // 撞到 Y
                    actor.jumpReset();
                    if (actor.velocity().y() < 0) {
                        actor.setY(obj.collider().bottom() +1 );
                        actor.velocity().stopY();
                    } else if (actor.velocity().y() > 0) {
                        actor.setY(obj.collider().top() - actor.painter().height() -1);
                        actor.velocity().stopY();
                    }
                    actor.moveX();
                }
                if (actor.collider().bottom() == obj.collider().top() |
                        actor.collider().top() == obj.collider().bottom()) {
                    actor.moveX();
                }
            }
        }

尚未有邦友留言

立即登入留言