aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax-001 <maxsmits21@kpnmail.nl>2024-12-06 17:14:00 +0100
committermax-001 <maxsmits21@kpnmail.nl>2024-12-06 17:14:00 +0100
commit33a072db28d71ba65e59f9491abd42dbf9695fc4 (patch)
treedc911454f5cc98198ac55370bb1bffd6aee3b053
parent0d0943d23364d7110f0232e3564f4ea63af13db2 (diff)
Implemented path_follow
-rw-r--r--src/crepe/api/AI.h14
-rw-r--r--src/crepe/system/AISystem.cpp34
-rw-r--r--src/crepe/system/AISystem.h2
-rw-r--r--src/example/AITest.cpp21
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);
}