Appearance
第04回 構造体と矩形
前回: 第03回 入力と移動 / 次回: 第05回 弾を撃つ
今回の授業内容
- 座標を
Vec2構造体でまとめる - 当たり判定用の範囲を
Rect構造体で表す - プレイヤーの座標を
intからVec2へ変更する - 矩形同士の重なりを判定する関数を作る
- 見た目と当たり判定の位置を確認する
今回の開始状態
第03回終了時点では、playerXとplayerYを使ってプレイヤーを動かしています。
今回の終了時点では、位置をVec2で持ち、当たり判定用のRectを作れるようにします。
変更するファイル
| ファイル | 変更内容 |
|---|---|
Common.h | Vec2とRectを追加する |
Collision.h | 矩形同士の重なり判定を追加する |
Game.h | プレイヤー座標をVec2へ変更する |
Game.cpp | 移動、描画、デバッグ表示をVec2基準に変更する |
Vec2を追加する
Common.hに、2D座標を表す構造体を追加します。
cpp
struct Vec2
{
float x;
float y;
};Game.hのプレイヤー座標を、2つのintから1つのVec2へ変更します。
cpp
Vec2 playerPosition = {};
float playerSpeed = 4.0f;初期化もVec2へ合わせます。
cpp
playerPosition = { screenWidth * 0.5f, screenHeight - 60.0f };Rectを追加する
当たり判定では、位置だけでなく幅と高さが必要です。Common.hへ矩形を表す構造体を追加します。
cpp
struct Rect
{
float x;
float y;
float width;
float height;
};プレイヤーの当たり判定を作るときは、中心座標から左上座標を計算します。
cpp
Rect playerRect =
{
playerPosition.x - 14.0f,
playerPosition.y - 14.0f,
28.0f,
28.0f
};Collision.hを追加する
SourceにCollision.hを追加し、矩形同士の重なりを判定する関数を作ります。
cpp
#pragma once
#include "Common.h"
inline bool IsOverlapping(const Rect& a, const Rect& b)
{
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}まだ敵や弾はないため、今回はプレイヤーの矩形を線で表示して確認します。
cpp
DrawBox(
static_cast<int>(playerRect.x),
static_cast<int>(playerRect.y),
static_cast<int>(playerRect.x + playerRect.width),
static_cast<int>(playerRect.y + playerRect.height),
yellow,
FALSE
);動作確認
- 第03回と同じようにプレイヤーを移動できることを確認する
- 当たり判定の黄色い矩形がプレイヤーに追従することを確認する
- 矩形のサイズを変えて、見た目との違いを確認する
Collision.hをインクルードし忘れたときのエラーを確認し、戻す
よくある問題
Vec2を追加した後は、playerXやplayerYの古い参照が残っていないか確認するfloatを描画関数へ渡すときは、static_cast<int>で整数へ変換するCollision.hは関数定義をヘッダーに置くため、inlineを付ける
今回の完成条件
Vec2で位置を表せるRectで当たり判定の範囲を表せる- プレイヤーの移動と描画を
Vec2基準に変更できる - 矩形同士の重なり判定の考え方を説明できる
まとめ
今回は、座標と範囲を構造体として整理しました。
次回は、固定配列と有効フラグを使って複数の弾を扱います。