aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax-001 <maxsmits21@kpnmail.nl>2024-12-09 14:14:03 +0100
committermax-001 <maxsmits21@kpnmail.nl>2024-12-09 14:14:03 +0100
commit857e408d6d3a8631b61ebd283b337819783f092c (patch)
treeeb201efe09f033187c2ce9c51f68f0239e548a5d
parentcdaf587006053874c2e286a7541e6a2b246ce2b3 (diff)
Implemented oval path
-rw-r--r--src/crepe/api/AI.cpp46
-rw-r--r--src/crepe/api/AI.h14
-rw-r--r--src/example/AITest.cpp4
3 files changed, 62 insertions, 2 deletions
diff --git a/src/crepe/api/AI.cpp b/src/crepe/api/AI.cpp
index 49f6b92..00e5b37 100644
--- a/src/crepe/api/AI.cpp
+++ b/src/crepe/api/AI.cpp
@@ -27,4 +27,50 @@ void AI::make_circle_path(float radius, vec2 center, float start_angle, bool clo
}
}
+void AI::make_oval_path(float radius_x, float radius_y, vec2 center, float start_angle,
+ bool clockwise, float rotation) {
+ float max_radius = std::max(radius_x, radius_y);
+ // The step size is determined by the radius (step size is in radians)
+ float step = 400.0f / max_radius;
+ // Force at least 16 steps (in case of a small radius)
+ if (step > 2 * M_PI / 16) {
+ step = 2 * M_PI / 16;
+ }
+ // The path node distance is determined by the step size and the radius
+ path_node_distance = max_radius * step * 0.75f;
+
+ auto rotate_point = [rotation](vec2 point, vec2 center) {
+ float s = sin(rotation);
+ float c = cos(rotation);
+
+ // Translate point back to origin
+ point.x -= center.x;
+ point.y -= center.y;
+
+ // Rotate point
+ float xnew = point.x * c - point.y * s;
+ float ynew = point.x * s + point.y * c;
+
+ // Translate point back
+ point.x = xnew + center.x;
+ point.y = ynew + center.y;
+
+ return point;
+ };
+
+ if (clockwise) {
+ for (float i = start_angle; i < 2 * M_PI + start_angle; i += step) {
+ vec2 point = {static_cast<float>(center.x + radius_x * cos(i)),
+ static_cast<float>(center.y + radius_y * sin(i))};
+ path.push_back(rotate_point(point, center));
+ }
+ } else {
+ for (float i = start_angle; i > start_angle - 2 * M_PI; i -= step) {
+ vec2 point = {static_cast<float>(center.x + radius_x * cos(i)),
+ static_cast<float>(center.y + radius_y * sin(i))};
+ path.push_back(rotate_point(point, center));
+ }
+ }
+}
+
} // namespace crepe
diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h
index 0dccd5f..c95924d 100644
--- a/src/crepe/api/AI.h
+++ b/src/crepe/api/AI.h
@@ -81,6 +81,20 @@ public:
*/
void make_circle_path(float radius, vec2 center = {0, 0}, float start_angle = 0,
bool clockwise = true);
+ /**
+ * \brief Make an oval path (for the path following behavior)
+ *
+ * \note The path is not relative to the entity's position (it is an absolute path)
+ *
+ * \param radius_x The x radius of the oval (in game units)
+ * \param radius_y The y radius of the oval (in game units)
+ * \param center The center of the oval (in game units)
+ * \param start_angle The start angle of the oval (in radians)
+ * \param clockwise The direction of the oval
+ * \param rotation The rotation of the oval (in radians)
+ */
+ void make_oval_path(float radius_x, float radius_y, vec2 center = {0, 0},
+ float start_angle = 0, bool clockwise = true, float rotation = 0);
public:
//! The maximum force that can be applied to the entity (higher values will make the entity adjust faster)
diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp
index 28537ed..f4efc9f 100644
--- a/src/example/AITest.cpp
+++ b/src/example/AITest.cpp
@@ -59,8 +59,8 @@ public:
// ai.arrive_on();
// ai.flee_on();
ai.path_follow_on();
- ai.make_circle_path(1000, {0, -1000}, 1.5707, true);
- ai.make_circle_path(1000, {0, 1000}, 4.7124, false);
+ ai.make_oval_path(500, 1000, {0, -1000}, 1.5708, true);
+ ai.make_oval_path(1000, 500, {0, 500}, 4.7124, false);
game_object1.add_component<Rigidbody>(Rigidbody::Data{
.mass = 0.1f,
.max_linear_velocity = {40, 40},