メモ
✅🎮 目的前提条件(仕様)
例えば「前方に移動できるか?」を調べるに
- プレイヤーは
、次の2つを確認すればよい:① 移動先の高さ足元が2ブロック分の大きさ(頭+胴体) - ジャンプは1ブロック分のみ可能
- ブロック世界は
world[x][y][z]のようなグリッドでな表現 - 「今立ってい
か?②る場所」と「前進方向」にあるブロックを調べて移動先の可能性を判定
🔍 判定に使うブロック範囲(図)
プレイヤーの体積足元 py として、
進行方向の dx, dz を使って座標 (px+dx, py, pz+dz) などを調べます。
上から見た進行方向(Z奥にブロ進む場合)
↑ 進行方向
z
|
|
[x][y+2][z+1] ← ジャンプ時の頭上クリアチェックがかぶってないか?
[x][y+1][z+1] ← 頭位置
[x][y ][z+1] ← 足元 or 障害物
[x][y+1][z] ← 現在地(頭)
[x][y ][z] ← 現在地(足)✅ 判定アルゴリズムロジックまとめ(擬似コード)
bool CanMoveOrJump(CanMoveForward(int px, int py, int pz, Direction dir) {
// 移動先方向オフセット
int dx, dz;
std::tie(dx,int dz) = GetDirectionOffset(dir);
// 進行方向のブロック座標{
int tx = px + dx;
int tz = pz + dz;
// プレイヤケース①:目の高さ前が空いていて、2ブロックの想定
// 地上にそのまま行け分スペースがあるパターン
if (isAir(tx, py, tz) && isAir(tx, py + 1, tz)) {
return true; // 前にそのまま前進める
}
// ケース②:1段だけ上にブロック段差がある → けど、ジャンプでき登れるか?
if (!isAir(tx, py, tz) && isAir(tx, py + 1, tz) && isAir(tx, py + 2, tz)) {
return true; // ジャンプで前進可能
}
// その他:ぶつかる or 高すぎる
return false;
}🧱 判定図(側面図)
ケース①:そのまま進める
空気
[ ][y+1][ ]
[ ][ y ][ ] ← 前方2ブロックが空なので通れる
↑↑↑
頭 胴 足
ケース②:1段ジャンプ可能
[ ][y+2][ ] ← 空気(ジャンプ後の頭)
[x][y+1][ ] ← 空気(ジャンプ後の胴体)
[x][ y ][ ] ← ブロック(ジャンプ対象)
ケース③:進めない(壁 or 高すぎ)
[x][y+2][x]
[x][y+1][x] ← どこかが詰まってるので登れるNG
}[x][ returny false; // それ以外は移動不可
}][x]✅🛠 判定のための補助関数(例)isAirとは?
bool isAir(int x, int y, int z) {
return (world[x][y][z] == BLOCK_AIR);BLOCK_AIR;
}✅ 方向の扱いメリット
Direction を列挙型管理しておくと便利です:
enum Direction { FORWARD, BACKWARD, LEFT, RIGHT };
std::pair<int, int> GetDirectionOffset(Direction dir) {
switch (dir) {
case FORWARD: return { 0, -1 };
case BACKWARD: return { 0, 1 };
case LEFT: return { -1, 0 };
case RIGHT: return { 1, 0 };
}
return {0, 0};
}✅ まとめ(移動判定に必要な、ブロック)
|
|
|
|---|---|---|
|
|
|
or ジャンプ |
|
|
|
|
|
✅ 応用
落下」を判定もisAir(x, y-1, z)を見れば簡単にできまる- 敵AIやパスファインディングでも使いやす
。い - 斜面や複雑地形にも柔軟に対応可能