ブロックにめり込まないようになりました。
とりあえず水平方向のみの判定です。今後、垂直方向も判定を入れていきます。
垂直方向を判定出来れば、ジャンプでブロックを超えることが可能になるので楽しみです。
ちなみに衝突判定処理は以下のコードのようになりました。斜め方向にぶつかった際、移動が止まらずにブロックを避ける方向にプレーヤーがうまくずれて動き続けるようにしています。
ブロックの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;