aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mwe/events/include/event.h2
-rw-r--r--src/crepe/api/AI.cpp7
-rw-r--r--src/crepe/api/AI.h55
-rw-r--r--src/crepe/api/CMakeLists.txt2
-rw-r--r--src/crepe/api/LoopManager.cpp10
-rw-r--r--src/crepe/api/Rigidbody.h1
-rw-r--r--src/crepe/api/Script.h2
-rw-r--r--src/crepe/api/Vector2.h24
-rw-r--r--src/crepe/api/Vector2.hpp48
-rw-r--r--src/crepe/system/AISystem.cpp85
-rw-r--r--src/crepe/system/AISystem.h26
-rw-r--r--src/crepe/system/CMakeLists.txt2
-rw-r--r--src/crepe/system/CollisionSystem.cpp38
-rw-r--r--src/crepe/system/CollisionSystem.h6
-rw-r--r--src/example/AITest.cpp63
-rw-r--r--src/example/CMakeLists.txt1
-rw-r--r--src/example/game.cpp98
-rw-r--r--src/test/CollisionTest.cpp6
-rw-r--r--src/test/Profiling.cpp6
-rw-r--r--src/test/Vector2Test.cpp148
20 files changed, 543 insertions, 87 deletions
diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h
index ee1bf52..e1b220b 100644
--- a/mwe/events/include/event.h
+++ b/mwe/events/include/event.h
@@ -148,7 +148,7 @@ private:
};
class ShutDownEvent : public Event {
public:
- ShutDownEvent() : Event("ShutDownEvent") {};
+ ShutDownEvent() : Event("ShutDownEvent"){};
REGISTER_EVENT_TYPE(ShutDownEvent)
diff --git a/src/crepe/api/AI.cpp b/src/crepe/api/AI.cpp
new file mode 100644
index 0000000..d785bb5
--- /dev/null
+++ b/src/crepe/api/AI.cpp
@@ -0,0 +1,7 @@
+#include "AI.h"
+
+namespace crepe {
+
+AI::AI(game_object_id_t id, float max_force) : Component(id), max_force(max_force) {}
+
+} // namespace crepe
diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h
new file mode 100644
index 0000000..046426d
--- /dev/null
+++ b/src/crepe/api/AI.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "Component.h"
+#include "types.h"
+
+namespace crepe {
+
+class AI : public Component {
+public:
+ enum BehaviorType {
+ NONE = 0x00000,
+ SEEK = 0x00002,
+ FLEE = 0x00004,
+ ARRIVE = 0x00008,
+ PATH_FOLLOW = 0x00010,
+ };
+
+public:
+ AI(game_object_id_t id, float max_force);
+
+ bool on(BehaviorType behavior) const { return (flags & behavior) == behavior; }
+ void seek_on() { flags |= SEEK; }
+ void seek_off() {
+ if (on(SEEK)) flags ^= SEEK;
+ }
+ void flee_on() { flags |= FLEE; }
+ void flee_off() {
+ if (on(FLEE)) flags ^= FLEE;
+ }
+ void arrive_on() { flags |= ARRIVE; }
+ void arrive_off() {
+ if (on(ARRIVE)) flags ^= ARRIVE;
+ }
+ void path_follow_on() { flags |= PATH_FOLLOW; }
+ void path_follow_off() {
+ if (on(PATH_FOLLOW)) flags ^= PATH_FOLLOW;
+ }
+
+public:
+ float max_force;
+
+ // The target to seek or arrive at
+ vec2 seek_target;
+ // The target to flee from
+ vec2 flee_target;
+ // The distance at which the entity will start to flee from the target
+ float square_flee_panic_distance = 100.0f * 100.0f;
+ // The deceleration rate for the arrive behavior (higher values will make the entity decelerate faster (less overshoot))
+ float arrive_deceleration = 2.0f;
+
+private:
+ int flags = 0;
+};
+
+} // namespace crepe
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index b2e3df8..9f61ef5 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -24,6 +24,7 @@ target_sources(crepe PUBLIC
Script.cpp
Button.cpp
UIObject.cpp
+ AI.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -58,4 +59,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
Asset.h
Button.h
UIObject.h
+ AI.h
)
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
index b9e91dd..90308a7 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -1,3 +1,5 @@
+#include "../facade/SDLContext.h"
+#include "../system/AISystem.h"
#include "../system/AnimatorSystem.h"
#include "../system/CollisionSystem.h"
#include "../system/InputSystem.h"
@@ -23,6 +25,7 @@ LoopManager::LoopManager() {
this->load_system<RenderSystem>();
this->load_system<ScriptSystem>();
this->load_system<InputSystem>();
+ this->load_system<AISystem>();
}
void LoopManager::process_input() { this->get_system<InputSystem>().update(); }
@@ -37,6 +40,7 @@ void LoopManager::fixed_update() {
EventManager & ev = this->mediator.event_manager;
ev.dispatch_events();
this->get_system<ScriptSystem>().update();
+ this->get_system<AISystem>().update();
this->get_system<PhysicsSystem>().update();
this->get_system<CollisionSystem>().update();
}
@@ -47,13 +51,13 @@ void LoopManager::loop() {
while (game_running) {
timer.update();
-
+
while (timer.get_lag() >= timer.get_fixed_delta_time()) {
this->process_input();
this->fixed_update();
timer.advance_fixed_update();
}
-
+
this->update();
this->render();
@@ -75,4 +79,4 @@ void LoopManager::render() {
this->get_system<RenderSystem>().update();
}
-void LoopManager::update() {}
+void LoopManager::update() { this->get_system<AnimatorSystem>().update(); }
diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h
index b0a24f7..722a665 100644
--- a/src/crepe/api/Rigidbody.h
+++ b/src/crepe/api/Rigidbody.h
@@ -7,7 +7,6 @@
#include "types.h"
-
namespace crepe {
/**
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 1474a09..fa83152 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -3,10 +3,10 @@
#include <vector>
#include "../manager/EventManager.h"
-#include "system/CollisionSystem.h"
#include "../manager/Mediator.h"
#include "../types.h"
#include "../util/OptionalRef.h"
+#include "system/CollisionSystem.h"
namespace crepe {
diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h
index c278c87..bf9d124 100644
--- a/src/crepe/api/Vector2.h
+++ b/src/crepe/api/Vector2.h
@@ -66,6 +66,30 @@ struct Vector2 {
//! Checks if this vector is not equal to another vector.
bool operator!=(const Vector2<T> & other) const;
+
+ //! Truncates the vector to a maximum length.
+ void truncate(T max);
+
+ //! Normalizes the vector (resulting in vector with a length of 1).
+ void normalize();
+
+ //! Returns the length of the vector.
+ T length() const;
+
+ //! Returns the squared length of the vector.
+ T length_squared() const;
+
+ //! Returns the dot product (inwendig product) of this vector and another vector.
+ T dot(const Vector2<T> & other) const;
+
+ //! Returns the distance between this vector and another vector.
+ T distance(const Vector2<T> & other) const;
+
+ //! Returns the squared distance between this vector and another vector.
+ T distance_squared(const Vector2<T> & other) const;
+
+ //! Returns the perpendicular vector to this vector.
+ Vector2 perpendicular() const;
};
} // namespace crepe
diff --git a/src/crepe/api/Vector2.hpp b/src/crepe/api/Vector2.hpp
index cad15f8..ff53cb0 100644
--- a/src/crepe/api/Vector2.hpp
+++ b/src/crepe/api/Vector2.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <cmath>
+
#include "Vector2.h"
namespace crepe {
@@ -115,4 +117,50 @@ bool Vector2<T>::operator!=(const Vector2<T> & other) const {
return !(*this == other);
}
+template <class T>
+void Vector2<T>::truncate(T max) {
+ if (length() > max) {
+ normalize();
+ *this *= max;
+ }
+}
+
+template <class T>
+void Vector2<T>::normalize() {
+ T len = length();
+ if (len > 0) {
+ *this /= len;
+ }
+}
+
+template <class T>
+T Vector2<T>::length() const {
+ return std::sqrt(x * x + y * y);
+}
+
+template <class T>
+T Vector2<T>::length_squared() const {
+ return x * x + y * y;
+}
+
+template <class T>
+T Vector2<T>::dot(const Vector2<T> & other) const {
+ return x * other.x + y * other.y;
+}
+
+template <class T>
+T Vector2<T>::distance(const Vector2<T> & other) const {
+ return (*this - other).length();
+}
+
+template <class T>
+T Vector2<T>::distance_squared(const Vector2<T> & other) const {
+ return (*this - other).length_squared();
+}
+
+template <class T>
+Vector2<T> Vector2<T>::perpendicular() const {
+ return {-y, x};
+}
+
} // namespace crepe
diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp
new file mode 100644
index 0000000..4858000
--- /dev/null
+++ b/src/crepe/system/AISystem.cpp
@@ -0,0 +1,85 @@
+#include "api/LoopTimer.h"
+#include "api/Rigidbody.h"
+#include "api/Transform.h"
+#include "manager/ComponentManager.h"
+#include "manager/Mediator.h"
+#include "types.h"
+
+#include "AISystem.h"
+
+using namespace crepe;
+
+void AISystem::update() {
+ const Mediator & mediator = this->mediator;
+ ComponentManager & mgr = mediator.component_manager;
+ RefVector<AI> ai_components = mgr.get_components_by_type<AI>();
+
+ double dt = LoopTimer::get_instance().get_delta_time();
+
+ for (AI & ai : ai_components) {
+ RefVector<Rigidbody> rigidbodies
+ = mgr.get_components_by_id<Rigidbody>(ai.game_object_id);
+ Rigidbody & rigidbody = rigidbodies.front().get();
+
+ vec2 force = this->calculate(ai);
+ vec2 acceleration = force / rigidbody.data.mass;
+ rigidbody.data.linear_velocity += acceleration * dt;
+ }
+}
+
+vec2 AISystem::calculate(AI & ai) {
+ vec2 force;
+
+ if (ai.on(AI::BehaviorType::SEEK)) {
+ vec2 force_to_add = this->seek(ai);
+
+ if (!this->accumulate_force(ai, force, force_to_add)) {
+ return force;
+ }
+ }
+ if (ai.on(AI::BehaviorType::FLEE)) {
+ // Flee from the target
+ }
+ if (ai.on(AI::BehaviorType::ARRIVE)) {
+ // Arrive at the target
+ }
+ if (ai.on(AI::BehaviorType::PATH_FOLLOW)) {
+ // Follow the path
+ }
+
+ return force;
+}
+
+bool AISystem::accumulate_force(AI & ai, vec2 & running_total, vec2 force_to_add) {
+ float magnitude = running_total.length();
+ float magnitude_remaining = ai.max_force - magnitude;
+
+ if (magnitude_remaining <= 0.0f) {
+ return false;
+ }
+
+ float magnitude_to_add = force_to_add.length();
+ if (magnitude_to_add < magnitude_remaining) {
+ running_total += force_to_add;
+ } else {
+ force_to_add.normalize();
+ running_total += force_to_add * magnitude_remaining;
+ }
+
+ return true;
+}
+
+vec2 AISystem::seek(const 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();
+
+ vec2 desired_velocity = ai.seek_target - transform.position;
+ desired_velocity.normalize();
+ desired_velocity *= rigidbody.data.max_linear_velocity;
+
+ return desired_velocity - rigidbody.data.linear_velocity;
+}
diff --git a/src/crepe/system/AISystem.h b/src/crepe/system/AISystem.h
new file mode 100644
index 0000000..18f1c61
--- /dev/null
+++ b/src/crepe/system/AISystem.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "api/AI.h"
+
+#include "System.h"
+#include "types.h"
+
+namespace crepe {
+
+class AISystem : public System {
+public:
+ using System::System;
+
+ void update() override;
+
+private:
+ vec2 calculate(AI & ai);
+ bool accumulate_force(AI & ai, vec2 & running_total, vec2 force_to_add);
+
+ vec2 seek(const AI & ai);
+ vec2 flee(const AI & ai);
+ vec2 arrive(const AI & ai);
+ vec2 path_follow(const AI & ai);
+};
+
+} // namespace crepe
diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt
index 95f6e33..7de5198 100644
--- a/src/crepe/system/CMakeLists.txt
+++ b/src/crepe/system/CMakeLists.txt
@@ -7,6 +7,7 @@ target_sources(crepe PUBLIC
RenderSystem.cpp
AnimatorSystem.cpp
InputSystem.cpp
+ AISystem.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -17,4 +18,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
RenderSystem.h
AnimatorSystem.h
InputSystem.h
+ AISystem.h
)
diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp
index 44ea7ee..2a487fd 100644
--- a/src/crepe/system/CollisionSystem.cpp
+++ b/src/crepe/system/CollisionSystem.cpp
@@ -6,6 +6,8 @@
#include <utility>
#include <variant>
+#include "../manager/ComponentManager.h"
+#include "../manager/EventManager.h"
#include "api/BoxCollider.h"
#include "api/CircleCollider.h"
#include "api/Event.h"
@@ -13,8 +15,6 @@
#include "api/Rigidbody.h"
#include "api/Transform.h"
#include "api/Vector2.h"
-#include "../manager/ComponentManager.h"
-#include "../manager/EventManager.h"
#include "Collider.h"
#include "CollisionSystem.h"
@@ -27,17 +27,14 @@ void CollisionSystem::update() {
std::vector<CollisionInternal> all_colliders;
game_object_id_t id = 0;
ComponentManager & mgr = this->mediator.component_manager;
- RefVector<Rigidbody> rigidbodies
- = mgr.get_components_by_type<Rigidbody>();
+ RefVector<Rigidbody> rigidbodies = mgr.get_components_by_type<Rigidbody>();
// Collisions can only happen on object with a rigidbody
for (Rigidbody & rigidbody : rigidbodies) {
if (!rigidbody.active) continue;
id = rigidbody.game_object_id;
- Transform & transform
- = mgr.get_components_by_id<Transform>(id).front().get();
+ Transform & transform = mgr.get_components_by_id<Transform>(id).front().get();
// Check if the boxcollider is active and has the same id as the rigidbody.
- RefVector<BoxCollider> boxcolliders
- = mgr.get_components_by_type<BoxCollider>();
+ RefVector<BoxCollider> boxcolliders = mgr.get_components_by_type<BoxCollider>();
for (BoxCollider & boxcollider : boxcolliders) {
if (boxcollider.game_object_id != id) continue;
if (!boxcollider.active) continue;
@@ -159,7 +156,7 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal
vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform,
data2.rigidbody);
resolution = this->get_circle_box_resolution(collider2, collider1, collider_pos2,
- collider_pos1,true);
+ collider_pos1, true);
break;
}
case CollisionInternalType::CIRCLE_CIRCLE: {
@@ -185,7 +182,7 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal
vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform,
data2.rigidbody);
resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1,
- collider_pos2,false);
+ collider_pos2, false);
break;
}
}
@@ -261,7 +258,6 @@ vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider & circle
// Normalize the delta vector to get the collision direction
vec2 collision_normal = delta / distance;
-
// Compute the resolution vector
vec2 resolution = -collision_normal * penetration_depth;
@@ -272,7 +268,8 @@ vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider & circle
vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_collider,
const BoxCollider & box_collider,
const vec2 & circle_position,
- const vec2 & box_position,bool inverse) const {
+ const vec2 & box_position,
+ bool inverse) const {
vec2 delta = circle_position - box_position;
// Compute half-dimensions of the box
@@ -294,7 +291,7 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co
// Compute penetration depth
float penetration_depth = circle_collider.radius - distance;
- if(inverse) collision_normal = -collision_normal;
+ if (inverse) collision_normal = -collision_normal;
// Compute the resolution vector
vec2 resolution = collision_normal * penetration_depth;
@@ -311,8 +308,7 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) {
// Call collision event for user
CollisionEvent data(info);
EventManager & emgr = this->mediator.event_manager;
- emgr.trigger_event<CollisionEvent>(
- data, info.this_collider.game_object_id);
+ emgr.trigger_event<CollisionEvent>(data, info.this_collider.game_object_id);
}
void CollisionSystem::static_collision_handler(CollisionInfo & info) {
@@ -389,14 +385,14 @@ CollisionSystem::gather_collisions(std::vector<CollisionInternal> & colliders) {
bool CollisionSystem::have_common_layer(const std::set<int> & layers1,
const std::set<int> & layers2) {
-
+
// Check if any number is equal in the layers
for (int num : layers1) {
- if (layers2.contains(num)) {
- // Common layer found
- return true;
- break;
- }
+ if (layers2.contains(num)) {
+ // Common layer found
+ return true;
+ break;
+ }
}
// No common layer found
return false;
diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h
index b978dbb..eee582b 100644
--- a/src/crepe/system/CollisionSystem.h
+++ b/src/crepe/system/CollisionSystem.h
@@ -6,11 +6,11 @@
#include "api/BoxCollider.h"
#include "api/CircleCollider.h"
+#include "api/Event.h"
#include "api/Metadata.h"
#include "api/Rigidbody.h"
#include "api/Transform.h"
#include "api/Vector2.h"
-#include "api/Event.h"
#include "Collider.h"
#include "System.h"
@@ -183,8 +183,8 @@ private:
*/
vec2 get_circle_box_resolution(const CircleCollider & circle_collider,
const BoxCollider & box_collider,
- const vec2 & circle_position,
- const vec2 & box_position,bool inverse) const;
+ const vec2 & circle_position, const vec2 & box_position,
+ bool inverse) const;
/**
* \brief Determines the appropriate collision handler for a collision.
diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp
new file mode 100644
index 0000000..2b6a4d6
--- /dev/null
+++ b/src/example/AITest.cpp
@@ -0,0 +1,63 @@
+#include <SDL2/SDL_timer.h>
+#include <chrono>
+#include <crepe/api/AI.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Camera.h>
+#include <crepe/api/Color.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/LoopManager.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Texture.h>
+#include <crepe/manager/Mediator.h>
+
+using namespace crepe;
+using namespace std;
+
+class Script1 : public Script {
+ bool shutdown(const ShutDownEvent & event) {
+ // Very dirty way of shutting down the game
+ throw "ShutDownEvent";
+ return true;
+ }
+
+ void init() {
+ subscribe<ShutDownEvent>(
+ [this](const ShutDownEvent & ev) -> bool { return this->shutdown(ev); });
+ }
+};
+
+class Scene1 : public Scene {
+public:
+ void load_scene() override {
+ Mediator & mediator = this->mediator;
+ ComponentManager & mgr = mediator.component_manager;
+
+ GameObject game_object1 = mgr.new_object("", "", vec2{250, 250}, 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);
+ game_object1.add_component<AI>(200).seek_on();
+ game_object1.add_component<Rigidbody>(Rigidbody::Data{
+ .mass = 1.0f, .max_linear_velocity = {21, 21}, // sqrt(21^2 + 21^2) = 30
+ });
+
+ game_object2.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{1036, 780},
+ 1.0f);
+ game_object2.add_component<BehaviorScript>().set_script<Script1>();
+ }
+
+ string get_name() const override { return "Scene1"; }
+};
+
+int main() {
+ LoopManager engine;
+ engine.add_scene<Scene1>();
+ engine.start();
+
+ return 0;
+}
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index 8ef71bb..149c412 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -21,3 +21,4 @@ add_example(savemgr)
add_example(rendering_particle)
add_example(game)
add_example(button)
+add_example(AITest)
diff --git a/src/example/game.cpp b/src/example/game.cpp
index be756bd..2b4e46f 100644
--- a/src/example/game.cpp
+++ b/src/example/game.cpp
@@ -1,6 +1,6 @@
#include "api/CircleCollider.h"
-#include "manager/ComponentManager.h"
#include "api/Scene.h"
+#include "manager/ComponentManager.h"
#include "manager/Mediator.h"
#include <crepe/api/BoxCollider.h>
#include <crepe/api/Camera.h>
@@ -28,66 +28,64 @@ class MyScript1 : public Script {
bool keypressed(const KeyPressEvent & test) {
Log::logf("Box script keypressed()");
switch (test.key) {
- case Keycode::A:
- {
+ case Keycode::A: {
Transform & tf = this->get_component<Transform>();
tf.position.x -= 1;
break;
}
- case Keycode::W:
- {
+ case Keycode::W: {
Transform & tf = this->get_component<Transform>();
tf.position.y -= 1;
break;
}
- case Keycode::S:
- {
+ case Keycode::S: {
Transform & tf = this->get_component<Transform>();
tf.position.y += 1;
break;
}
- case Keycode::D:
- {
+ case Keycode::D: {
Transform & tf = this->get_component<Transform>();
tf.position.x += 1;
break;
}
- case Keycode::E:
- {
- if(flip){
+ case Keycode::E: {
+ if (flip) {
flip = false;
this->get_component<BoxCollider>().active = true;
this->get_components<Sprite>()[0].get().active = true;
this->get_component<CircleCollider>().active = false;
this->get_components<Sprite>()[1].get().active = false;
- }
- else {
+ } else {
flip = true;
this->get_component<BoxCollider>().active = false;
this->get_components<Sprite>()[0].get().active = false;
this->get_component<CircleCollider>().active = true;
this->get_components<Sprite>()[1].get().active = true;
}
-
-
+
//add collider switch
break;
}
+ case Keycode::Q: {
+ throw "Test";
+ break;
+ }
default:
- break;
+ break;
}
return false;
- }
+ }
void init() {
Log::logf("init");
- subscribe<CollisionEvent>([this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); });
- subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); });
+ subscribe<CollisionEvent>(
+ [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); });
+ subscribe<KeyPressEvent>(
+ [this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); });
}
void update() {
// Retrieve component from the same GameObject this script is on
}
-
};
class MyScript2 : public Script {
@@ -99,74 +97,68 @@ class MyScript2 : public Script {
bool keypressed(const KeyPressEvent & test) {
Log::logf("Box script keypressed()");
switch (test.key) {
- case Keycode::LEFT:
- {
+ case Keycode::LEFT: {
Transform & tf = this->get_component<Transform>();
tf.position.x -= 1;
break;
}
- case Keycode::UP:
- {
+ case Keycode::UP: {
Transform & tf = this->get_component<Transform>();
tf.position.y -= 1;
break;
}
- case Keycode::DOWN:
- {
+ case Keycode::DOWN: {
Transform & tf = this->get_component<Transform>();
tf.position.y += 1;
break;
}
- case Keycode::RIGHT:
- {
+ case Keycode::RIGHT: {
Transform & tf = this->get_component<Transform>();
tf.position.x += 1;
break;
}
- case Keycode::PAUSE:
- {
- if(flip){
+ case Keycode::PAUSE: {
+ if (flip) {
flip = false;
this->get_component<BoxCollider>().active = true;
this->get_components<Sprite>()[0].get().active = true;
this->get_component<CircleCollider>().active = false;
this->get_components<Sprite>()[1].get().active = false;
- }
- else {
+ } else {
flip = true;
this->get_component<BoxCollider>().active = false;
this->get_components<Sprite>()[0].get().active = false;
this->get_component<CircleCollider>().active = true;
this->get_components<Sprite>()[1].get().active = true;
}
-
-
+
//add collider switch
break;
}
default:
- break;
+ break;
}
return false;
- }
+ }
void init() {
Log::logf("init");
- subscribe<CollisionEvent>([this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); });
- subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); });
+ subscribe<CollisionEvent>(
+ [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); });
+ subscribe<KeyPressEvent>(
+ [this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); });
}
void update() {
// Retrieve component from the same GameObject this script is on
}
-
};
class ConcreteScene1 : public Scene {
public:
using Scene::Scene;
-
+
void load_scene() {
-
+
Mediator & m = this->mediator;
ComponentManager & mgr = m.component_manager;
Color color(0, 0, 0, 255);
@@ -195,7 +187,10 @@ public:
vec2{world_collider, world_collider}); // Left
world.add_component<BoxCollider>(vec2{screen_size_width / 2 + world_collider / 2, 0},
vec2{world_collider, world_collider}); // right
- world.add_component<Camera>(Color::WHITE, ivec2{static_cast<int>(screen_size_width), static_cast<int>(screen_size_height)}, vec2{screen_size_width, screen_size_height}, 1.0f);
+ world.add_component<Camera>(
+ Color::WHITE,
+ ivec2{static_cast<int>(screen_size_width), static_cast<int>(screen_size_height)},
+ vec2{screen_size_width, screen_size_height}, 1.0f);
GameObject game_object1 = mgr.new_object(
"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);
@@ -219,10 +214,10 @@ public:
//add circle with cirlcecollider deactiveated
game_object1.add_component<CircleCollider>(vec2{0, 0}, 10).active = false;
auto img2 = Texture("asset/texture/circle.png");
- game_object1.add_component<Sprite>(img2, color, Sprite::FlipSettings{false, false}, 1,
- 1, 20).active = false;
-
-
+ game_object1
+ .add_component<Sprite>(img2, color, Sprite::FlipSettings{false, false}, 1, 1, 20)
+ .active
+ = false;
GameObject game_object2 = mgr.new_object(
"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);
@@ -246,9 +241,10 @@ public:
//add circle with cirlcecollider deactiveated
game_object2.add_component<CircleCollider>(vec2{0, 0}, 10).active = false;
auto img4 = Texture("asset/texture/circle.png");
- game_object2.add_component<Sprite>(img4, color, Sprite::FlipSettings{false, false}, 1,
- 1, 20).active = false;
-
+ game_object2
+ .add_component<Sprite>(img4, color, Sprite::FlipSettings{false, false}, 1, 1, 20)
+ .active
+ = false;
}
string get_name() const { return "scene1"; }
diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp
index a683b1f..dd45eb6 100644
--- a/src/test/CollisionTest.cpp
+++ b/src/test/CollisionTest.cpp
@@ -7,14 +7,14 @@
#define private public
#define protected public
-#include <crepe/manager/ComponentManager.h>
-#include <crepe/manager/Mediator.h>
#include <crepe/api/Event.h>
-#include <crepe/manager/EventManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/Rigidbody.h>
#include <crepe/api/Script.h>
#include <crepe/api/Transform.h>
+#include <crepe/manager/ComponentManager.h>
+#include <crepe/manager/EventManager.h>
+#include <crepe/manager/Mediator.h>
#include <crepe/system/CollisionSystem.h>
#include <crepe/system/ScriptSystem.h>
#include <crepe/types.h>
diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp
index 91be769..f091d9d 100644
--- a/src/test/Profiling.cpp
+++ b/src/test/Profiling.cpp
@@ -9,14 +9,14 @@
#define private public
#define protected public
-#include <crepe/manager/ComponentManager.h>
#include <crepe/api/Event.h>
-#include <crepe/manager/EventManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/ParticleEmitter.h>
#include <crepe/api/Rigidbody.h>
#include <crepe/api/Script.h>
#include <crepe/api/Transform.h>
+#include <crepe/manager/ComponentManager.h>
+#include <crepe/manager/EventManager.h>
#include <crepe/system/CollisionSystem.h>
#include <crepe/system/ScriptSystem.h>
#include <crepe/types.h>
@@ -162,7 +162,7 @@ TEST_F(Profiling, Profiling_2) {
.body_type = Rigidbody::BodyType::STATIC,
});
gameobject.add_component<BoxCollider>(vec2{0, 0}, vec2{1, 1});
-
+
gameobject.add_component<BehaviorScript>().set_script<TestScript>();
Color color(0, 0, 0, 0);
auto img = Texture("asset/texture/green_square.png");
diff --git a/src/test/Vector2Test.cpp b/src/test/Vector2Test.cpp
index 17bca41..1e21af9 100644
--- a/src/test/Vector2Test.cpp
+++ b/src/test/Vector2Test.cpp
@@ -382,3 +382,151 @@ TEST_F(Vector2Test, NotEquals) {
EXPECT_FALSE(long_vec1 != long_vec1);
EXPECT_TRUE(long_vec1 != long_vec2);
}
+
+TEST_F(Vector2Test, Truncate) {
+ Vector2<int> vec = {3, 4};
+ vec.truncate(3);
+ EXPECT_EQ(vec.x, 0);
+ EXPECT_EQ(vec.y, 0);
+
+ Vector2<double> vec2 = {3.0, 4.0};
+ vec2.truncate(3.0);
+ EXPECT_FLOAT_EQ(vec2.x, 1.8);
+ EXPECT_FLOAT_EQ(vec2.y, 2.4);
+
+ Vector2<long> vec3 = {3, 4};
+ vec3.truncate(3);
+ EXPECT_EQ(vec3.x, 0);
+ EXPECT_EQ(vec3.y, 0);
+
+ Vector2<float> vec4 = {3.0f, 4.0f};
+ vec4.truncate(3.0f);
+ EXPECT_FLOAT_EQ(vec4.x, 1.8f);
+ EXPECT_FLOAT_EQ(vec4.y, 2.4f);
+}
+
+TEST_F(Vector2Test, Normalize) {
+ Vector2<int> vec = {3, 4};
+ vec.normalize();
+ EXPECT_EQ(vec.x, 0);
+ EXPECT_EQ(vec.y, 0);
+
+ Vector2<double> vec2 = {3.0, 4.0};
+ vec2.normalize();
+ EXPECT_FLOAT_EQ(vec2.x, 0.6);
+ EXPECT_FLOAT_EQ(vec2.y, 0.8);
+
+ Vector2<long> vec3 = {3, 4};
+ vec3.normalize();
+ EXPECT_EQ(vec3.x, 0);
+ EXPECT_EQ(vec3.y, 0);
+
+ Vector2<float> vec4 = {3.0f, 4.0f};
+ vec4.normalize();
+ EXPECT_FLOAT_EQ(vec4.x, 0.6f);
+ EXPECT_FLOAT_EQ(vec4.y, 0.8f);
+}
+
+TEST_F(Vector2Test, Length) {
+ Vector2<int> vec = {3, 4};
+ EXPECT_EQ(vec.length(), 5);
+
+ Vector2<double> vec2 = {3.0, 4.0};
+ EXPECT_FLOAT_EQ(vec2.length(), 5.0);
+
+ Vector2<long> vec3 = {3, 4};
+ EXPECT_EQ(vec3.length(), 5);
+
+ Vector2<float> vec4 = {3.0f, 4.0f};
+ EXPECT_FLOAT_EQ(vec4.length(), 5.0f);
+}
+
+TEST_F(Vector2Test, LengthSquared) {
+ Vector2<int> vec = {3, 4};
+ EXPECT_EQ(vec.length_squared(), 25);
+
+ Vector2<double> vec2 = {3.0, 4.0};
+ EXPECT_FLOAT_EQ(vec2.length_squared(), 25.0);
+
+ Vector2<long> vec3 = {3, 4};
+ EXPECT_EQ(vec3.length_squared(), 25);
+
+ Vector2<float> vec4 = {3.0f, 4.0f};
+ EXPECT_FLOAT_EQ(vec4.length_squared(), 25.0f);
+}
+
+TEST_F(Vector2Test, Dot) {
+ Vector2<int> vec1 = {3, 4};
+ Vector2<int> vec2 = {5, 6};
+ EXPECT_EQ(vec1.dot(vec2), 39);
+
+ Vector2<double> vec3 = {3.0, 4.0};
+ Vector2<double> vec4 = {5.0, 6.0};
+ EXPECT_FLOAT_EQ(vec3.dot(vec4), 39.0);
+
+ Vector2<long> vec5 = {3, 4};
+ Vector2<long> vec6 = {5, 6};
+ EXPECT_EQ(vec5.dot(vec6), 39);
+
+ Vector2<float> vec7 = {3.0f, 4.0f};
+ Vector2<float> vec8 = {5.0f, 6.0f};
+ EXPECT_FLOAT_EQ(vec7.dot(vec8), 39.0f);
+}
+
+TEST_F(Vector2Test, Distance) {
+ Vector2<int> vec1 = {1, 1};
+ Vector2<int> vec2 = {4, 5};
+ EXPECT_EQ(vec1.distance(vec2), 5);
+
+ Vector2<double> vec3 = {1.0, 1.0};
+ Vector2<double> vec4 = {4.0, 5.0};
+ EXPECT_FLOAT_EQ(vec3.distance(vec4), 5.0);
+
+ Vector2<long> vec5 = {1, 1};
+ Vector2<long> vec6 = {4, 5};
+ EXPECT_EQ(vec5.distance(vec6), 5);
+
+ Vector2<float> vec7 = {1.0f, 1.0f};
+ Vector2<float> vec8 = {4.0f, 5.0f};
+ EXPECT_FLOAT_EQ(vec7.distance(vec8), 5.0f);
+}
+
+TEST_F(Vector2Test, DistanceSquared) {
+ Vector2<int> vec1 = {3, 4};
+ Vector2<int> vec2 = {5, 6};
+ EXPECT_EQ(vec1.distance_squared(vec2), 8);
+
+ Vector2<double> vec3 = {3.0, 4.0};
+ Vector2<double> vec4 = {5.0, 6.0};
+ EXPECT_FLOAT_EQ(vec3.distance_squared(vec4), 8.0);
+
+ Vector2<long> vec5 = {3, 4};
+ Vector2<long> vec6 = {5, 6};
+ EXPECT_EQ(vec5.distance_squared(vec6), 8);
+
+ Vector2<float> vec7 = {3.0f, 4.0f};
+ Vector2<float> vec8 = {5.0f, 6.0f};
+ EXPECT_FLOAT_EQ(vec7.distance_squared(vec8), 8.0f);
+}
+
+TEST_F(Vector2Test, Perpendicular) {
+ Vector2<int> vec = {3, 4};
+ Vector2<int> result = vec.perpendicular();
+ EXPECT_EQ(result.x, -4);
+ EXPECT_EQ(result.y, 3);
+
+ Vector2<double> vec2 = {3.0, 4.0};
+ Vector2<double> result2 = vec2.perpendicular();
+ EXPECT_FLOAT_EQ(result2.x, -4.0);
+ EXPECT_FLOAT_EQ(result2.y, 3.0);
+
+ Vector2<long> vec3 = {3, 4};
+ Vector2<long> result3 = vec3.perpendicular();
+ EXPECT_EQ(result3.x, -4);
+ EXPECT_EQ(result3.y, 3);
+
+ Vector2<float> vec4 = {3.0f, 4.0f};
+ Vector2<float> result4 = vec4.perpendicular();
+ EXPECT_FLOAT_EQ(result4.x, -4.0f);
+ EXPECT_FLOAT_EQ(result4.y, 3.0f);
+}