diff --git a/CMakeLists.txt b/CMakeLists.txt index aef3ce2e..c5478fc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,8 @@ set(SRC_FILES ${SRC_DIR}/Structure/WayPointStructure.cpp ${SRC_DIR}/Unit/PathfindingUnit.cpp - + ${SRC_DIR}/Unit/Runner.cpp + ${SRC_DIR}/Unit/Hunter.cpp ${SRC_DIR}/Scene/DefaultScene.cpp ${SRC_DIR}/Camera.cpp @@ -163,6 +164,8 @@ set(INCLUDE_FILES ${INCLUDE_DIR}/Unit/PathfindingUnit.hpp ${INCLUDE_DIR}/Unit/Avatar.hpp ${INCLUDE_DIR}/Unit/WayPointUnit.hpp + ${INCLUDE_DIR}/Unit/Runner.hpp + ${INCLUDE_DIR}/Unit/Hunter.hpp ${INCLUDE_DIR}/imgui/imconfig.h ${INCLUDE_DIR}/imgui/imgui.h diff --git a/assets/sprites/Hunter.png b/assets/sprites/Hunter.png new file mode 100644 index 00000000..d8372b4a Binary files /dev/null and b/assets/sprites/Hunter.png differ diff --git a/assets/sprites/Runner.png b/assets/sprites/Runner.png new file mode 100644 index 00000000..d8eb522f Binary files /dev/null and b/assets/sprites/Runner.png differ diff --git a/assets/sprites/temp_Bullet.png b/assets/sprites/temp_Bullet.png new file mode 100644 index 00000000..c432dbe6 Binary files /dev/null and b/assets/sprites/temp_Bullet.png differ diff --git a/include/GameObjectManager.hpp b/include/GameObjectManager.hpp index bf62fa0b..01660b68 100644 --- a/include/GameObjectManager.hpp +++ b/include/GameObjectManager.hpp @@ -71,6 +71,7 @@ class GameObjectManager { void Append(std::shared_ptr newstruct) { newstruct->Start(); +// newstruct->importMap(m_Map); m_BuiltStructure.push_back(newstruct); } void Append(std::shared_ptr newUnit) { diff --git a/include/Scene/DefaultScene.hpp b/include/Scene/DefaultScene.hpp index f1d2d79f..1d0b34c8 100644 --- a/include/Scene/DefaultScene.hpp +++ b/include/Scene/DefaultScene.hpp @@ -23,6 +23,8 @@ #include "UI/UI.hpp" #include "Unit/Avatar.hpp" #include "Unit/FindValidPathToDest.hpp" +#include "Unit/Hunter.hpp" +#include "Unit/Runner.hpp" #include "Unit/PathfindingUnit.hpp" #include "Util/Image.hpp" #include "Util/Input.hpp" @@ -52,6 +54,8 @@ class DefaultScene { std::shared_ptr m_Manager = std::make_shared(); Avatar m_dummy; + std::shared_ptr m_hunter=std::make_shared(); + std::shared_ptr m_runner=std::make_shared(); }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_DEFAULTSCENE_HPP diff --git a/include/Structure/Structure.hpp b/include/Structure/Structure.hpp index 17ef3bd3..c7782ca6 100644 --- a/include/Structure/Structure.hpp +++ b/include/Structure/Structure.hpp @@ -89,6 +89,7 @@ class Structure : public Util::GameObject, public Selectable { float GetBuildingHp(); GameObjectID GetID() { return m_ID; } +// void importMap(std::shared_ptr map){m_Map=map;} private: updateMode m_CurrentState = updateMode::Invisidable; glm::vec2 ObjectLocation = {100, 100}; @@ -103,6 +104,7 @@ class Structure : public Util::GameObject, public Selectable { GameObjectID m_ID; protected: +// std::shared_ptr m_Map; bool b_selectingNewWayPoint = false; }; diff --git a/include/Unit/AttackAndDamageUnit.hpp b/include/Unit/AttackAndDamageUnit.hpp index 295b9a04..d18d2699 100644 --- a/include/Unit/AttackAndDamageUnit.hpp +++ b/include/Unit/AttackAndDamageUnit.hpp @@ -5,6 +5,7 @@ #ifndef PRACTICALTOOLSFORSIMPLEDESIGN_ATTACKANDDAMAGEUNIT_HPP #define PRACTICALTOOLSFORSIMPLEDESIGN_ATTACKANDDAMAGEUNIT_HPP #include "Weapon.hpp" + class AttackAndDamageUnit { public: AttackAndDamageUnit() {} diff --git a/include/Unit/Avatar.hpp b/include/Unit/Avatar.hpp index 35d87b21..e6f0c69b 100644 --- a/include/Unit/Avatar.hpp +++ b/include/Unit/Avatar.hpp @@ -9,6 +9,8 @@ #include "Unit/PathfindingUnit.hpp" class Avatar : public PathfindingUnit, public AttackAndDamageUnit { +protected: + std::shared_ptr m_Image; private: FindValidPathToDest m_wayPointUnit; bool b_SelectedByCursor = true; @@ -24,7 +26,7 @@ class Avatar : public PathfindingUnit, public AttackAndDamageUnit { // waypointLocation // setCurrentCell() //CurrentCell = Structure's Location this->SetDrawable( - std::make_unique("../assets/sprites/capybara.png")); + customizeImage()); SetVisible(true); m_grid.SetActivate(true); m_wayPointUnit.Start(map); @@ -51,6 +53,8 @@ class Avatar : public PathfindingUnit, public AttackAndDamageUnit { cursorSetNewDest(); printf("-----------------------------\n"); } + virtual void customizeUpdate(){} + virtual std::shared_ptr customizeImage(){ return std::make_unique("../assets/sprites/capybara.png");} virtual void Update() override { switch (m_currentMode) { case (UnitMode::DEAD): { @@ -58,6 +62,7 @@ class Avatar : public PathfindingUnit, public AttackAndDamageUnit { } case (UnitMode::ALIVE): { aliveUpdate(); + customizeUpdate(); } } } @@ -77,5 +82,49 @@ class Avatar : public PathfindingUnit, public AttackAndDamageUnit { Util::Input::GetCursorPosition()))); } } + float getDistance(glm::vec2 cell){ + return sqrt(pow(cell.x-getCurrentCell().x,2)+pow(cell.y-getCurrentCell().y,2)); + } + + void DEBUG_printCurrentMoveDirection(MoveDirection Dir){ + switch (Dir) { + case MoveDirection::RIGHT: { + printf("(DEBUG)Avatar DIR:Right\n"); + break; + } + case MoveDirection::LEFT: { + printf("(DEBUG)Avatar DIR:Left\n"); + break; + } + case MoveDirection::UP: { + printf("(DEBUG)Avatar DIR:Up\n"); + break; + } + case MoveDirection::DOWN: { + printf("(DEBUG)Avatar DIR:Down\n"); + break; + } + case MoveDirection::UP_RIGHT: { + printf("(DEBUG)Avatar DIR:Up_Right\n"); + break; + } + case MoveDirection::DOWN_LEFT: { + printf("(DEBUG)Avatar DIR:Down_Left\n"); + break; + } + case MoveDirection::DOWN_RIGHT: { + printf("(DEBUG)Avatar DIR:Down_Right\n"); + break; + } + case MoveDirection::UP_LEFT: { + printf("(DEBUG)Avatar DIR:Up_Left\n"); + break; + } + case MoveDirection::IDLE: { + printf("(DEBUG)Avatar DIR:IDLE\n"); + break; + } + } + } }; #endif // PRACTICALTOOLSFORSIMPLEDESIGN_DUMMY_HPP diff --git a/include/Unit/Hunter.hpp b/include/Unit/Hunter.hpp new file mode 100644 index 00000000..a5eb938d --- /dev/null +++ b/include/Unit/Hunter.hpp @@ -0,0 +1,23 @@ +// +// Created by nudle on 2024/3/28. +// + +#ifndef PRACTICALTOOLSFORSIMPLEDESIGN_HUNTER_HPP +#define PRACTICALTOOLSFORSIMPLEDESIGN_HUNTER_HPP +#include "Avatar.hpp" +#include "Runner.hpp" + +#define ATTACK_RANGE 7 + +class Hunter:public Avatar{ +private: + std::shared_ptr m_target; + glm::vec2 lastTargetCell; + +public: + void setTarget(std::shared_ptr m_target){this->m_target=m_target;} + std::shared_ptr customizeImage()override{ return std::make_unique("../assets/sprites/Hunter.png");} + void customizeUpdate() override; + void attack(std::shared_ptr attackTarget){}; +}; +#endif // PRACTICALTOOLSFORSIMPLEDESIGN_HUNTER_HPP diff --git a/include/Unit/PathfindingUnit.hpp b/include/Unit/PathfindingUnit.hpp index 1eac15dd..8c565735 100644 --- a/include/Unit/PathfindingUnit.hpp +++ b/include/Unit/PathfindingUnit.hpp @@ -56,7 +56,7 @@ class PathfindingUnit : public Util::GameObject { virtual ~PathfindingUnit(){}; // - + UnitMode getUnitMode(){return m_currentMode;} void setDestinationCell(int x, int y) { this->m_destinationCell = {glm::vec2(x, y)}; } diff --git a/include/Unit/Runner.hpp b/include/Unit/Runner.hpp new file mode 100644 index 00000000..784cab8e --- /dev/null +++ b/include/Unit/Runner.hpp @@ -0,0 +1,31 @@ +// +// Created by nudle on 2024/3/28. +// + +#ifndef PRACTICALTOOLSFORSIMPLEDESIGN_RUNNER_HPP +#define PRACTICALTOOLSFORSIMPLEDESIGN_RUNNER_HPP +#include "Avatar.hpp" +#define ATTACK_RANGE 7 + +class Runner : public Avatar{ +private: + bool b_beingChase= false; + + std::shared_ptr m_hunter; + glm::vec2 lastTargetCell; + std::vector dictionary = { + MoveDirection::UP, MoveDirection::UP_RIGHT, + MoveDirection::RIGHT, MoveDirection::DOWN_RIGHT, + MoveDirection::DOWN, MoveDirection::DOWN_LEFT, + MoveDirection::LEFT, MoveDirection::UP_LEFT}; + enum class runMode{REASONABLE,LIDL_RANDOM,FULL_RANDOM}; + int edgeCount=0; +public: + void setBeingChase(std::shared_ptr hunter); + std::shared_ptr customizeImage()override{ return std::make_unique("../assets/sprites/Runner.png");} + void customizeUpdate()override; + MoveDirection findNewDir(MoveDirection Dir,int edgeCount); + MoveDirection oppositeDir(MoveDirection Dir,runMode mode); + glm::vec2 getNextCellByCurrentPlus3(MoveDirection currentdir,glm::vec2 currentcell,int n,int m) ; +}; +#endif // PRACTICALTOOLSFORSIMPLEDESIGN_RUNNER_HPP diff --git a/include/Unit/Weapon.hpp b/include/Unit/Weapon.hpp index 0878f49f..4a669c7f 100644 --- a/include/Unit/Weapon.hpp +++ b/include/Unit/Weapon.hpp @@ -4,6 +4,7 @@ #ifndef PRACTICALTOOLSFORSIMPLEDESIGN_WEAPON_HPP #define PRACTICALTOOLSFORSIMPLEDESIGN_WEAPON_HPP +#include enum class WeaponType { COLT_45, M16, diff --git a/src/Scene/DefaultScene.cpp b/src/Scene/DefaultScene.cpp index 4df7e75d..30b69d7f 100644 --- a/src/Scene/DefaultScene.cpp +++ b/src/Scene/DefaultScene.cpp @@ -32,11 +32,21 @@ void DefaultScene::Start() { m_Player->setTotalCurrency(5000); + +// m_hunter->setCurrentCell({20,10}); +// m_runner->setCurrentCell({10,10}); + m_hunter->Start({20,9},m_Map); + m_runner->Start({9,10},m_Map); + m_hunter->setTarget(m_runner); + m_runner->setBeingChase(m_hunter); } void DefaultScene::Update() { //m_dummy.Update(); + m_hunter->Update(); + m_runner->Update(); + m_Manager->Update(); Util::Transform trans; diff --git a/src/Structure/Structure.cpp b/src/Structure/Structure.cpp index 9af20f8a..3f385af9 100644 --- a/src/Structure/Structure.cpp +++ b/src/Structure/Structure.cpp @@ -47,11 +47,12 @@ void Structure::updateMoveable() { this->SetVisible(true); this->Draw(); glm::vec2 cellPos = MapUtil::GlobalCoordToCellCoord(location); - if (Util::Input::IsKeyPressed( - Util::Keycode:: - MOUSE_LB) /*&&MapClass::getTileByCellPosition(cellPos)->getBuildable()*/) { +// std::shared_ptr tileClass = m_Map->getTileByCellPosition(cellPos); + if (Util::Input::IsKeyPressed(Util::Keycode::MOUSE_LB) /*tileClass->getBuildable()*/) { this->SetObjectLocation(location); this->SetCurrentUpdateMode(updateMode::Fixed); +// tileClass->setBuildable(false); +// tileClass->setWalkable(false); // 在這裡增加設置Tile屬性 /* std::shared_ptrtile = diff --git a/src/Structure/WayPointStructure.cpp b/src/Structure/WayPointStructure.cpp index 6ef204cf..475c2cc2 100644 --- a/src/Structure/WayPointStructure.cpp +++ b/src/Structure/WayPointStructure.cpp @@ -13,14 +13,15 @@ void WayPointStructure::updateMoveable() { this->SetVisible(true); this->Draw(); glm::vec2 cellPos = MapUtil::GlobalCoordToCellCoord(location); - if (Util::Input::IsKeyPressed( - Util::Keycode:: - MOUSE_LB) /*&&MapClass::getTileByCellPosition(cellPos)->getBuildable()*/) { +// std::shared_ptr tileClass = m_Map->getTileByCellPosition(cellPos); + if (Util::Input::IsKeyPressed(Util::Keycode::MOUSE_LB) /*tileClass->getBuildable()*/) { this->SetObjectLocation(location); this->SetWayPointLocation({GetDrawLocation().x + CELL_SIZE.x, GetDrawLocation().y + CELL_SIZE.y}); onSelected(); this->SetCurrentUpdateMode(updateMode::Fixed); +// tileClass->setBuildable(false); +// tileClass->setWalkable(false); // 在這裡增加設置Tile屬性 /* std::shared_ptrtile = diff --git a/src/Unit/Hunter.cpp b/src/Unit/Hunter.cpp new file mode 100644 index 00000000..9d55f6f2 --- /dev/null +++ b/src/Unit/Hunter.cpp @@ -0,0 +1,20 @@ +// +// Created by nudle on 2024/3/29. +// + +#include "Unit/Hunter.hpp" + +void Hunter::customizeUpdate(){ + glm::vec2 targetCell = m_target->getCurrentCell(); + if(getDistance(targetCell)>ATTACK_RANGE-1 && lastTargetCell!=m_target->getCurrentCell()){ + // glm::vec2 nextCell = getNextCellByCurrent(getDirByRelativeCells(getCurrentCell(),targetCell),getCurrentCell()); + setNewDestination(m_target->getCurrentCell()); + lastTargetCell=m_target->getCurrentCell(); + // setNewDestination(nextCell); + } + else if(getDistance(targetCell) hunter){ + b_beingChase=true; + m_hunter=hunter; + lastTargetCell=getCurrentCell(); +} +void Runner::customizeUpdate(){ + if(b_beingChase && m_hunter->getUnitMode()==UnitMode::ALIVE){ + glm::vec2 hunterCell = m_hunter->getCurrentCell(); + if(getDistance(hunterCell)<=ATTACK_RANGE-1 && lastTargetCell==getCurrentCell()){ + edgeCount=0; + MoveDirection Dir = oppositeDir(getDirByRelativeCells(getCurrentCell(),hunterCell),runMode::LIDL_RANDOM); + DEBUG_printCurrentMoveDirection(Dir); + glm::vec2 nextCell = getNextCellByCurrentPlus3(Dir,getCurrentCell(),3,1); + while(nextCell.x<0 || nextCell.y<0){ + edgeCount+=rand() %2+1; + Dir=findNewDir(Dir,edgeCount); + DEBUG_printCurrentMoveDirection(Dir); + nextCell = getNextCellByCurrentPlus3(Dir,getCurrentCell(),1,3); + } + lastTargetCell=nextCell; + setNewDestination(nextCell); + + } + }else{ + b_beingChase=false; + } +} + +PathfindingUnit::MoveDirection Runner::findNewDir(MoveDirection Dir,int edgeCount){ + for(int i=0;i<8;i++){ + if(dictionary[i]==Dir){ + int index = (i+edgeCount)%8; + if(index<0){ + index+=8; + } + return dictionary[index]; + } + } +} + +PathfindingUnit::MoveDirection Runner::oppositeDir(MoveDirection Dir,runMode mode){ + switch (mode) { + case (runMode::REASONABLE):{ + for(int i=0;i<8;i++){ + if(dictionary[i]==Dir){ + if(i+3>7){ + return dictionary[i+3-7]; + }else{ + return dictionary[i+3]; + } + } + } + } + case runMode::LIDL_RANDOM:{ + for(int i=0;i<8;i++){ + if(dictionary[i]==Dir){ + int index = i+3-7+rand()%3-1; + if(index<0){ + return dictionary[index+8]; + }else{ + return dictionary[index]; + } + } + } + } + case runMode::FULL_RANDOM:{ + return dictionary[rand()%8+0]; + } + } +} + +glm::vec2 Runner::getNextCellByCurrentPlus3(MoveDirection currentdir,glm::vec2 currentcell,int n,int m) { + switch (currentdir) { + case MoveDirection::RIGHT: { + currentcell = {currentcell.x + n, currentcell.y}; + break; + } + case MoveDirection::LEFT: { + currentcell = {currentcell.x - n, currentcell.y}; + break; + } + case MoveDirection::UP: { + currentcell = {currentcell.x, currentcell.y + n}; + break; + } + case MoveDirection::DOWN: { + currentcell = {currentcell.x, currentcell.y - n}; + break; + } + case MoveDirection::UP_RIGHT: { + currentcell = {currentcell.x + m, currentcell.y + m}; + break; + } + case MoveDirection::DOWN_LEFT: { + currentcell = {currentcell.x - m, currentcell.y - m}; + break; + } + case MoveDirection::DOWN_RIGHT: { + currentcell = {currentcell.x + m, currentcell.y - m}; + break; + } + case MoveDirection::UP_LEFT: { + currentcell = {currentcell.x - m, currentcell.y + m}; + break; + } + case MoveDirection::IDLE: { + printf("Direction debug didn't move\n"); + break; + } + } + return currentcell; +}