図0705a
この画面がリソースのロード中の画面です。デバッグモードで実行すれば、比較的長い時間表示されます。リリースモードの場合は、一瞬、場合によってはほとんど表示されずに次の画面に映ります。
//-------------------------------------------------------------------------------------- /// ゲームシーン //-------------------------------------------------------------------------------------- class Scene : public SceneBase { //中略 public: //中略 //-------------------------------------------------------------------------------------- /*! @brief 初期化 @return なし */ //-------------------------------------------------------------------------------------- virtual void OnCreate() override; //-------------------------------------------------------------------------------------- /*! @brief イベント取得 @return なし */ //-------------------------------------------------------------------------------------- virtual void OnEvent(const shared_ptr<Event>& event) override; };
void Scene::OnCreate() { try { //自分自身にイベントを送る //これにより各ステージやオブジェクトがCreate時にシーンにアクセスできる PostEvent(0.0f, GetThis<ObjectInterface>(), GetThis<Scene>(), L"ToWaitStage"); } catch (...) { throw; } } void Scene::OnEvent(const shared_ptr<Event>& event) { if (event->m_MsgStr == L"ToWaitStage") { //リソース読み込み用のステージ ResetActiveStage<WaitStage>(); } else if (event->m_MsgStr == L"ToTitleStage") { ResetActiveStage<TitleStage>(); } else if (event->m_MsgStr == L"ToGameStage") { ResetActiveStage<GameStage>(); } }
class WaitStage : public Stage {
//ビューの作成
void CreateViewLight();
//スプライトの作成
void CreateTitleSprite();
//リソースロード用のスレッド(スタティック関数)
static void LoadResourceFunc();
//リソースを読み込んだことを知らせるフラグ(スタティック変数)
static bool m_Loaded;
public:
//構築と破棄
WaitStage() :Stage() {}
virtual ~WaitStage() {}
//初期化
virtual void OnCreate()override;
//更新
virtual void OnUpdate()override;
};
bool WaitStage::m_Loaded = false; //リソースロード用のスレッド(スタティック関数) void WaitStage::LoadResourceFunc() { mutex m; m.lock(); m_Loaded = false; m.unlock(); wstring DataDir; //サンプルのためアセットディレクトリを取得 App::GetApp()->GetAssetsDirectory(DataDir); //各ゲームは以下のようにデータディレクトリを取得すべき //App::GetApp()->GetDataDirectory(DataDir); wstring strTexture = DataDir + L"sky.jpg"; App::GetApp()->RegisterTexture(L"SKY_TX", strTexture); strTexture = DataDir + L"trace.png"; App::GetApp()->RegisterTexture(L"TRACE_TX", strTexture); strTexture = DataDir + L"spark.png"; App::GetApp()->RegisterTexture(L"SPARK_TX", strTexture); strTexture = DataDir + L"StageMessage.png"; App::GetApp()->RegisterTexture(L"MESSAGE_TX", strTexture); //サウンド wstring CursorWav = DataDir + L"cursor.wav"; App::GetApp()->RegisterWav(L"cursor", CursorWav); //BGM wstring strMusic = DataDir + L"nanika .wav"; App::GetApp()->RegisterWav(L"Nanika", strMusic); m.lock(); m_Loaded = true; m.unlock(); } //中略 //初期化 void WaitStage::OnCreate() { wstring DataDir; //サンプルのためアセットディレクトリを取得 App::GetApp()->GetAssetsDirectory(DataDir); //お待ちくださいのテクスチャのみここで登録 wstring strTexture = DataDir + L"wait.png"; App::GetApp()->RegisterTexture(L"WAIT_TX", strTexture); //他のリソースを読み込むスレッドのスタート std::thread LoadThread(LoadResourceFunc); //終了までは待たない LoadThread.detach(); CreateViewLight(); //スプライトの作成 CreateTitleSprite(); } //更新 void WaitStage::OnUpdate() { if (m_Loaded) { //リソースのロードが終了したらタイトルステージに移行 PostEvent(0.0f, GetThis<ObjectInterface>(), App::GetApp()->GetScene<Scene>(), L"ToTitleStage"); } }
図0705b
これがタイトルステージです。
//更新 void TitleStage::OnUpdate() { //コントローラの取得 auto CntlVec = App::GetApp()->GetInputDevice().GetControlerVec(); if (CntlVec[0].bConnected) { //Bボタン if (CntlVec[0].wPressedButtons & XINPUT_GAMEPAD_B) { PostEvent(0.0f, GetThis<ObjectInterface>(), App::GetApp()->GetScene<Scene>(), L"ToGameStage"); } } }
図0705c
ステージに入ると上から物理オブジェクトが落下してきます。
void ActivePsSphere::OnCreate() {
//中略
//衝突判定をつける
auto PtrCol = AddComponent<CollisionSphere>();
//衝突判定はNoneにする
PtrCol->SetIsHitAction(IsHitAction::None);
//中略
//物理計算球体
PsSphereParam param;
//DEFAULT_SPHEREのスケーリングは直径基準なので、半径にする
param.m_Radius = m_Scale * 0.5f;
param.m_Mass = 1.0f;
//慣性テンソルの計算
param.m_Inertia = BasePhysics::CalcInertiaSphere(param.m_Radius, param.m_Mass);
param.m_MotionType = PsMotionType::MotionTypeActive;
param.m_Quat = m_Qt;
param.m_Pos = m_Position;
auto PsPtr = AddComponent<PsSphereBody>(param);
PsPtr->SetDrawActive(true);
}
//初期化
void Player::OnCreate() {
//中略
//衝突判定をつける
auto PtrCol = AddComponent<CollisionSphere>();
//判定するだけなのでアクションはNone
PtrCol->SetIsHitAction(IsHitAction::None);
PsSphereParam param;
//basecrossのスケーリングは直径基準なので、半径基準にする
param.m_Radius = m_Scale * 0.5f;
param.m_Mass = 1.0f;
//慣性テンソルの計算
param.m_Inertia = BasePhysics::CalcInertiaSphere(param.m_Radius, param.m_Mass);
//プレイヤーなのでスリープしない
param.m_UseSleep = false;
param.m_MotionType = PsMotionType::MotionTypeActive;
param.m_Quat.identity();
param.m_Pos = m_StartPos;
param.m_LinearVelocity = Vec3(0);
auto PsPtr = AddComponent<PsSphereBody>(param);
PsPtr->SetAutoTransform(false);
PsPtr->SetDrawActive(true);
//中略
}
void Player::OnPushX() { auto XAPtr = App::GetApp()->GetXAudio2Manager(); XAPtr->Start(L"cursor"); auto Ptr = GetComponent<Transform>(); Vec3 Pos = Ptr->GetPosition(); Pos.y += 0.3f; Quat Qt = Ptr->GetQuaternion(); Vec3 Rot = Qt.toRotVec(); float RotY = Rot.y; Vec3 velo(sin(RotY), 0.05f, cos(RotY)); velo.normalize(); velo *= 20.0f; auto Group = GetStage()->GetSharedObjectGroup(L"ShellGroup"); for (size_t i = 0; i < Group->size(); i++) { auto shptr = dynamic_pointer_cast<ShellSphere>(Group->at(i)); if (shptr && !shptr->IsUpdateActive()) { //空きが見つかった shptr->Reset(Pos, velo); return; } } //ここまで来てれば空きがない GetStage()->AddGameObject<ShellSphere>(Pos, velo); }
void Box::OnCreate() {
//中略
//衝突判定をつける
auto PtrCol = AddComponent<CollisionObb>();
//衝突判定はNoneにする
PtrCol->SetIsHitAction(IsHitAction::None);
//中略
//物理計算ボックス
PsBoxParam param;
//DEFAULT_CUBEのスケーリングは各辺基準なので、ハーフサイズにする
param.m_HalfSize = Vec3(0.5f, 0.5f, 0.5f) * 0.5f;
param.m_Mass = 1.0f;
//慣性テンソルの計算
param.m_Inertia = BasePhysics::CalcInertiaBox(param.m_HalfSize, param.m_Mass);
param.m_MotionType = PsMotionType::MotionTypeActive;
param.m_Quat = Qt;
param.m_Pos = m_StartPos;
auto PsPtr = AddComponent<PsBoxBody>(param);
PsPtr->SetDrawActive(true);
//ステートマシンの構築
m_StateMachine.reset(new StateMachine<Box>(GetThis<Box>()));
//最初のステートをSeekFarStateに設定
m_StateMachine->ChangeState(BoxDefaultState::Instance());
}
void ShellSphere::OnCreate() {
//中略
//Rigidbodyをつける
auto PtrRedid = AddComponent<Rigidbody>();
PtrRedid->SetVelocity(m_Velocity);
//衝突判定をつける
auto PtrCol = AddComponent<CollisionSphere>();
PtrCol->SetIsHitAction(IsHitAction::None);
//中略
}
void ShellSphere::OnUpdate2() { auto PtrTransform = GetComponent<Transform>(); if (PtrTransform->GetPosition().y < -0.5f) { Erase(); return; } auto PtrSpark = GetStage()->GetSharedGameObject<MultiSpark>(L"MultiSpark", false); if (GetComponent<Collision>()->GetHitObjectVec().size() > 0) { for (auto& v : GetComponent<Collision>()->GetHitObjectVec()) { auto& ptr = dynamic_pointer_cast<Box>(v); auto& ptr2 = dynamic_pointer_cast<Player>(v); auto& ptr3 = dynamic_pointer_cast<ActivePsObject>(v); if (ptr || ptr2) { if (ptr) { GetStage()->RemoveGameObject<Box>(ptr); } else { //ここにプレイヤーのダメージを記述 } //スパークの放出 if (PtrSpark) { PtrSpark->InsertSpark(GetComponent<Transform>()->GetPosition()); } } else if (ptr3) { //スパークの放出 if (PtrSpark) { PtrSpark->InsertSpark(GetComponent<Transform>()->GetPosition()); } Erase(); } } } }