diff --git a/CMakeLists.txt b/CMakeLists.txt index c7b53d9c..9c49260d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,8 @@ set(SRC_FILES ${SRC_DIR}/Enemy/Enemy.cpp + ${SRC_DIR}/AI/EnemyScripts.cpp + ${SRC_DIR}/Structure/Structure.cpp ${SRC_DIR}/Structure/WayPoint.cpp ${SRC_DIR}/Structure/HighLight.cpp @@ -99,7 +101,7 @@ set(SRC_FILES ${SRC_DIR}/Scene/MapScene.cpp ${SRC_DIR}/Scene/TutorialScene.cpp - + ${SRC_DIR}/Scene/SandboxScene.cpp ${SRC_DIR}/Avatar/Runner.cpp ${SRC_DIR}/Avatar/Avatar.cpp @@ -220,6 +222,8 @@ set(INCLUDE_FILES ${INCLUDE_DIR}/Scene/Scene.hpp ${INCLUDE_DIR}/Scene/TutorialScene.hpp + ${INCLUDE_DIR}/Scene/SandboxScene.hpp + ${INCLUDE_DIR}/Enemy/Enemy.hpp ${INCLUDE_DIR}/Enemy/EnemyScripts.hpp diff --git a/include/AI/Enemy.hpp b/include/AI/Enemy.hpp index 30adaf9e..c494654b 100644 --- a/include/AI/Enemy.hpp +++ b/include/AI/Enemy.hpp @@ -5,7 +5,7 @@ #ifndef PRACTICALTOOLSFORSIMPLEDESIGN_ENEMY_HPP #define PRACTICALTOOLSFORSIMPLEDESIGN_ENEMY_HPP -#include "Mechanics/GameObjectID.hpp" +//#include "Mechanics/GameObjectID.hpp" #include "Mechanics/Player.hpp" enum class EnemyMode{ DEFAULT, @@ -34,7 +34,7 @@ class EnemyPlayer:public Player{ int getAvatarCount(){ return unitCount[UnitType::INFANTRY]; } - void setAvatarCount(UnitType type,int value){ + void addAvatarCount(UnitType type,int value){ unitCount[type] += value; } protected: diff --git a/include/AI/EnemyScripts.hpp b/include/AI/EnemyScripts.hpp index e91718e4..2c4cbec3 100644 --- a/include/AI/EnemyScripts.hpp +++ b/include/AI/EnemyScripts.hpp @@ -8,94 +8,64 @@ #include "Mechanics/UnitManager.hpp" #define SPACE 4 -class EnemyScripts { + + +enum class SpawnMode { BUILDINGS,AVATAR}; +class EnemyScripts{ + private: - std::shared_ptr m_Enemy; std::shared_ptr m_GameObjectManager; + std::shared_ptr m_EnemyObjectManager; std::shared_ptr m_Map; glm::vec2 m_baseCell = {20, 20}; int constructCountX = 0; int constructCountY = 0; - float CDTime = 0; - std::chrono::high_resolution_clock::time_point m_StartTime; - double m_lastElapsed = 0.F; + float m_buildingCDTime=0; + float m_AvatarCDTime=0; + float m_buildingCost = 0.F; + float m_avatarCost = 0.F; + + UnitType m_selectedBuildingType = UnitType::NONE; + UnitType m_selectedAvatarType = UnitType::NONE; + + float m_buildDeltaTime = 0; + float m_avatarDeltaTime = 0; + float m_mainDeltaTime = 0; + Util::Time m_Time; + + bool m_active; public: EnemyScripts(){}; ~EnemyScripts(){}; - void Start(std::shared_ptr enemyPlayer, - std::shared_ptr GameObjectManager, - std::shared_ptr map) { - m_StartTime = std::chrono::high_resolution_clock::now(); - m_Enemy = enemyPlayer; - m_GameObjectManager = GameObjectManager; - m_Map = map; + void Start(std::shared_ptr GameObjectManager,std::shared_ptr EnemyObjectManager,std::shared_ptr map,bool active = true); + void Update(); + void modeUpdate(); + void offensiveUpdate(){ + // if(m_EnemyObjectManager->getOffensiveTroopSize()>0){ + // m_EnemyObjectManager->setOffensiveTroopAttack(m_GameObjectManager->getMostValuableTarget()); + // } } - void Update() { - - std::chrono::high_resolution_clock::time_point m_currentTime = - std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = m_currentTime - m_StartTime; - if (elapsed.count() - m_lastElapsed >= CDTime) { // update when CD over - m_lastElapsed = elapsed.count(); - UpdateSpawnScript(); - } + void updateAllTroopStates(){ + // m_EnemyObjectManager->setAllTroopToAttackMode(); + // m_EnemyObjectManager->setDefensiveTroopSize(0); } - void UpdateSpawnScript() { - if (m_Enemy->getUnitConstructCount(UnitType::POWER_PLANT) < 1 && - m_Enemy->getTotalCurrency() > 300) { - m_GameObjectManager->spawn(m_Map, UnitType::POWER_PLANT, - HouseType::ENEMY, - {m_baseCell.x + constructCountX, - m_baseCell.y + constructCountY}); - constructCountX += SPACE; - CDTime = 15.f * CHEAT; - } else if (m_Enemy->getUnitConstructCount(UnitType::ORE_REF) < 1 && - m_Enemy->getTotalCurrency() > 2000) { - m_GameObjectManager->spawn(m_Map, UnitType::ORE_REF, - HouseType::ENEMY, - {m_baseCell.x + constructCountX, - m_baseCell.y + constructCountY}); - constructCountX += SPACE; - CDTime = 100.f * CHEAT; - } else if (m_Enemy->getUnitConstructCount(UnitType::BARRACKS) < 1 && - m_Enemy->getTotalCurrency() > 300) { - m_GameObjectManager->spawn(m_Map, UnitType::BARRACKS, - HouseType::ENEMY, - {m_baseCell.x + constructCountX, - m_baseCell.y + constructCountY}); - constructCountX += SPACE; - CDTime = 15.f * CHEAT; - } else if (m_Enemy->getAvatarCount() <= 25 && - m_Enemy->getTotalCurrency() > 100) { - m_GameObjectManager->spawnToWayPoint(m_Map, UnitType::INFANTRY, - HouseType::ENEMY); - CDTime = 5.f * CHEAT; - } else if (m_Enemy->getUnitConstructCount(UnitType::WAR_FACT) < 1 && - m_Enemy->getTotalCurrency() > 2000) { - m_GameObjectManager->spawn(m_Map, UnitType::WAR_FACT, - HouseType::ENEMY, - {m_baseCell.x + constructCountX, - m_baseCell.y + constructCountY}); - constructCountX += SPACE; - CDTime = 100.f * CHEAT; - } else if (m_Enemy->getUnitConstructCount(UnitType::ADV_POWER_PLANT) < - 1 && - m_Enemy->getTotalCurrency() > 500) { - m_GameObjectManager->spawn(m_Map, UnitType::ADV_POWER_PLANT, - HouseType::ENEMY, - {m_baseCell.x + constructCountX, - m_baseCell.y + constructCountY}); - constructCountX += SPACE; - CDTime = 25.f * CHEAT; - } - if (constructCountX >= 15) { - constructCountY += SPACE; - constructCountX = 0; - } + void setCDTime(float time,SpawnMode spawnMode,bool cheat = true); + void setCost(float cost,SpawnMode spawnMode); + + bool ifBuiltBasic(){ + return m_EnemyObjectManager->getUnitConstructCount(UnitType::POWER_PLANT)>=1 && m_EnemyObjectManager->getUnitConstructCount(UnitType::ORE_REF)>=1 && m_EnemyObjectManager->getUnitConstructCount(UnitType::BARRACKS)>=1 ; } + bool ifBuiltADV(){ + return m_EnemyObjectManager->getUnitConstructCount(UnitType::WAR_FACT)>=1 && m_EnemyObjectManager->getUnitConstructCount(UnitType::ADV_POWER_PLANT)>=1 ; + } + + void buildBasic(); + void buildADV(); + void spawnUnit(); + void UpdateSpawnScript(SpawnMode spawnMode); }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_ENEMYSCRIPTS_HPP diff --git a/include/Mechanics/BuiltStructure.hpp b/include/Mechanics/BuiltStructure.hpp index 3f80583c..4bb1771d 100644 --- a/include/Mechanics/BuiltStructure.hpp +++ b/include/Mechanics/BuiltStructure.hpp @@ -77,24 +77,20 @@ class BuiltStructure { m_BuiltStructure.push_back(structure); } - void updateAvatarSpawnLocation( - std::vector> structure) { - for (auto i : structure) { + void updateAvatarSpawnLocation() { + for (auto i : m_BuiltStructure) { if (std::dynamic_pointer_cast(i)) { - if (i->getHouseType() == HouseType::ENEMY) { - m_EnemyBarrackCell = i->GetObjectLocation(); - m_EnemyWayPointCell = std::dynamic_pointer_cast(i) - ->GetWayPointLocation(); - } else { - m_PlayerBarrackCell = i->GetObjectLocation(); - m_PlayerWayPointCell = - std::dynamic_pointer_cast(i) - ->GetWayPointLocation(); - } + m_PlayerBarrackCell = MapUtil::GlobalCoordToCellCoord(i->GetObjectLocation()); + m_PlayerWayPointCell =MapUtil::GlobalCoordToCellCoord( + std::dynamic_pointer_cast(i) + ->GetWayPointLocation()); } } } + glm::vec2 getPlayerBarrackCell() { return {m_PlayerBarrackCell.x-1,m_PlayerBarrackCell.y-1}; } + glm::vec2 getPlayerWayPointCell() { return m_PlayerWayPointCell; } + public: glm::vec2 getEnemyBarrackCell() { return m_EnemyBarrackCell; } glm::vec2 getEnemyWayPointCell() { return m_EnemyWayPointCell; } @@ -126,11 +122,10 @@ class BuiltStructure { return false; } + private: std::shared_ptr m_Map = std::make_shared(); std::vector> m_BuiltStructure; - glm::vec2 m_EnemyBarrackCell = {-1, -1}; - glm::vec2 m_EnemyWayPointCell = {-1, -1}; glm::vec2 m_PlayerBarrackCell = {-1, -1}; glm::vec2 m_PlayerWayPointCell = {-1, -1}; }; diff --git a/include/Mechanics/Player.hpp b/include/Mechanics/Player.hpp index 49edc83b..f662ac10 100644 --- a/include/Mechanics/Player.hpp +++ b/include/Mechanics/Player.hpp @@ -10,7 +10,7 @@ class Player { Player() {} ~Player() {} void setTotalCurrency(int value) { m_TotalCurrency = value; } - void addTotalCurrency(int value) { m_TotalCurrency += value; }; + void addTotalCurrency(float value) { m_TotalCurrency += value; }; void setFixedPower(int value) { m_FixedPower = value; } void addFixedPower(int value) { m_FixedPower += value; } @@ -33,6 +33,6 @@ class Player { protected: int m_MaxTroopSize = 200; int m_FixedPower = 0; - int m_TotalCurrency = 0; + float m_TotalCurrency = 0; }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_PLAYER_HPP diff --git a/include/Mechanics/UnitManager.hpp b/include/Mechanics/UnitManager.hpp index c9e49ea7..ee433bd1 100644 --- a/include/Mechanics/UnitManager.hpp +++ b/include/Mechanics/UnitManager.hpp @@ -78,7 +78,7 @@ class UnitManager : public Player { switch (unit) { case UnitType::INFANTRY: { auto avatar = std::make_shared(house); - + m_StructureManager->getStructureArray()->updateAvatarSpawnLocation(); if (m_StructureManager->getStructureArray() ->getPlayerBarrackCell() .x == -1) { @@ -88,11 +88,13 @@ class UnitManager : public Player { avatar->Start(m_StructureManager->getStructureArray() ->getPlayerBarrackCell()); + m_AvatarManager->assignMoveOrderToAvatar(avatar,{m_StructureManager->getStructureArray()->getPlayerWayPointCell()}); // assign order m_AvatarManager->assignMoveOrderToAvatar( avatar, m_StructureManager->getStructureArray() ->getPlayerWayPointCell()); m_AvatarManager->AppendAvatar(avatar); + m_troopSize+=1; } default: { @@ -109,6 +111,7 @@ class UnitManager : public Player { auto structure = std::make_shared(house); auto globalPos = MapUtil::CellCoordToGlobal(cellPos); structure->Start(globalPos); + structure->SetWayPointLocationByCellCoord({cellPos.x+2,cellPos.y-2}); m_StructureManager->getStructureArray()->buildNewStructure( structure, true); break; @@ -133,6 +136,7 @@ class UnitManager : public Player { auto structure = std::make_shared(house); auto globalPos = MapUtil::CellCoordToGlobal(cellPos); structure->Start(globalPos); + structure->SetWayPointLocationByCellCoord({cellPos.x+2,cellPos.y-2}); m_StructureManager->getStructureArray()->buildNewStructure( structure, true); break; @@ -149,7 +153,9 @@ class UnitManager : public Player { auto avatar = std::make_shared(house); avatar->Start(cellPos); // avatar ->setNewDestination(cellPos); + m_AvatarManager->assignMoveOrderToAvatar(avatar,{cellPos.x+1,cellPos.y+1}); m_AvatarManager->AppendAvatar(avatar); + m_troopSize+=1; break; } case UnitType::NONE: { @@ -163,47 +169,21 @@ class UnitManager : public Player { } } - // bool ifClosestEnemyInRange(glm::vec2 cell,HouseType myHouse,int - // range){ - // float closestDistance=500.f; - // if(myHouse==HouseType::MY){ - // for(auto i:m_EnemyUnitArray){ - // if(MapUtil::findDistance(cell,i->getCurrentCell())getCurrentCell()); - // } - // } - // }else{ - // for(auto i:m_PlayerUnitArray){ - // if(MapUtil::findDistance(cell,i->getCurrentCell())getCurrentCell()); - // } - // } - // } - // return closestDistance<=range; - // } - // - // std::shared_ptr findInRangeEnemy(glm::vec2 - // cell,HouseType myHouse,int range){ - // float closestDistance=500.f; - // std::shared_ptr ansUnit; - // if(myHouse==HouseType::MY){ - // for(auto i:m_EnemyUnitArray){ - // if(MapUtil::findDistance(cell,i->getCurrentCell())getCurrentCell()); - // ansUnit = i; - // } - // } - // }else{ - // for(auto i:m_PlayerUnitArray){ - // if(MapUtil::findDistance(cell,i->getCurrentCell())getCurrentCell()); - // ansUnit = i; - // } - // } - // } - // return ansUnit; - // } + void addUnitConstructCount(UnitType type, int value) { + unitCount[type] += value; + } + int getUnitConstructCount(UnitType type){ + return unitCount[type]; + } + int getAvatarCount(){ + return unitCount[UnitType::INFANTRY]; + } + void addAvatarCount(UnitType type,int value){ + unitCount[type] += value; + } + private: + std::unordered_map unitCount; std::shared_ptr m_CursorSelection = std::make_shared(); std::shared_ptr m_StructureManager = @@ -213,6 +193,7 @@ class UnitManager : public Player { std::shared_ptr m_Map = std::make_shared(); std::chrono::high_resolution_clock::time_point m_StartTime; double m_lastElapsed = 0.F; + int m_troopSize = 0; }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_UNITMANAGER_HPP diff --git a/include/Scene/MenuScene.hpp b/include/Scene/MenuScene.hpp index 5f60dd4f..357f03c7 100644 --- a/include/Scene/MenuScene.hpp +++ b/include/Scene/MenuScene.hpp @@ -6,10 +6,12 @@ #define PRACTICALTOOLSFORSIMPLEDESIGN_MENUSCENE_HPP #include "Scene/DefaultScene.hpp" #include "Scene/MapScene.hpp" +#include "SandBoxScene.hpp" #include "Scene/Scene.hpp" #include "TutorialScene.hpp" + class MenuScene : public Scene { - enum class SceneMode { DEFAULT, MAP, MENU, TUTORIAL }; + enum class SceneMode { DEFAULT, MAP, MENU, TUTORIAL, SANDBOX}; public: MenuScene() @@ -20,6 +22,7 @@ class MenuScene : public Scene { m_MapScene->Start(); m_DefaultScene->Start(); m_TutorialScene->Start(); + m_SandBoxScene->Start(); } void Update() override { @@ -41,6 +44,9 @@ class MenuScene : public Scene { if (Util::Input::IsKeyPressed(Util::Keycode::T)) { m_currentMode = SceneMode::TUTORIAL; } + if (Util::Input::IsKeyPressed(Util::Keycode::S)) { + m_currentMode = SceneMode::SANDBOX; + } } switch (m_currentMode) { @@ -53,6 +59,9 @@ class MenuScene : public Scene { case (SceneMode::TUTORIAL): m_TutorialScene->Update(); break; + case (SceneMode::SANDBOX): + m_SandBoxScene->Update(); + break; } } @@ -62,6 +71,7 @@ class MenuScene : public Scene { std::shared_ptr m_MapScene = std::make_shared(); std::shared_ptr m_DefaultScene = std::make_shared(); + std::shared_ptr m_SandBoxScene = std::make_shared(); Util::BGM m_BGM; std::shared_ptr m_ButtonSinglePlayer = std::make_shared( diff --git a/include/Scene/SandBoxScene.hpp b/include/Scene/SandBoxScene.hpp new file mode 100644 index 00000000..40c74675 --- /dev/null +++ b/include/Scene/SandBoxScene.hpp @@ -0,0 +1,37 @@ +// +// Created by nudle on 2024/4/28. +// + +#ifndef PRACTICALTOOLSFORSIMPLEDESIGN_SANDBOXSCENE_HPP +#define PRACTICALTOOLSFORSIMPLEDESIGN_SANDBOXSCENE_HPP +#include "AI/EnemyScripts.hpp" +#include "Cursor.hpp" +#include "Scene.hpp" +#include "Task.hpp" +#include "Util/Prop.hpp" +#include + +#define DEBUG_KEY P + + +class SandBoxScene : public Scene { + enum class Stages { STAGE1, STAGE2, STAGE3, STAGE4 ,START ,END}; +public: + SandBoxScene(){}; + ~SandBoxScene(){}; + void Start() override; + void Update() override; + void stageStart(); + void stageUpdate(); + +private: + SpriteSheet m_SpriteSheet; + std::shared_ptr m_Cursor = std::make_shared(); + Grid testGrid; + std::shared_ptr m_Enemy = + std::make_shared(SceneMode::TUTORIAL); + std::shared_ptr m_EnemyScripts = + std::make_shared(); + Stages m_stage = Stages::START; +}; +#endif // PRACTICALTOOLSFORSIMPLEDESIGN_SANDBOXSCENE_HPP diff --git a/include/Scene/TutorialScene.hpp b/include/Scene/TutorialScene.hpp index 461bbf35..1c706819 100644 --- a/include/Scene/TutorialScene.hpp +++ b/include/Scene/TutorialScene.hpp @@ -13,8 +13,11 @@ #define DEBUG_KEY P + enum class TutorialStages { STAGE1, STAGE2, STAGE3, STAGE4 }; + class TutorialScene : public Scene { + enum class Stages { STAGE1, STAGE2, STAGE3, STAGE4 }; public: TutorialScene(){}; ~TutorialScene(){}; diff --git a/src/AI/EnemyScripts.cpp b/src/AI/EnemyScripts.cpp new file mode 100644 index 00000000..0159d1df --- /dev/null +++ b/src/AI/EnemyScripts.cpp @@ -0,0 +1,178 @@ +// +// Created by nudle on 2024/5/23. +// +#include "AI/EnemyScripts.hpp" +void EnemyScripts::Start(std::shared_ptr GameObjectManager,std::shared_ptr EnemyObjectManager,std::shared_ptr map,bool active){ + m_GameObjectManager=GameObjectManager; + m_EnemyObjectManager = EnemyObjectManager; + m_Map=map; + m_active = active; +} + +void EnemyScripts::Update(){ + if(!m_active){ + return; + } + m_buildDeltaTime += m_Time.GetDeltaTime(); + m_avatarDeltaTime += m_Time.GetDeltaTime(); + m_mainDeltaTime += m_Time.GetDeltaTime(); + + if (m_buildDeltaTime >= m_buildingCDTime) { // update when CD over + m_buildDeltaTime = 0; + UpdateSpawnScript(SpawnMode::BUILDINGS); + } + if (m_avatarDeltaTime >= m_AvatarCDTime) { // update when CD over + m_avatarDeltaTime = 0; + UpdateSpawnScript(SpawnMode::AVATAR); + } + + if(m_mainDeltaTime>=1){ + m_mainDeltaTime=0; + if(m_buildingCDTime<1.f){ + m_EnemyObjectManager->addTotalCurrency(m_buildingCost/(-1.f)); + }else{ + m_EnemyObjectManager->addTotalCurrency(m_buildingCost/m_buildingCDTime*(-1.f)); + } + if(m_AvatarCDTime<1.f){ + m_EnemyObjectManager->addTotalCurrency(m_avatarCost/(-1.f)); + }else{ + m_EnemyObjectManager->addTotalCurrency(m_avatarCost/m_AvatarCDTime*(-1.f)); + } + modeUpdate(); + } + +} + +void EnemyScripts::modeUpdate(){ + if(!ifBuiltBasic()){ + buildBasic(); + } else{ + if(m_EnemyObjectManager->getAvatarCount()==0||(m_GameObjectManager->getAvatarCount()/m_EnemyObjectManager->getAvatarCount()>=2 && m_GameObjectManager->getAvatarCount()!=0)){ + //Defense mode , spawn Troop only + spawnUnit(); + }else{ + if(m_GameObjectManager->getAvatarCount()/m_EnemyObjectManager->getAvatarCount()<=0.5){ + //Attack , set all troop to attack mode , set defensive Troop = 0 + updateAllTroopStates(); + }else{ + //Safe now , build adv or spawn troop + if(!ifBuiltADV()){ + buildADV(); + spawnUnit(); + }else{ + spawnUnit(); + } + } + } + } + offensiveUpdate(); +} + +void EnemyScripts::setCDTime(float time,SpawnMode spawnMode,bool cheat){ + if(spawnMode==SpawnMode::AVATAR){ + if(m_EnemyObjectManager->getTotalPower()<=0){ + m_AvatarCDTime = time*2; + }else{ + m_AvatarCDTime = time; + } + } + if(spawnMode==SpawnMode::BUILDINGS){ + if(m_EnemyObjectManager->getTotalPower()<=0){ + m_buildingCDTime = time*2; + }else{ + m_buildingCDTime = time; + } + } + + if(cheat){ + m_AvatarCDTime*=CHEAT; + m_buildingCDTime*=CHEAT; + } +} + +void EnemyScripts::setCost(float cost,SpawnMode spawnMode){ + if(spawnMode==SpawnMode::AVATAR){ + m_avatarCost=cost; + } + if(spawnMode==SpawnMode::BUILDINGS){ + m_buildingCost=cost; + } +} + +void EnemyScripts::buildBasic(){ + if(m_selectedBuildingType!=UnitType::NONE){ + return; + } + if(m_EnemyObjectManager->getUnitConstructCount(UnitType::POWER_PLANT)<1 && m_EnemyObjectManager->getTotalCurrency()> 300 ){ + setCDTime(15.f,SpawnMode::BUILDINGS); + setCost(300,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::POWER_PLANT; + }else if(m_EnemyObjectManager->getUnitConstructCount(UnitType::ORE_REF)<1 && m_EnemyObjectManager->getTotalCurrency()> 2000){ + setCDTime(100.f,SpawnMode::BUILDINGS); + setCost(2000,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::ORE_REF; + }else if(m_EnemyObjectManager->getUnitConstructCount(UnitType::BARRACKS)<1 && m_EnemyObjectManager->getTotalCurrency()> 300){ + setCDTime(15.f,SpawnMode::BUILDINGS); + setCost(300,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::BARRACKS; + } +} + +void EnemyScripts::buildADV(){ + if(m_selectedBuildingType!=UnitType::NONE){ + return; + } + if(m_EnemyObjectManager->getUnitConstructCount(UnitType::WAR_FACT)<1 && m_EnemyObjectManager->getTotalCurrency()> 2000){ + setCDTime(100.f,SpawnMode::BUILDINGS); + setCost(2000,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::WAR_FACT; + }else if(m_EnemyObjectManager->getUnitConstructCount(UnitType::ADV_POWER_PLANT)<1 && m_EnemyObjectManager->getTotalCurrency()> 500){ + setCDTime(25.f,SpawnMode::BUILDINGS); + setCost(500,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::ADV_POWER_PLANT; + } +} + +void EnemyScripts::spawnUnit(){ + if(m_selectedAvatarType!=UnitType::NONE||m_EnemyObjectManager->getAvatarCount()>50){ + return; + } + if(m_EnemyObjectManager->getAvatarCount()<=25 && m_EnemyObjectManager->getTotalCurrency()> 100){ + setCDTime(5.f,SpawnMode::AVATAR); + setCost(100,SpawnMode::AVATAR); + m_selectedAvatarType = UnitType::INFANTRY; + } +} + +void EnemyScripts::UpdateSpawnScript(SpawnMode spawnMode){ + //issue , avatar spawn and structure spawn should be separated CD time , so can spawn avatar and structure same time + + if(spawnMode == SpawnMode::BUILDINGS){ + if(m_selectedBuildingType == UnitType::NONE){ + return; + } + m_GameObjectManager->spawn(m_Map,m_selectedBuildingType ,HouseType::ENEMY,{m_baseCell.x+constructCountX,m_baseCell.y+constructCountY}); + m_EnemyObjectManager->addUnitConstructCount(m_selectedBuildingType,1); + setCost(0,SpawnMode::BUILDINGS); + setCDTime(0.f,SpawnMode::BUILDINGS); + m_selectedBuildingType = UnitType::NONE; + + if(constructCountX>10){ + constructCountY+=5; + constructCountX=0; + }else{ + constructCountX+=5; + } + } + if(spawnMode == SpawnMode::AVATAR) { + if(m_selectedAvatarType == UnitType::NONE){ + return; + } + if(m_selectedAvatarType == UnitType::INFANTRY){ + m_GameObjectManager->spawn(m_Map,m_selectedAvatarType ,HouseType::ENEMY); + setCost(0,SpawnMode::AVATAR); + setCDTime(0.f,SpawnMode::AVATAR); + m_selectedAvatarType = UnitType::NONE; + } + } +} \ No newline at end of file diff --git a/src/Scene/SandBoxScene.cpp b/src/Scene/SandBoxScene.cpp new file mode 100644 index 00000000..f8974107 --- /dev/null +++ b/src/Scene/SandBoxScene.cpp @@ -0,0 +1,145 @@ +// +// Created by nudle on 2024/4/29. +// +#include "Scene/SandBoxScene.hpp" + +void SandBoxScene::Start() { + + LOG_TRACE("Start"); + m_Map->Init(100, 100); + m_GameObjectManager->Start(m_Map); + m_EnemyObjectManager->Start(m_Map); + m_UI.Start(m_Map, m_GameObjectManager); + m_GameObjectManager->setTotalCurrency(5000); + m_EnemyObjectManager->setTotalCurrency(5000); + m_SceneCamera->Start(MapUtil::CellCoordToGlobal(glm::vec2(-10, -10)), + MapUtil::CellCoordToGlobal(glm::vec2(100, 100))); + + +} +void SandBoxScene::Update() { + m_GameObjectManager->Update(); + m_EnemyObjectManager->Update(); + if(m_stage != Stages::START){ + m_EnemyScripts->Update(); + } + stageUpdate(); + Util::Transform trans; + m_Map->Draw(trans, 0); + m_SceneCamera->Update(); + m_Renderer.Update(); + m_UI.Update(); + + // temperarory place here + auto tileLocation = MapUtil::GlobalCoordToCellCoord( + MapUtil::ScreenToGlobalCoord(Util::Input::GetCursorPosition())); + if (tileLocation.x >= 0 && tileLocation.y >= 0) { + m_Cursor->Update(m_Map->getTileByCellPosition(tileLocation)); + } + + auto tile = m_Map->getTileByCellPosition(MapUtil::GlobalCoordToCellCoord( + MapUtil::ScreenToGlobalCoord(Util::Input::GetCursorPosition()))); + + if (m_UI.getIfAnyBuildingReadyToBuild()) { + m_GameObjectManager->getStructureManager()->AddStructSelectingBuiltSite( + m_UI.getSelectedBuilding()); + } + m_UI.checkExistBuilding(*m_GameObjectManager->getStructureManager() + ->getStructureArray() + ->getBuiltStructureArray()); + if (m_UI.getIfUnitReadyToSpawn()) { + m_GameObjectManager->getAvatarManager()->AppendAvatar( + m_UI.getUnitFromUI()); + } +} +void SandBoxScene::stageStart() { + switch (m_stage) { + case Stages::STAGE1: { + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 5}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 6}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 7}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 8}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 9}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 5}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 6}); + m_stage = Stages::END; + break; + } + case Stages::STAGE2: { + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 5}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 6}); + + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 5}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 6}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 7}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 8}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 9}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 10}); + m_stage = Stages::END; + break; + } + case Stages::STAGE3: { + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 5}); + m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, + {5, 6}); + + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 5}); + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {10, 6}); + m_stage = Stages::END; + break; + } + case Stages::STAGE4: { + for(int i=0;i<50;i++){ + m_EnemyObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::ENEMY, + {30+i/5, 5+i%5}); + } + m_stage = Stages::END; + break; + } + } +} +void SandBoxScene::stageUpdate() { + if(m_stage == Stages::START){ + if (Util::Input::IsKeyPressed(Util::Keycode::NUM_1 )) { + m_stage = Stages::STAGE1; + m_EnemyScripts->Start(m_GameObjectManager, m_EnemyObjectManager, m_Map); + stageStart(); + } + if (Util::Input::IsKeyPressed(Util::Keycode::NUM_2 )) { + m_stage = Stages::STAGE2; + m_EnemyScripts->Start(m_GameObjectManager, m_EnemyObjectManager, m_Map); + stageStart(); + } + if (Util::Input::IsKeyPressed(Util::Keycode::NUM_3 )) { + m_stage = Stages::STAGE3; + m_EnemyScripts->Start(m_GameObjectManager, m_EnemyObjectManager, m_Map); + stageStart(); + } + if (Util::Input::IsKeyPressed(Util::Keycode::NUM_4 )) { + m_stage = Stages::STAGE4; + m_EnemyScripts->Start(m_GameObjectManager, m_EnemyObjectManager, m_Map, false); + stageStart(); + } + } + if (Util::Input::IsKeyPressed(Util::Keycode::DEBUG_KEY )) { + m_Enemy->addTotalCurrency(500); + } +} diff --git a/src/Scene/TutorialScene.cpp b/src/Scene/TutorialScene.cpp index fb0d1542..fca90702 100644 --- a/src/Scene/TutorialScene.cpp +++ b/src/Scene/TutorialScene.cpp @@ -15,7 +15,7 @@ void TutorialScene::Start() { m_SceneCamera->Start(MapUtil::CellCoordToGlobal(glm::vec2(-10, -10)), MapUtil::CellCoordToGlobal(glm::vec2(100, 100))); - m_EnemyScripts->Start(m_Enemy, m_EnemyObjectManager, m_Map); +// m_EnemyScripts->Start(m_Enemy,m_GameObjectManager, m_EnemyObjectManager, m_Map); m_GameObjectManager->spawn(m_Map, UnitType::INFANTRY, HouseType::MY, {5, 5});