diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/crepe/api/AI.h | 14 | ||||
-rw-r--r-- | src/crepe/system/AISystem.cpp | 34 | ||||
-rw-r--r-- | src/crepe/system/AISystem.h | 2 | ||||
-rw-r--r-- | src/example/AITest.cpp | 21 |
4 files changed, 60 insertions, 11 deletions
diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h index d4bd9d3..35b8998 100644 --- a/src/crepe/api/AI.h +++ b/src/crepe/api/AI.h @@ -36,6 +36,8 @@ public: if (on(PATH_FOLLOW)) flags ^= PATH_FOLLOW; } + void add_path_node(vec2 node) { path.push_back(node); } + public: float max_force; @@ -47,9 +49,21 @@ public: float square_flee_panic_distance = 200.0f * 200.0f; // The deceleration rate for the arrive behavior (higher values will make the entity decelerate faster (less overshoot)) float arrive_deceleration = 40.0f; + // The path to follow + std::vector<vec2> path; + // The distance from the path node at which the entity will move to the next node + float path_node_distance = 400.0f; + // Looping behavior for the path + bool path_loop = true; private: + // The flags for the behaviors int flags = 0; + // The current path index + size_t path_index = 0; + + // The AISystem is the only class that can access the private members of AI + friend class AISystem; }; } // namespace crepe diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp index ce3147f..55dc14c 100644 --- a/src/crepe/system/AISystem.cpp +++ b/src/crepe/system/AISystem.cpp @@ -55,11 +55,11 @@ vec2 AISystem::calculate(AI & ai) { } } if (ai.on(AI::BehaviorType::PATH_FOLLOW)) { - /*vec2 force_to_add = this->path_follow(ai); + vec2 force_to_add = this->path_follow(ai); if (!this->accumulate_force(ai, force, force_to_add)) { return force; - }*/ + } } return force; @@ -138,3 +138,33 @@ vec2 AISystem::arrive(const AI & ai) { return vec2{0, 0}; } + +vec2 AISystem::path_follow(AI & ai) { + const Mediator & mediator = this->mediator; + ComponentManager & mgr = mediator.component_manager; + RefVector<Transform> transforms = mgr.get_components_by_id<Transform>(ai.game_object_id); + Transform & transform = transforms.front().get(); + RefVector<Rigidbody> rigidbodies = mgr.get_components_by_id<Rigidbody>(ai.game_object_id); + Rigidbody & rigidbody = rigidbodies.front().get(); + + if (ai.path.empty()) { + return vec2{0, 0}; + } + + vec2 to_target = ai.path.at(ai.path_index) - transform.position; + if (to_target.length_squared() > ai.path_node_distance * ai.path_node_distance) { + ai.seek_target = ai.path.at(ai.path_index); + } else { + ai.path_index++; + if (ai.path_index >= ai.path.size()) { + if (ai.path_loop) { + ai.path_index = 0; + } else { + ai.path_index = ai.path.size() - 1; + return this->arrive(ai); + } + } + } + + return this->seek(ai); +} diff --git a/src/crepe/system/AISystem.h b/src/crepe/system/AISystem.h index 18f1c61..27861d9 100644 --- a/src/crepe/system/AISystem.h +++ b/src/crepe/system/AISystem.h @@ -20,7 +20,7 @@ private: vec2 seek(const AI & ai); vec2 flee(const AI & ai); vec2 arrive(const AI & ai); - vec2 path_follow(const AI & ai); + vec2 path_follow(AI & ai); }; } // namespace crepe diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp index 319d0fe..d12a99a 100644 --- a/src/example/AITest.cpp +++ b/src/example/AITest.cpp @@ -25,10 +25,10 @@ class Script1 : public Script { } bool mousemove(const MouseMoveEvent & event) { - RefVector<AI> aivec = this->get_components<AI>(); + /*RefVector<AI> aivec = this->get_components<AI>(); AI & ai = aivec.front().get(); ai.flee_target - = vec2{static_cast<float>(event.mouse_x), static_cast<float>(event.mouse_y)}; + = vec2{static_cast<float>(event.mouse_x), static_cast<float>(event.mouse_y)};*/ return true; } @@ -46,21 +46,26 @@ public: Mediator & mediator = this->mediator; ComponentManager & mgr = mediator.component_manager; - GameObject game_object1 = mgr.new_object("", "", vec2{250, 250}, 0, 1); + GameObject game_object1 = mgr.new_object("", "", vec2{0, 0}, 0, 1); GameObject game_object2 = mgr.new_object("", "", vec2{0, 0}, 0, 1); Texture img = Texture("asset/texture/test_ap43.png"); game_object1.add_component<Sprite>(img, Color::MAGENTA, Sprite::FlipSettings{false, false}, 1, 1, 195); - AI & ai = game_object1.add_component<AI>(30); - ai.arrive_on(); - ai.flee_on(); + AI & ai = game_object1.add_component<AI>(300); + // ai.arrive_on(); + // ai.flee_on(); + ai.path_follow_on(); + ai.add_path_node(vec2{1200, 1200}); + ai.add_path_node(vec2{-1200, 1200}); + ai.add_path_node(vec2{1200, -1200}); + ai.add_path_node(vec2{-1200, -1200}); game_object1.add_component<Rigidbody>(Rigidbody::Data{ - .mass = 0.5f, .max_linear_velocity = {21, 21}, // sqrt(21^2 + 21^2) = 30 + .mass = 0.5f, .max_linear_velocity = {50, 50}, // sqrt(21^2 + 21^2) = 30 }); game_object1.add_component<BehaviorScript>().set_script<Script1>(); - game_object2.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{1036, 780}, + game_object2.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{5000, 5000}, 1.0f); } |