Appearance
第16回 ワールド座標とカメラ
2 / 4 プレイヤーへ追従するCameraを作る
このステップの目的
プレイヤーを画面の中央付近にとらえ続けるカメラ座標の計算方法と、ステージ外側の余白を映さない境界制限(クランプ)を実装します。
プレイヤーを画面中央に見せるカメラ目標位置
横スクロールゲームでは、プレイヤーキャラクターが画面の中央付近に映っている状態が基本となります。
画面幅が 640ピクセルの場合、プレイヤーを画面の中央($X = 320$)に見せるためには、**「プレイヤーのワールドX座標から、目標とする画面X座標(320)を引いた位置」**にカメラを配置します。
GameTuning.hcpp
namespace dxgame::platformer::tuning::camera
{
// カメラがプレイヤーをとらえる目標画面X座標(画面中央:320ピクセル)
inline constexpr float TargetScreenX = dxgame::config::ScreenWidth * 0.5f;
}例えば、プレイヤーが $X = 320$ にいるときはカメラは $320 - 320 = 0$(ステージ左端)となり、プレイヤーが右へ進んで $X = 1000$ に達したときはカメラは $1000 - 320 = 680$ となります。
ステージ両端での見切れを防ぐクランプ処理
この計算結果(desiredX)をそのまま使うと、ゲーム開始直後にプレイヤーが左端付近(例えば $X = 100$)にいる場合、カメラは $100 - 320 = -220$ という負の座標になり、ステージ左側の余白が画面に映ってしまいます。右端(ゴール側)に到達した際も同様です。
これを防ぐため、カメラの移動範囲をステージの左端から右端までの間に制限(クランプ)します。
Camera.cppcpp
void Camera::Update(const dxgame::Vector2& target, int worldWidth)
{
const int targetX = static_cast<int>(
target.x - tuning::camera::TargetScreenX);
const int maxX = std::max(0, worldWidth - dxgame::config::ScreenWidth);
x_ = std::clamp(targetX, 0, maxX);
}境界値の計算根拠
- 最小値(
0): ステージの左端です。これより左へカメラが進むことはありません。 - 最大値(
worldWidth - ScreenWidth): カメラの右端がステージの右端に揃う位置です。これより右へ進むとステージ外の余白が見えてしまいます。
この std::clamp により、ステージの端に近づいたときはカメラが停止し、プレイヤーのみが画面端へと進む挙動が実現します。
チェックリスト
- プレイヤーのワールドX座標から画面中央幅を引いてカメラ位置を求められる
- カメラの移動可能範囲が
0〜worldWidth - ScreenWidthである理由を説明できる -
std::clampによって、ステージ外側の余白が画面に映り込まないよう制限されている - 画面幅より小さなステージであっても負にならないガード(
std::max(0, ...))がある