C++ 衝突判定の中身解説
こんにちは。ネノワヲンです。今日は、昨日作った衝突判定についての中身を書きます。
ソース
コライダー(衝突物クラス)
void RectangleCollider::Create(GameObject* object, ImageVertex(&vertexArray)[4]) { Create(object); float min_x = 0; float max_x = 0; float min_y = 0; float max_y = 0; int size = sizeof(vertexArray) / sizeof(ImageVertex); for (size_t i = 0; i < size; i++) { // x座標の最大値を更新する if (vertexArray[i].m_vertPos.x > max_x) { max_x = vertexArray[i].m_vertPos.x; } // x座標の最小値を更新する if (vertexArray[i].m_vertPos.x < min_x) { min_x = vertexArray[i].m_vertPos.x; } // y座標の最大値を更新する if (vertexArray[i].m_vertPos.y > max_y) { max_y = vertexArray[i].m_vertPos.y; } // y座標の最小値を更新する if (vertexArray[i].m_vertPos.y < min_y) { min_y = vertexArray[i].m_vertPos.y; } } // 左辺の座標を設定 m_pRect->left = min_x; // 右辺の座標を設定 m_pRect->right = max_x; // 上辺の座標を設定 m_pRect->top = max_y; // 下辺の座標を設定 m_pRect->bottom = min_y; } void RectangleCollider::Create(GameObject* object) { m_pGameObject = object; m_pRect = new RectangleVertex(); DirectXRenderer::instance->AddCollider(this); } bool RectangleCollider::CheckCollider(RectangleCollider * collider) { // チェック相手のコライダー RectangleVertex checkRect = collider->GetRect(); // 自分のコライダー RectangleVertex myRect = GetRect(); //横に重なっていた場合 if (myRect.left <= checkRect.right && myRect.right >= checkRect.left) { //縦に重なっていた場合 if (myRect.top >= checkRect.bottom && myRect.bottom <= checkRect.top) { return true; } } return false; } RectangleVertex RectangleCollider::GetRect() { RectangleVertex rect = RectangleVertex(); // 頂点座標をワールド座標に変換する // 左 rect.left = (m_pGameObject->m_transform->m_pos.x) + (m_pRect->left); // 上 rect.top = (m_pGameObject->m_transform->m_pos.y) + (m_pRect->top); // 右 rect.right = (m_pGameObject->m_transform->m_pos.x) + (m_pRect->right); // 下 rect.bottom = (m_pGameObject->m_transform->m_pos.y) + (m_pRect->bottom); return rect; }
このクラスは、4辺の座標、自分のオブジェクトをメンバ変数として保持しています。 コライダーを受け取り、衝突しているかどうかを判定し、結果としてboolを返します。
オブジェクトクラス(コライダーに命令を送る)
HRESULT SpriteTest::Create(HWND hwnd) { HRESULT hr; // 画像を描画するクラスを作成する m_pSprite = new Mesh::Sprite(); hr = m_pSprite->Create(hwnd, &IMAGE_FILE_NAME); // コライダーを作成する m_pCollider = new RectangleCollider(); m_pCollider->Create(this, m_pSprite->m_pVertexArray); // タグを設定する m_tag = Tag::TEST; return hr; } void SpriteTest::LateUpdate() { // コライダーのリストを取得 for (auto collider : DirectXRenderer::instance->m_ColliderList) { // プレイヤーとのみ衝突する if (collider->m_pGameObject->m_tag != Tag::PLAYER) { continue; } // 衝突判定をする if (!m_pCollider->CheckCollider(collider)) { continue; } // 右に移動(テスト用) MoveX(0.05f); } }
メインクラスに保持してあるコライダーを取得し、自分のコライダーに命令を送ります。 衝突している場合、右に移動しています。 また、オブジェクトごとのタグによりプレイヤーを認識しています。
あとがき
このブログとしては初の、ソースについての解説になりました。実際に何をしているかの説明は難しいですね・・・! 何度も練習して上達したいと思います。