#include "stdafx.h" #include "GameplayScene.h" #include "Materials/DiffuseMaterial.h" #include "Materials/Shadow/DiffuseMaterial_Shadow.h" #include "Materials/DiffuseMaterial_Skinned.h" #include "Materials/DiffuseOpacityMaterial.h" #include "Materials/DiffuseOpacityMaterial_Skinned.h" #include "Materials/Shadow/DiffuseMaterial_Shadow_Skinned.h" #include "Prefabs/Bomberman/Butterfly.h" #include "Prefabs/Bomberman/Crystal.h" #include "Prefabs/Bomberman/Bush.h" #include "Prefabs/Bomberman/Player.h" #include "Prefabs/Bomberman/LevelExit.h" #include "Materials/Post/PostLevels.h" GameplayScene::GameplayScene() : GameScene(L"GameplayScene") {} void GameplayScene::Initialize() { m_pFont = ContentManager::Load(L"SpriteFonts/ArialRounded_32.fnt"); m_pCrystalSprite = new GameObject(); m_pCrystalSprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Crystal_Sprite.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,1.f })); AddChild(m_pCrystalSprite); m_pCrystalSprite->GetTransform()->Translate(977.f, 97.f, 1.f); m_pHeartSprite = new GameObject(); m_pHeartSprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Heart_Sprite.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,1.f })); AddChild(m_pHeartSprite); m_pHeartSprite->GetTransform()->Translate(175.f, 97.f, 1.f); //Logger::LogInfo(L"Bomberman Scene"); m_SceneContext.settings.showInfoOverlay = false; m_SceneContext.settings.drawPhysXDebug = false; //true; m_SceneContext.settings.drawGrid = false; //true; m_SceneContext.settings.enableOnGUI = true; //LIGHTS m_SceneContext.pLights->SetDirectionalLight({ 382.274f, 218.735f, -181.521f }, { -0.434507f, -0.781122f, 0.448389f }); auto& physx = PxGetPhysics(); //Physics Materials auto pDefaultMat = physx.createMaterial(.5f, .5f, .5f); // Level Entry Block GameObject* pCollisionBlock = new GameObject(); AddChild(pCollisionBlock); pCollisionBlock->GetTransform()->Translate(-60, 0, 0); auto pActor = pCollisionBlock->AddComponent(new RigidBodyComponent(true)); const auto pPxConvexMesh = ContentManager::Load(L"Meshes/Bomberman/Tile_Collision.ovpc"); pActor->AddCollider(PxConvexMeshGeometry(pPxConvexMesh, PxMeshScale({ 1.f, 1.f, 1.f })), *pDefaultMat); // Level Exit Block pCollisionBlock = new GameObject(); AddChild(pCollisionBlock); pCollisionBlock->GetTransform()->Translate(380, 0, 0); pActor = pCollisionBlock->AddComponent(new RigidBodyComponent(true)); pActor->AddCollider(PxConvexMeshGeometry(pPxConvexMesh, PxMeshScale({ 1.f, 1.f, 1.f })), *pDefaultMat); //CAMERA //const auto pCamera = m_SceneContext.pCamera; auto pCamera = AddChild(new FixedCamera()); m_pCameraTransform = pCamera->GetTransform(); m_pCameraComponent = pCamera->GetComponent(); m_pCameraComponent->SetActive(true); //pCamera->GetTransform()->Translate(143.f, 212.f, -171.f); m_SceneContext.pCamera->GetTransform()->Translate(m_CameraMin); m_SceneContext.pCamera->GetTransform()->Rotate(53.f, 0.f, 0.f); //********* //MATERIALS //********* //Level Materials auto pLevelMaterial1 = MaterialManager::Get()->CreateMaterial(); pLevelMaterial1->SetDiffuseTexture(L"Textures/Bomberman/Levels/sm001b.png"); auto pLevelMaterial2 = MaterialManager::Get()->CreateMaterial(); pLevelMaterial2->SetDiffuseTexture(L"Textures/Bomberman/Levels/sm001c.png"); pLevelMaterial2->SetOpacityTexture(L"Textures/Bomberman/Levels/sm001c_opacity.png"); //pLevelMaterial2->SetTransparencyShadows(true); auto pLevelMaterial3 = MaterialManager::Get()->CreateMaterial(); pLevelMaterial3->SetDiffuseTexture(L"Textures/Bomberman/Levels/sm011al3.png"); pLevelMaterial3->SetOpacityTexture(L"Textures/Bomberman/Levels/sm011al3_opacity.png"); auto pLevelMaterial4 = MaterialManager::Get()->CreateMaterial(); pLevelMaterial4->SetDiffuseTexture(L"Textures/Bomberman/Levels/tree1.png"); pLevelMaterial4->SetOpacityTexture(L"Textures/Bomberman/Levels/tree1_opacity.png"); auto pLevelMaterial6 = MaterialManager::Get()->CreateMaterial(); pLevelMaterial6->SetDiffuseTexture(L"Textures/Bomberman/Levels/shadow.png"); pLevelMaterial6->SetOpacityTexture(L"Textures/Bomberman/Levels/shadow_opacity.png"); //Level Play area auto pPlayAreaMaterial0 = MaterialManager::Get()->CreateMaterial(); //DiffuseMaterial_Shadow pPlayAreaMaterial0->SetDiffuseTexture(L"Textures/Bomberman/Levels/sm001a.png"); auto pPlayAreaMaterial1 = MaterialManager::Get()->CreateMaterial(); //DiffuseMaterial_Shadow pPlayAreaMaterial1->SetDiffuseTexture(L"Textures/Bomberman/Levels/sm001b.png"); //Level Bushes auto pLevelBushesMaterial = MaterialManager::Get()->CreateMaterial(); pLevelBushesMaterial->SetTransparencyShadows(true); pLevelBushesMaterial->SetDiffuseTexture(L"Textures/Bomberman/Levels/tree2.png"); pLevelBushesMaterial->SetOpacityTexture(L"Textures/Bomberman/Levels/tree2_opacity.png"); //Ground Plane //GameSceneExt::CreatePhysXGroundPlane(*this); //******* //MESHES //******* //Playable area const auto pPlayArea = new GameObject(); AddChild(pPlayArea); ModelComponent* pPlayAreaModel = new ModelComponent(L"Meshes/Bomberman/Levels/Level01_Playarea.ovm", false); pPlayAreaModel->SetMaterial(pPlayAreaMaterial0); pPlayAreaModel->SetMaterial(pPlayAreaMaterial1, 4); pPlayArea->AddComponent(pPlayAreaModel); const auto pPlayAreaActor = pPlayArea->AddComponent(new RigidBodyComponent(true)); const auto pPxTriangleMesh = ContentManager::Load(L"Meshes/Bomberman/Levels/Level01_Playarea.ovpt"); pPlayAreaActor->AddCollider(PxTriangleMeshGeometry(pPxTriangleMesh, PxMeshScale({ 1.f, 1.f, 1.f })), *pDefaultMat); //Level Mesh const auto pLevel = new GameObject(); AddChild(pLevel); ModelComponent* pLevelModel = new ModelComponent(L"Meshes/Bomberman/Levels/Level01.ovm", false); pLevelModel->SetMaterial(pLevelMaterial1); pLevelModel->SetMaterial(pLevelMaterial2, 0); pLevelModel->SetMaterial(pLevelMaterial6, 1); pLevelModel->SetMaterial(pLevelMaterial3, 2); pLevelModel->SetMaterial(pLevelMaterial3, 3); for (UINT8 i{ 4 }; i <= 37; i++) pLevelModel->SetMaterial(pLevelMaterial2, i); pLevel->AddComponent(pLevelModel); if (const auto pAnimator = pLevelModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } //Butterfly Meshes GameObject* pButterfly = new Butterfly({ -27.5f, 20, -22.5f }, Butterfly::Type::Blue, Butterfly::Direction::Clockwise); AddChild(pButterfly); pButterfly = new Butterfly({ -22.5f, 20, 17.5f }, Butterfly::Type::White, Butterfly::Direction::CCW); AddChild(pButterfly); pButterfly = new Butterfly({ 240.f, 20, -100.f }, Butterfly::Type::Yellow, Butterfly::Direction::Clockwise); AddChild(pButterfly); pButterfly = new Butterfly({ 210.f, 20, -100.f }, Butterfly::Type::White, Butterfly::Direction::CCW); AddChild(pButterfly); pButterfly = new Butterfly({ 100.f, 20, -102.5f }, Butterfly::Type::White, Butterfly::Direction::Clockwise); AddChild(pButterfly); pButterfly = new Butterfly({ 300.f, 20, -45.f }, Butterfly::Type::Blue, Butterfly::Direction::Clockwise); AddChild(pButterfly); pButterfly = new Butterfly({ 335.f, 20, 22.5f }, Butterfly::Type::White, Butterfly::Direction::CCW); AddChild(pButterfly); //Player Mesh //m_pPlayer = new GameObject(); //Character PlayerDesc playerDesc{ pDefaultMat, 9.f, 19.f }; playerDesc.actionId_MoveUp = CharacterMoveUp; playerDesc.actionId_MoveDown = CharacterMoveDown; playerDesc.actionId_MoveLeft = CharacterMoveLeft; playerDesc.actionId_MoveRight = CharacterMoveRight; playerDesc.actionId_DropBomb = CharacterDropBomb; m_pPlayer = new Player(playerDesc, m_TileSize); AddChild(m_pPlayer); m_pPlayer->GetTransform()->Translate(0, playerDesc.controller.height / 2.f + playerDesc.controller.radius, 0); // Level Exit Arrows GameObject* pLevelExit = new LevelExit({330, 0, 0}); AddChild(pLevelExit); // Crystals GameObject* pCrystal = new Crystal({ 80, 0, 40 }, Crystal::Type::Yellow); AddChild(pCrystal); pCrystal = new Crystal({ 160, 0, -40 }, Crystal::Type::Blue); AddChild(pCrystal); pCrystal = new Crystal({ 240, 0, 80 }, Crystal::Type::Red); AddChild(pCrystal); //Destroyable Bushes m_pBushesPositions.push_back({ 40, 0, -20 }); m_pBushesPositions.push_back({ 80, 0, 0 }); m_pBushesPositions.push_back({ 80, 0, 20 }); m_pBushesPositions.push_back({ 100, 0, -1 }); m_pBushesPositions.push_back({ 60, 0, 40 }); m_pBushesPositions.push_back({ 80, 0, 60 }); m_pBushesPositions.push_back({ 100, 0, 40 }); m_pBushesPositions.push_back({ 120, 0, 20 }); m_pBushesPositions.push_back({ 140, 0, 40 }); m_pBushesPositions.push_back({ 120, 0, 60 }); m_pBushesPositions.push_back({ 100, 0, 80 }); m_pBushesPositions.push_back({ 120, 0, 79 }); m_pBushesPositions.push_back({ 140, 0, -39 }); m_pBushesPositions.push_back({ 120, 0, -40 }); m_pBushesPositions.push_back({ 120, 0, -60 }); m_pBushesPositions.push_back({ 180, 0, -40 }); m_pBushesPositions.push_back({ 200, 0, -20 }); m_pBushesPositions.push_back({ 220, 0, 0 }); m_pBushesPositions.push_back({ 220, 0, 40 }); m_pBushesPositions.push_back({ 200, 0, 60 }); m_pBushesPositions.push_back({ 200, 0, 80 }); m_pBushesPositions.push_back({ 240, 0, -60 }); m_pBushesPositions.push_back({ 260, 0, -1 }); m_pBushesPositions.push_back({ 280, 0, 0 }); m_pBushesPositions.push_back({ 280, 0, 20 }); m_pBushesPositions.push_back({ 280, 0, -20 }); m_pBushesPositions.push_back({ 300, 0, -19 }); std::sort(m_pBushesPositions.begin(), m_pBushesPositions.end(), [](const XMFLOAT3& a, const XMFLOAT3& b) { return a.z > b.z; }); for (auto& position : m_pBushesPositions) { GameObject* pBush = new Bush(position); m_pBushes.emplace_back(pBush); AddChild(pBush); } //Misc Flowers auto pFlower = new GameObject(); pFlower->GetTransform()->Translate(305, 4, 47.8f); AddChild(pFlower); ModelComponent* pFlowerModel = new ModelComponent(L"Meshes/Bomberman/Levels/Flower01.ovm", false); pFlowerModel->SetMaterial(pLevelMaterial2); pFlower->AddComponent(pFlowerModel); if (const auto pAnimator = pFlowerModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } pFlower = new GameObject(); pFlower->GetTransform()->Translate(160, 20, 109.5f); AddChild(pFlower); pFlowerModel = new ModelComponent(L"Meshes/Bomberman/Levels/Flower01.ovm", false); pFlowerModel->SetMaterial(pLevelMaterial2); pFlower->AddComponent(pFlowerModel); if (const auto pAnimator = pFlowerModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } pFlower = new GameObject(); pFlower->GetTransform()->Translate(16.2f, 4, -42.9f); AddChild(pFlower); pFlowerModel = new ModelComponent(L"Meshes/Bomberman/Levels/Flower03.ovm", false); pFlowerModel->SetMaterial(pLevelMaterial2); pFlower->AddComponent(pFlowerModel); if (const auto pAnimator = pFlowerModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } pFlower = new GameObject(); pFlower->GetTransform()->Translate(13, 4, -45.3f); AddChild(pFlower); pFlowerModel = new ModelComponent(L"Meshes/Bomberman/Levels/Flower02.ovm", false); pFlowerModel->SetMaterial(pLevelMaterial2); pFlower->AddComponent(pFlowerModel); if (const auto pAnimator = pFlowerModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } //Border bushes const auto pLevelBushes = new GameObject(); AddChild(pLevelBushes); ModelComponent* pLevelBushesModel = new ModelComponent(L"Meshes/Bomberman/Levels/Level01_Bushes.ovm", false); pLevelBushesModel->SetMaterial(pLevelBushesMaterial); pLevelBushes->AddComponent(pLevelBushesModel); if (const auto pAnimator = pLevelBushesModel->GetAnimator()) { pAnimator->SetAnimation(0); pAnimator->Play(); } //Tree Tops const auto pLevelTreeTops = new GameObject(); AddChild(pLevelTreeTops); ModelComponent* pLevelTreeTopsModel = new ModelComponent(L"Meshes/Bomberman/Levels/Level01_TreeTops.ovm", false); pLevelTreeTopsModel->SetMaterial(pLevelMaterial4); pLevelTreeTops->AddComponent(pLevelTreeTopsModel); //Input auto inputAction = InputAction(CharacterMoveLeft, InputState::down, 'A'); m_SceneContext.pInput->AddInputAction(inputAction); inputAction = InputAction(CharacterMoveRight, InputState::down, 'D'); m_SceneContext.pInput->AddInputAction(inputAction); inputAction = InputAction(CharacterMoveUp, InputState::down, 'W'); m_SceneContext.pInput->AddInputAction(inputAction); inputAction = InputAction(CharacterMoveDown, InputState::down, 'S'); m_SceneContext.pInput->AddInputAction(inputAction); inputAction = InputAction(CharacterDropBomb, InputState::pressed, VK_SPACE, -1, XINPUT_GAMEPAD_A); m_SceneContext.pInput->AddInputAction(inputAction); inputAction = InputAction(5, InputState::pressed, VK_RETURN); m_SceneContext.pInput->AddInputAction(inputAction); //POST PROCESSING auto pPostLevels = MaterialManager::Get()->CreateMaterial(); AddPostProcessingEffect(pPostLevels); } void GameplayScene::Update() { TextRenderer::Get()->DrawText(m_pFont, StringUtil::utf8_decode(std::to_string(reinterpret_cast(m_pPlayer)->GetPoints())), { 997.f, 82.f }, XMFLOAT4{ Colors::White }); const float elapsedSec = m_SceneContext.pGameTime->GetElapsed(); const float lerpFactor = 5.f * elapsedSec; //Update camera to follow player XMFLOAT3 cameraPos = m_pCameraTransform->GetPosition(); XMFLOAT3 playerPos = m_pPlayer->GetTransform()->GetPosition(); XMFLOAT3 targetPos = XMFLOAT3(playerPos.x, cameraPos.y, cameraPos.z); if (targetPos.x < m_CameraMin.x) { targetPos = m_CameraMin; } else if (targetPos.x > m_CameraMax.x) { targetPos = m_CameraMax; } targetPos = XMFLOAT3 { cameraPos.x + lerpFactor * (targetPos.x - cameraPos.x), cameraPos.y, cameraPos.z }; m_pCameraTransform->Translate(targetPos); if (m_pPlayer->GetState() == Player::State::DEAD) { m_pHeartSprite->GetComponent()->SetTexture(L"Textures/Bomberman/Heart_Sprite_Empty.png"); } if (m_pPlayer->GetState() == Player::State::DEAD || m_pPlayer->GetState() == Player::State::WIN) { if (m_pGameOverSprite == nullptr) { m_pGameOverSprite = new GameObject(); AddChild(m_pGameOverSprite); if (m_pPlayer->GetState() == Player::State::DEAD) m_pGameOverSprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Game_Over.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,0.f })); else m_pGameOverSprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Level_Clear.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,0.f })); m_pGameOverSprite->GetTransform()->Translate(m_SceneContext.windowWidth / 2.f, m_SceneContext.windowHeight / 2.f, 1.f); } else { if (m_GameOverSpriteTimer > 0) { m_GameOverSpriteTimer -= elapsedSec; m_pGameOverSprite->GetComponent()->SetColor({ 1.f, 1.f, 1.f, 1 - (m_GameOverSpriteTimer * 2) }); } else { if (m_pRetrySprite == nullptr) { m_pRetrySprite = new GameObject(); AddChild(m_pRetrySprite); if (m_pPlayer->GetState() == Player::State::DEAD) m_pRetrySprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Menu/Retry_On.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,1.f })); else m_pRetrySprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Menu/Continue_On.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,1.f })); m_pRetrySprite->GetTransform()->Translate(m_SceneContext.windowWidth / 2.f, m_SceneContext.windowHeight - 200.f, 1.f); } if (m_pQuitSprite == nullptr) { m_pQuitSprite = new GameObject(); AddChild(m_pQuitSprite); m_pQuitSprite->AddComponent(new SpriteComponent(L"Textures/Bomberman/Menu/Quit_Off.png", { 0.5f, 0.5f }, { 1.f,1.f,1.f,1.f })); m_pQuitSprite->GetTransform()->Scale(.8f); m_pQuitSprite->GetTransform()->Translate(m_SceneContext.windowWidth / 2.f, m_SceneContext.windowHeight - 75.f, 1.f); } if (m_SceneContext.pInput->IsActionTriggered(3) || InputManager::GetThumbstickPosition().y < 0) { m_pQuitSprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Quit_On.png"); m_pQuitSprite->GetTransform()->Scale(1); if (m_pPlayer->GetState() == Player::State::DEAD) m_pRetrySprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Retry_Off.png"); else m_pRetrySprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Continue_Off.png"); m_pRetrySprite->GetTransform()->Scale(.8f); if (m_SelectedUI != 1) { //sfx FMOD::Sound* sound; auto fmodSystem = SoundManager::Get()->GetSystem(); fmodSystem->createSound("Resources/Sounds/menu_select.wav", FMOD_DEFAULT, 0, &sound); fmodSystem->playSound(sound, 0, false, 0); } m_SelectedUI = 1; } if (m_SceneContext.pInput->IsActionTriggered(2) || InputManager::GetThumbstickPosition().y > 0) { if (m_pPlayer->GetState() == Player::State::DEAD) m_pRetrySprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Retry_On.png"); else m_pRetrySprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Continue_On.png"); m_pRetrySprite->GetTransform()->Scale(1); m_pQuitSprite->GetComponent()->SetTexture(L"Textures/Bomberman/Menu/Quit_Off.png"); m_pQuitSprite->GetTransform()->Scale(.8f); if (m_SelectedUI != 0) { //sfx FMOD::Sound* sound; auto fmodSystem = SoundManager::Get()->GetSystem(); fmodSystem->createSound("Resources/Sounds/menu_select.wav", FMOD_DEFAULT, 0, &sound); fmodSystem->playSound(sound, 0, false, 0); } m_SelectedUI = 0; } if (m_SceneContext.pInput->IsActionTriggered(4) || m_SceneContext.pInput->IsActionTriggered(5)) { //sfx FMOD::Sound* sound; auto fmodSystem = SoundManager::Get()->GetSystem(); fmodSystem->createSound("Resources/Sounds/menu_click.wav", FMOD_DEFAULT, 0, &sound); fmodSystem->playSound(sound, 0, false, 0); if (!m_SelectedUI) { SceneManager::Get()->AddGameScene(new GameplayScene()); SceneManager::Get()->LastScene(); } else { SceneManager::Get()->SetActiveGameScene(L"MenuScene"); } } } } } for (auto pGo : m_pLateRemoveChildren) { RemoveChild(pGo, true); } m_pLateRemoveChildren.clear(); } void GameplayScene::Draw() { } XMFLOAT3 pos{ 130.f, 220.f, -170.f }; XMFLOAT3 rot{ 53, 0, 0 }; float fov{ 45 }; void GameplayScene::OnGUI() { const auto pCameraTransform = m_SceneContext.pCamera->GetTransform(); ImGui::Text("This only activates if\n SceneSettings.enableOnGUI is True.\n\n"); ImGui::Text("Use ImGui to add custom\n controllable scene parameters!"); ImGui::ColorEdit3("Demo ClearColor", &m_SceneContext.settings.clearColor.x, ImGuiColorEditFlags_NoInputs); ImGui::InputFloat3("Camera Position", &pos.x); ImGui::InputFloat3("Camera Rotation", &rot.x); ImGui::InputFloat("Camera FOV", &fov); pCameraTransform->Translate(pos); pCameraTransform->Rotate(rot); m_SceneContext.pCamera->SetFieldOfView(XMConvertToRadians(fov)); }