diff options
| author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-14 13:40:21 +0100 | 
|---|---|---|
| committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-14 13:40:21 +0100 | 
| commit | 2389b23459cf5b01c6ea1cbbcfeb2043e26e0a0c (patch) | |
| tree | 6a5322838386657d90ff69776876262740774a7a /src | |
| parent | ccbfb97a11cd931655f2762443ffc36f5f25e86f (diff) | |
| parent | 876896e50711509e80ef551b4e8ad440e8039b97 (diff) | |
Merge branch 'master' of https://github.com/lonkaars/crepe into wouter/inputSystem
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/crepe/api/Scene.cpp | 15 | ||||
| -rw-r--r-- | src/crepe/api/Scene.h | 38 | ||||
| -rw-r--r-- | src/crepe/api/Scene.hpp | 19 | ||||
| -rw-r--r-- | src/crepe/manager/LoopTimerManager.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/manager/LoopTimerManager.h | 8 | ||||
| -rw-r--r-- | src/crepe/system/AnimatorSystem.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 76 | ||||
| -rw-r--r-- | src/example/game.cpp | 31 | ||||
| -rw-r--r-- | src/test/CollisionTest.cpp | 12 | ||||
| -rw-r--r-- | src/test/LoopTimerTest.cpp | 18 | ||||
| -rw-r--r-- | src/test/SceneManagerTest.cpp | 22 | 
12 files changed, 179 insertions, 69 deletions
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index fb11c8d..8f84f06 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(crepe PUBLIC  	Button.cpp  	UIObject.cpp  	AI.cpp +	Scene.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -36,6 +37,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	Vector2.hpp  	Color.h  	Scene.h +	Scene.hpp  	Metadata.h  	Camera.h  	Animator.h diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp new file mode 100644 index 0000000..ad729d2 --- /dev/null +++ b/src/crepe/api/Scene.cpp @@ -0,0 +1,15 @@ +#include "Scene.h" + +using namespace crepe; + +SaveManager & Scene::get_save_manager() const { return mediator->save_manager; } + +GameObject Scene::new_object(const std::string & name, const std::string & tag, +							 const vec2 & position, double rotation, double scale) { +	// Forward the call to ComponentManager's new_object method +	return mediator->component_manager->new_object(name, tag, position, rotation, scale); +} + +void Scene::set_persistent(const Asset & asset, bool persistent) { +	mediator->resource_manager->set_persistent(asset, persistent); +} diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index ba9bb76..dcca9d4 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -2,13 +2,19 @@  #include <string> +#include "../manager/ComponentManager.h"  #include "../manager/Mediator.h" +#include "../manager/ResourceManager.h" +#include "../util/Log.h"  #include "../util/OptionalRef.h" +#include "GameObject.h" +  namespace crepe {  class SceneManager;  class ComponentManager; +class Asset;  /**   * \brief Represents a Scene @@ -38,7 +44,7 @@ public:  	// TODO: Late references should ALWAYS be private! This is currently kept as-is so unit tests  	// keep passing, but this reference should not be directly accessible by the user!!! -protected: +private:  	/**  	 * \name Late references  	 * @@ -53,6 +59,36 @@ protected:  	//! Mediator reference  	OptionalRef<Mediator> mediator;  	//! \} + +protected: +	/** +	* \brief Retrieve the reference to the SaveManager instance +	* +	* \returns A reference to the SaveManager instance held by the Mediator. +	*/ +	SaveManager & get_save_manager() const; + +	//! \copydoc ComponentManager::new_object +	GameObject new_object(const std::string & name, const std::string & tag = "", +						  const vec2 & position = {0, 0}, double rotation = 0, +						  double scale = 1); + +	//! \copydoc ResourceManager::set_persistent +	void set_persistent(const Asset & asset, bool persistent); +	/** +	* \name Logging functions +	* \see Log +	* \{ +	*/ +	//! \copydoc Log::logf +	template <class... Args> +	void logf(const Log::Level & level, std::format_string<Args...> fmt, Args &&... args); +	//! \copydoc Log::logf +	template <class... Args> +	void logf(std::format_string<Args...> fmt, Args &&... args); +	//! \}  };  } // namespace crepe + +#include "Scene.hpp" diff --git a/src/crepe/api/Scene.hpp b/src/crepe/api/Scene.hpp new file mode 100644 index 0000000..14635df --- /dev/null +++ b/src/crepe/api/Scene.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "../util/Log.h" + +#include "Scene.h" + +namespace crepe { + +template <class... Args> +void Scene::logf(const Log::Level & level, std::format_string<Args...> fmt, Args &&... args) { +	Log::logf(level, fmt, std::forward<Args>(args)...); +} + +template <class... Args> +void Scene::logf(std::format_string<Args...> fmt, Args &&... args) { +	Log::logf(fmt, std::forward<Args>(args)...); +} + +} // namespace crepe diff --git a/src/crepe/manager/LoopTimerManager.cpp b/src/crepe/manager/LoopTimerManager.cpp index 9819632..a6e4788 100644 --- a/src/crepe/manager/LoopTimerManager.cpp +++ b/src/crepe/manager/LoopTimerManager.cpp @@ -31,7 +31,7 @@ void LoopTimerManager::update() {  		this->delta_time = this->maximum_delta_time;  	}  	if (this->delta_time > 0s) { -		this->actual_fps = 1.0 / duration_cast<seconds>(this->delta_time).count(); +		this->actual_fps = static_cast<unsigned>(1.0 / this->delta_time.count());  	} else {  		this->actual_fps = 0;  	} diff --git a/src/crepe/manager/LoopTimerManager.h b/src/crepe/manager/LoopTimerManager.h index 91403e4..76b02d3 100644 --- a/src/crepe/manager/LoopTimerManager.h +++ b/src/crepe/manager/LoopTimerManager.h @@ -6,7 +6,7 @@  namespace crepe { -typedef std::chrono::duration<double> duration_t; +typedef std::chrono::duration<float> duration_t;  typedef std::chrono::duration<unsigned long long, std::micro> elapsed_time_t;  /** @@ -55,7 +55,7 @@ public:  	 *  	 * \return Current FPS.  	 */ -	unsigned get_fps() const; +	unsigned int get_fps() const;  	/**  	 * \brief Get the current time scale. @@ -149,9 +149,9 @@ private:  private:  	//! Target frames per second. -	unsigned target_fps = 60; +	unsigned int target_fps = 60;  	//! Actual frames per second. -	unsigned actual_fps = 0; +	unsigned int actual_fps = 0;  	//! Time scale for speeding up or slowing down the game (0 = pause, < 1 = slow down, 1 = normal speed, > 1 = speed up).  	float time_scale = 1;  	//! Maximum delta time in seconds to avoid large jumps. diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp index 31eb85c..107b25d 100644 --- a/src/crepe/system/AnimatorSystem.cpp +++ b/src/crepe/system/AnimatorSystem.cpp @@ -3,20 +3,23 @@  #include "../api/Animator.h"  #include "../manager/ComponentManager.h"  #include "../manager/LoopTimerManager.h" +#include <chrono>  #include "AnimatorSystem.h"  using namespace crepe; +using namespace std::chrono;  void AnimatorSystem::update() {  	ComponentManager & mgr = this->mediator.component_manager;  	LoopTimerManager & timer = this->mediator.loop_timer;  	RefVector<Animator> animations = mgr.get_components_by_type<Animator>(); -	unsigned long long elapsed_time = timer.get_elapsed_time().count(); +	float elapsed_time = duration_cast<duration<float>>(timer.get_elapsed_time()).count();  	for (Animator & a : animations) {  		if (!a.active) continue; +		if (a.data.fps == 0) continue;  		Animator::Data & ctx = a.data;  		float frame_duration = 1.0f / ctx.fps; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 44a0431..af8adce 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -192,13 +192,17 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal  		resolution_direction = Direction::BOTH;  	} else if (resolution.x != 0) {  		resolution_direction = Direction::X_DIRECTION; -		if (data1.rigidbody.data.linear_velocity.y != 0) -			resolution.y = data1.rigidbody.data.linear_velocity.y +		//checks if the other velocity has a value and if this object moved +		if (data1.rigidbody.data.linear_velocity.x != 0 +			&& data1.rigidbody.data.linear_velocity.y != 0) +			resolution.y = -data1.rigidbody.data.linear_velocity.y  						   * (resolution.x / data1.rigidbody.data.linear_velocity.x);  	} else if (resolution.y != 0) {  		resolution_direction = Direction::Y_DIRECTION; -		if (data1.rigidbody.data.linear_velocity.x != 0) -			resolution.x = data1.rigidbody.data.linear_velocity.x +		//checks if the other velocity has a value and if this object moved +		if (data1.rigidbody.data.linear_velocity.x != 0 +			&& data1.rigidbody.data.linear_velocity.y != 0) +			resolution.x = -data1.rigidbody.data.linear_velocity.x  						   * (resolution.y / data1.rigidbody.data.linear_velocity.y);  	} @@ -314,28 +318,48 @@ void CollisionSystem::static_collision_handler(CollisionInfo & info) {  	// Move object back using calculate move back value  	info.this_transform.position += info.resolution; -	// If bounce is enabled mirror velocity -	if (info.this_rigidbody.data.elastisity_coefficient > 0) { -		if (info.resolution_direction == Direction::BOTH) { -			info.this_rigidbody.data.linear_velocity.y -				= -info.this_rigidbody.data.linear_velocity.y -				  * info.this_rigidbody.data.elastisity_coefficient; -			info.this_rigidbody.data.linear_velocity.x -				= -info.this_rigidbody.data.linear_velocity.x -				  * info.this_rigidbody.data.elastisity_coefficient; -		} else if (info.resolution_direction == Direction::Y_DIRECTION) { -			info.this_rigidbody.data.linear_velocity.y -				= -info.this_rigidbody.data.linear_velocity.y -				  * info.this_rigidbody.data.elastisity_coefficient; -		} else if (info.resolution_direction == Direction::X_DIRECTION) { -			info.this_rigidbody.data.linear_velocity.x -				= -info.this_rigidbody.data.linear_velocity.x -				  * info.this_rigidbody.data.elastisity_coefficient; -		} -	} -	// Stop movement if bounce is disabled -	else { -		info.this_rigidbody.data.linear_velocity = {0, 0}; +	switch (info.resolution_direction) { +		case Direction::BOTH: +			//bounce +			if (info.this_rigidbody.data.elastisity_coefficient > 0) { +				info.this_rigidbody.data.linear_velocity +					= -info.this_rigidbody.data.linear_velocity +					  * info.this_rigidbody.data.elastisity_coefficient; +			} +			//stop movement +			else { +				info.this_rigidbody.data.linear_velocity = {0, 0}; +			} +			break; +		case Direction::Y_DIRECTION: +			// Bounce +			if (info.this_rigidbody.data.elastisity_coefficient > 0) { +				info.this_rigidbody.data.linear_velocity.y +					= -info.this_rigidbody.data.linear_velocity.y +					  * info.this_rigidbody.data.elastisity_coefficient; +			} +			// Stop movement +			else { +				info.this_rigidbody.data.linear_velocity.y = 0; +				info.this_transform.position.x -= info.resolution.x; +			} +			break; +		case Direction::X_DIRECTION: +			// Bounce +			if (info.this_rigidbody.data.elastisity_coefficient > 0) { +				info.this_rigidbody.data.linear_velocity.x +					= -info.this_rigidbody.data.linear_velocity.x +					  * info.this_rigidbody.data.elastisity_coefficient; +			} +			// Stop movement +			else { +				info.this_rigidbody.data.linear_velocity.x = 0; +				info.this_transform.position.y -= info.resolution.y; +			} +			break; +		case Direction::NONE: +			// Not possible +			break;  	}  } diff --git a/src/example/game.cpp b/src/example/game.cpp index 5361f3a..8ea50ea 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -29,23 +29,23 @@ class MyScript1 : public Script {  		Log::logf("Box script keypressed()");  		switch (test.key) {  			case Keycode::A: { -				Transform & tf = this->get_component<Transform>(); -				tf.position.x -= 1; +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.x -= 1;  				break;  			}  			case Keycode::W: { -				Transform & tf = this->get_component<Transform>(); -				tf.position.y -= 1; +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.y -= 1;  				break;  			}  			case Keycode::S: { -				Transform & tf = this->get_component<Transform>(); -				tf.position.y += 1; +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.y += 1;  				break;  			}  			case Keycode::D: { -				Transform & tf = this->get_component<Transform>(); -				tf.position.x += 1; +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.x += 1;  				break;  			}  			case Keycode::E: { @@ -85,7 +85,10 @@ class MyScript1 : public Script {  			[this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); });  	}  	void update() { -		// Retrieve component from the same GameObject this script is on +		Rigidbody & tf = this->get_component<Rigidbody>(); +		Log::logf("linear_velocity.x {}", tf.data.linear_velocity.x); +		Log::logf("linear_velocity.y {}", tf.data.linear_velocity.y); +		// tf.data.linear_velocity = {0,0};  	}  }; @@ -160,15 +163,13 @@ public:  	void load_scene() { -		Mediator & m = this->mediator; -		ComponentManager & mgr = m.component_manager;  		Color color(0, 0, 0, 255);  		float screen_size_width = 320;  		float screen_size_height = 240;  		float world_collider = 1000;  		//define playable world -		GameObject world = mgr.new_object( +		GameObject world = new_object(  			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);  		world.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 0, @@ -196,13 +197,13 @@ public:  				.zoom = 1,  			}); -		GameObject game_object1 = mgr.new_object( +		GameObject game_object1 = new_object(  			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);  		game_object1.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 1,  			.gravity_scale = 1,  			.body_type = Rigidbody::BodyType::DYNAMIC, -			.linear_velocity = {0, 0}, +			.linear_velocity = {0, 1},  			.constraints = {0, 0, 0},  			.elastisity_coefficient = 1,  			.offset = {0, 0}, @@ -228,7 +229,7 @@ public:  			.active  			= false; -		GameObject game_object2 = mgr.new_object( +		GameObject game_object2 = new_object(  			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);  		game_object2.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 1, diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 5dbc670..2ad65fa 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -232,7 +232,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 1);  		EXPECT_EQ(ev.info.resolution.x, -5); -		EXPECT_EQ(ev.info.resolution.y, -5); +		EXPECT_EQ(ev.info.resolution.y, 5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::X_DIRECTION);  	}; @@ -240,7 +240,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 2);  		EXPECT_EQ(ev.info.resolution.x, 5); -		EXPECT_EQ(ev.info.resolution.y, 5); +		EXPECT_EQ(ev.info.resolution.y, -5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::X_DIRECTION);  	}; @@ -260,7 +260,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) {  	script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 1); -		EXPECT_EQ(ev.info.resolution.x, -5); +		EXPECT_EQ(ev.info.resolution.x, 5);  		EXPECT_EQ(ev.info.resolution.y, -5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::Y_DIRECTION); @@ -268,7 +268,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) {  	script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 2); -		EXPECT_EQ(ev.info.resolution.x, 5); +		EXPECT_EQ(ev.info.resolution.x, -5);  		EXPECT_EQ(ev.info.resolution.y, 5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::Y_DIRECTION); @@ -312,7 +312,7 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 1);  		EXPECT_EQ(ev.info.resolution.x, -5); -		EXPECT_EQ(ev.info.resolution.y, -5); +		EXPECT_EQ(ev.info.resolution.y, 5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::X_DIRECTION);  	}; @@ -336,7 +336,7 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) {  	script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) {  		collision_happend = true;  		EXPECT_EQ(ev.info.this_collider.game_object_id, 1); -		EXPECT_EQ(ev.info.resolution.x, -5); +		EXPECT_EQ(ev.info.resolution.x, 5);  		EXPECT_EQ(ev.info.resolution.y, -5);  		EXPECT_EQ(ev.info.resolution_direction,  				  crepe::CollisionSystem::Direction::Y_DIRECTION); diff --git a/src/test/LoopTimerTest.cpp b/src/test/LoopTimerTest.cpp index d76bf45..7bd6305 100644 --- a/src/test/LoopTimerTest.cpp +++ b/src/test/LoopTimerTest.cpp @@ -30,7 +30,7 @@ TEST_F(LoopTimerTest, EnforcesTargetFrameRate) {  	auto elapsed_ms = duration_cast<milliseconds>(elapsed_time).count();  	// For 60 FPS, the target frame time is around 16.67ms -	ASSERT_NEAR(elapsed_ms, 16.7, 1); +	ASSERT_NEAR(elapsed_ms, 16.7, 5);  }  TEST_F(LoopTimerTest, SetTargetFps) { @@ -79,3 +79,19 @@ TEST_F(LoopTimerTest, DISABLED_getCurrentTime) {  	ASSERT_NEAR(loop_timer.get_elapsed_time().count(), elapsed_time, 5);  } +TEST_F(LoopTimerTest, getFPS) { +	// Set the target FPS to 60 (which gives a target time per frame of ~16.67 ms) +	loop_timer.set_target_framerate(60); + +	auto start_time = steady_clock::now(); +	loop_timer.enforce_frame_rate(); + +	auto elapsed_time = steady_clock::now() - start_time; +	loop_timer.update(); +	unsigned int fps = loop_timer.get_fps(); +	auto elapsed_ms = duration_cast<milliseconds>(elapsed_time).count(); + +	// For 60 FPS, the target frame time is around 16.67ms +	ASSERT_NEAR(elapsed_ms, 16.7, 1); +	ASSERT_NEAR(fps, 60, 2); +} diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 9bb260c..480e07a 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -15,11 +15,9 @@ using namespace crepe;  class ConcreteScene1 : public Scene {  public:  	void load_scene() { -		Mediator & mediator = this->mediator; -		ComponentManager & mgr = mediator.component_manager; -		GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", vec2{0, 0}, 0, 1); -		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", vec2{1, 0}, 0, 1); -		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", vec2{2, 0}, 0, 1); +		GameObject object1 = new_object("scene_1", "tag_scene_1", vec2{0, 0}, 0, 1); +		GameObject object2 = new_object("scene_1", "tag_scene_1", vec2{1, 0}, 0, 1); +		GameObject object3 = new_object("scene_1", "tag_scene_1", vec2{2, 0}, 0, 1);  	}  	string get_name() const { return "scene1"; } @@ -28,12 +26,10 @@ public:  class ConcreteScene2 : public Scene {  public:  	void load_scene() { -		Mediator & mediator = this->mediator; -		ComponentManager & mgr = mediator.component_manager; -		GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 0}, 0, 1); -		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 1}, 0, 1); -		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 2}, 0, 1); -		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 3}, 0, 1); +		GameObject object1 = new_object("scene_2", "tag_scene_2", vec2{0, 0}, 0, 1); +		GameObject object2 = new_object("scene_2", "tag_scene_2", vec2{0, 1}, 0, 1); +		GameObject object3 = new_object("scene_2", "tag_scene_2", vec2{0, 2}, 0, 1); +		GameObject object4 = new_object("scene_2", "tag_scene_2", vec2{0, 3}, 0, 1);  	}  	string get_name() const { return "scene2"; } @@ -44,9 +40,7 @@ public:  	ConcreteScene3(const string & name) : name(name) {}  	void load_scene() { -		Mediator & mediator = this->mediator; -		ComponentManager & mgr = mediator.component_manager; -		GameObject object1 = mgr.new_object("scene_3", "tag_scene_3", vec2{0, 0}, 0, 1); +		GameObject object1 = new_object("scene_3", "tag_scene_3", vec2{0, 0}, 0, 1);  	}  	string get_name() const { return name; }  |