質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

2回答

1527閲覧

DxLib ゲーム内での選択によって参照する派生クラスを選びたい

yuki_snow

総合スコア27

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2021/04/07 08:14

前提・実現したいこと

Dxライブラリを用いて2dシューティングを作っています。
Playerクラスを作り派生クラスとしてPlayer01クラスとPlayer02クラスを作りました。そしてゲーム内の機体選択時に選択した機体を選ぶようにプログラミングしたのですが、if文を使って強引に作成してしまったので特にエラーなどは発生していませんが見栄えが悪くなってしまったように感じています。

そこで、別の方法があればヒントを教えていただけませんでしょうか?

該当のソースコード

C++

1SceneSelect.cpp 2 3#include "SceneSelect.h" 4#include "DxLib.h" 5#include "../SceneManager.h" 6#include "../Utility.h" 7#include "SceneGame.h" 8#include "../Literal.h" 9#include "../CheckDownKey.h" 10 11// ステージセレクト画面の処理をここで行う 12SceneSelect::SceneSelect() 13{ 14 m_PlyShip = PLY_TYPE1; // 自機を選択する番号 1は自機1のこと 同時押しは0に設定し誤って反応しないように 15 m_SelectCheck = false; // 決定キーを押したかどうか判別するキー 偽なら画面遷移せずメッセージを出力 16 17 // キー入力のbool 18 m_LeftFlg = false; 19 m_RightFlg = false; 20 m_LShiftFlg = false; 21 m_RShiftFlg = false; 22 m_XFlg = false; 23 24} 25 26 27// シーンの計算処理 描画処理は行わない 28void SceneSelect::Update(float DeltaTime,SceneManager* const SceneManager) 29{ 30 // 機体選択 31 if (m_SelectCheck == false) { 32 //省略 33 else if (m_LeftFlg) { // 押したのが左キーなら 34 m_PlyShip = PLY_TYPE1; // 選択中を自機1に変更 35 } 36 else if (m_RightFlg) { // 押したのが右キーなら 37 m_PlyShip = PLY_TYPE2; // 選択中を自機2に変更 38 } 39 if (m_LShiftFlg || m_RShiftFlg) { // 決定 40 m_SelectCheck = true; 41 } 42 } 43 else { 44 45 if (m_XFlg) { // キャンセル 46 m_SelectCheck = false; 47 return; 48 } 49 // シフトキーが押されたらゲームシーンに遷移する 50 if (m_LShiftFlg || m_RShiftFlg) 51 { 52 // ステージNo、機体No.などをゲームシーンに渡す 53 // とりあえず機体Noのみ 54 SceneManager->SetNextScene(new SceneGame(m_PlyShip)); 55 } 56 } 57} 58

C++

1SceneGame.cpp 2 3 4#include "SceneGame.h" // Gameシーン(本編)のヘッダ 5#include "DxLib.h" // Dxライブラリ本体 6//省略 7 8// ゲームシーンクラス ゲームの画面処理をここで行う 9// 画像のロードなどを行う 10void SceneGame::Initialize() 11{ 12 // スコア 13 m_Score = 0; //スコアの初期化 14 m_BombCnt = 0; // ボムカウント 15 m_HpBonus = 0; 16 17 // オブジェクトの生成 <ここでif文使って判別してました。> 18 if (m_PlayerType == 1)//自機によってHPや見た目などのパラメータを変更 19 { 20 m_Ply = new Player01; // 自機1 21 m_MyBomb = new Bomb01; // ボム 22 } 23 else if(m_PlayerType == 2) 24 { 25 m_Ply = new Player02; // 自機2 26 m_MyBomb = new Bomb02; // ボム 27 } 28}

C++

1Player.2// 基底クラスとなるPlayerクラス 3class Player 4{ 5protected: 6//省略 7 RECT MyRect; // 当たり判定 8 9public: 10 virtual RECT GetRect() { return MyRect; } // 自機の当たりをオーバーライド 11}; 12 13class Player01 : public Player 14{ 15//省略 16public: 17 RECT GetRect() 18 { 19 // 自機の当たり判定 20 RECT MyRect = { 21 (int)m_PlyPosX - m_pSizeX / 2, // Left 22 (int)m_PlyPosY - m_pSizeY / 2, // Top 23 (int)m_PlyPosX + m_pSizeX / 2, // Right 24 (int)m_PlyPosY + m_pSizeY / 2 // Bottom 25 }; 26 DrawBox(MyRect.left, MyRect.top, MyRect.right, MyRect.bottom, GetColor(255, 255, 255), false); // デバッグ用 27 return MyRect; 28 } 29}; 30 31class Player02 : public Player 32{ 33//省略 34public: 35 // 自機の当たり 36 RECT GetRect() 37 { 38 RECT MyRect = { 39 (int)m_PlyPosX - m_pSizeX / 5 * 2, // Left 40 (int)m_PlyPosY - m_pSizeY / 5 * 2, // Top 41 (int)m_PlyPosX + m_pSizeX / 5 * 2, // Right 42 (int)m_PlyPosY + m_pSizeY / 5 * 2 // Bottom 43 }; 44 DrawBox(MyRect.left, MyRect.top, MyRect.right, MyRect.bottom, GetColor(255, 255, 255), false); // デバッグ用 45 return MyRect; 46 } 47}; 48 49

試したこと

シーン間で値を引き継ぎ無理やりif文でつなげた。
// オブジェクトの生成
if (m_PlayerType == 1)//自機によってHPや見た目などのパラメータを変更
{
m_Ply = new Player01; // 自機1
m_MyBomb = new Bomb01; // ボム
}
else if(m_PlayerType == 2)
{
m_Ply = new Player02; // 自機2
m_MyBomb = new Bomb02; // ボム
}

補足情報(FW/ツールのバージョンなど)

Dxライブラリ
VisualStudio2017

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

この手の常套手段のPlayerの配列を作って条件分岐の代わりにindexで必要なものを選ぶというのを一応示しておきます。

std::array<std::unique_ptr<Player>, 2> players = { std::unique_ptr<Player01>{}, std::unique_ptr<Player02>{} }; auto p = players[m_PlayerType].get();

この方法はPlayerクラスのコンストラクタがゲーム初期化時のみ走らせてずっと保持し続けるという考え方ですね。

ただゲームだとPlayerみたいなクラスは任意のタイミングで構築したいという要求があると思うのでするとepistemeさんの回答のように愚直にswitch-caseを書くことになろうかと思います。

投稿2021/04/07 12:01

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

これでちっとはマシになるかしら...

C++

1class Player { 2public: 3 static Player* make(int type); 4 ... 5}; 6 7class Player01 : public Player { ... }; 8class Player02 : public Player { ... }; 9 10Player* Player::make(int type) { 11 Player* p = nullptr; 12 switch ( type ) { 13 case 1 : p = new Player01(); break; 14 case 2 : p = new Player02(); break; 15 } 16 return p; 17}

使う側では:

C++

1m_Ply = Player::make(m_PlayerType);

投稿2021/04/07 11:09

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問