3 / 4 プレイヤーの位置と表示
2D画面の座標系を理解し、プレイヤーの初期位置を設定して機体画像を描画できるようにします。
2Dゲームにおける画面座標系
画面上の位置は、数値の組み合わせである座標で指定します。
2Dゲームでは通常、横方向のX座標と縦方向のY座標の2つで位置を表します。
一般的な数学のグラフと異なり、多くのコンピューターグラフィックスや2Dゲームエンジンでは、画面の左上端が原点{ 0, 0 }になります。
X軸は右へ進むほど値が大きくなります。右が正の方向です。
Y軸は下へ進むほど値が大きくなります。下が正の方向です。
画面座標系の向き
本作の画面サイズは横640ピクセル、縦480ピクセルです。そのため、画面の右下端の座標は{ 640, 480 }となります。
Playerクラスと座標の保持
プレイヤーに関するデータと機能は、Playerクラスとしてカプセル化されています。
既存の宣言を読むときは、次の記法に注目します。
| 記法 | このコードでの役割 |
|---|---|
public / private | 外から呼ぶ機能と、クラスの内部で扱う情報を分ける |
const Input& / const ImageManager& | 既存のオブジェクトをコピーせず、変更しない参照として受け取る |
メンバ関数の末尾のconst | この関数では自身のメンバを変更しないと示す |
先頭のclass Input;とclass ImageManager;は、その名前のクラスがあることを伝える宣言です。クラス本体は別のヘッダーに定義されています。
#pragma once
#include "DxGame/Rect.h"
#include "DxGame/Vector2.h"
namespace dxgame::shooting
{
class Input;
class ImageManager;
// プレイヤーの中心座標と移動を管理する
class Player
{
public:
// プレイヤーを開始位置へ戻す
void Reset();
// 入力から移動方向を求めプレイヤーを画面内で移動させる
// deltaTimeは移動計算で1フレーム分として使う秒数
void Update(const Input& input, float deltaTime);
// プレイヤー画像を表示用Rectに合わせて描く
void Draw(const ImageManager& images) const;
// 表示用Rectを現在位置へ移動して返す
Rect GetDrawRect() const;
private:
// プレイヤーの中心座標
Vector2 position = {};
};
}機体の位置情報は、メンバ変数positionに保持されます。
ここで使われているVector2は、X座標とY座標の組を扱うための構造体です。
// 2D空間の位置や移動方向をX成分とY成分で表す
struct Vector2
{
float x = 0.0f;
float y = 0.0f;
};カプセル化による保護
position変数はprivate領域に宣言されています。
外部のクラスから位置を直接書き換えられないようにするためです。座標の変更をPlayerクラス内に限定し、意図しない場所で座標が書き換わるバグを防ぎます。
プレイヤーの開始位置を設定する
ゲーム開始時やリトライ時に、プレイヤーを指定の初期位置へ配置する処理を実装します。Player.cppのPlayer::Reset()を次のように実装します。
void Player::Reset()
{
position = tuning::player::StartPosition;
}開始位置の座標値は、調整しやすいようにGameTuning.hに定義されています。inline constexprは、このヘッダーを複数のファイルから読み込んで使う定数に付けています。
inline constexpr Vector2 StartPosition = { 320.0f, 424.0f };画面全体の横幅が640ピクセルのため、X座標320はちょうど画面の中央になります。またY座標424は、画面の下端付近に機体が収まる位置を示しています。
機体画像を描画する
次に、画面上の正しい位置にプレイヤー画像を表示します。Player.cppのPlayer::Draw()を次のように実装します。
void Player::Draw(const ImageManager& images) const
{
images.Draw(ImageManager::Id::Player, GetDrawRect());
}Playerクラスでは、画像の読み込みやDirectXの描画APIを直接呼び出しません。描画を担当するImageManagerへ、画像の種類(Id::Player)と表示する領域(drawRect)を渡します。
オブジェクトの中心座標と画像の表示領域
キャラクターのpositionを機体の中心点として扱うと、当たり判定や移動の計算が簡単になります。
一方、グラフィックスを描画する際は、画像の左上座標や表示サイズを指定する必要があります。
この「中心座標」から「描画用の矩形領域」を計算する役割を担っているのがGetDrawRect()です。
Rect Player::GetDrawRect() const
{
return tuning::player::DrawRect.MovedBy(position);
}GameTuning.hの基準矩形(tuning::player::DrawRect)を、現在のpositionの分だけ平行移動します。これで、機体の中心に合わせた描画矩形を求められます。
// プレイヤーの中心を基準にした画像の表示範囲(幅48、高さ58)
inline constexpr Rect DrawRect = Rect::Centered(48.0f, 58.0f).MovedBy({ 0.0f, 3.0f });ここまでの実装を終えてビルド・実行すると、画面下部の中央にプレイヤーの機体画像が表示されます。
初期位置に表示されたプレイヤー
- 2Dゲームにおける画面座標系(左上が原点、右が+X、下が+Y)を理解している
-
Player::Reset()によって開始位置が正しく設定されている -
Player::Draw()によって画面下部にプレイヤー画像が表示されることを確認できる - 機体の中心座標と描画矩形(
GetDrawRect())の関係を説明できる