デアゴスティーニ商法作業管理第2弾 53-55日目

ブロックにめり込まないようになりました。

とりあえず水平方向のみの判定です。今後、垂直方向も判定を入れていきます。

垂直方向を判定出来れば、ジャンプでブロックを超えることが可能になるので楽しみです。

ちなみに衝突判定処理は以下のコードのようになりました。斜め方向にぶつかった際、移動が止まらずにブロックを避ける方向にプレーヤーがうまくずれて動き続けるようにしています。

ブロックの1辺の長さは 1.0 です。_land.isBlockはx/y/z軸方向の位置を整数で指定すると、その位置にブロックがあるか判定してくれる関数です。見ての通り垂直方向のy軸には0しか指定していません。

ちょっと長いな・・・もう少し短くしたいな・・・


// 衝突判定
const DISTANCE_TO_BLOCK = 0.45;
const BOUND_DIFF = 0.0001;
if (moveX < 1.0 && moveZ < 1.0) {   // ←ラグでのブロック抜けを防ぐ
    // x方向のチェック
    if (0 != moveX) {
        let nextBX = Math.floor(0.5 + _objs.player.basePos.x + moveX + DISTANCE_TO_BLOCK * (0 < moveX ? 1 : -1));
        let nextBZ = Math.floor(0.5 + _objs.player.basePos.z);
        let posOfBlock = _objs.player.basePos.z - Math.floor(_objs.player.basePos.z);
        if (0.5 <= posOfBlock && posOfBlock <= 0.5 + DISTANCE_TO_BLOCK) {
            // 1個奥もチェック
            if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX, 0, nextBZ - 1)) {
                _objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
                moveX = 0;
            }
        } else if (0.5 - DISTANCE_TO_BLOCK <= posOfBlock && posOfBlock <= 0.5) {
            // 1個手前もチェック
            if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX, 0, nextBZ + 1)) {
                _objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
                moveX = 0;
            }
        } else {
            if (_land.isBlock(nextBX, 0, nextBZ)) {
                _objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
                moveX = 0;
            }
        }
    }
    // z方向のチェック
    if (0 != moveZ) {
        let nextBX = Math.floor(0.5 + _objs.player.basePos.x);
        let nextBZ = Math.floor(0.5 + _objs.player.basePos.z + moveZ + DISTANCE_TO_BLOCK * (0 < moveZ ? 1 : -1));
        let posOfBlock = _objs.player.basePos.x - Math.floor(_objs.player.basePos.x);
        if (0.5 <= posOfBlock && posOfBlock <= 0.5 + DISTANCE_TO_BLOCK) {
            // 1個左もチェック
            if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX - 1, 0, nextBZ)) {
                _objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
                moveZ = 0;
            }
        } else if (0.5 - DISTANCE_TO_BLOCK <= posOfBlock && posOfBlock <= 0.5) {
            // 1個右もチェック
            if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX + 1, 0, nextBZ)) {
                _objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
                moveZ = 0;
            }
        } else {       
            if (_land.isBlock(nextBX, 0, nextBZ)) {
                _objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
                moveZ = 0;
            }
        }
    }
} else {
    moveX = 0;
    moveZ = 0;
}
// 加算
_objs.player.basePos.x += moveX;
_objs.player.basePos.z += moveZ;

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です