diff options
Diffstat (limited to 'src/crepe')
| -rw-r--r-- | src/crepe/Particle.cpp | 13 | ||||
| -rw-r--r-- | src/crepe/Particle.h | 11 | ||||
| -rw-r--r-- | src/crepe/api/Config.h | 2 | ||||
| -rw-r--r-- | src/crepe/api/ParticleEmitter.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/api/ParticleEmitter.h | 31 | ||||
| -rw-r--r-- | src/crepe/api/Rigidbody.h | 2 | ||||
| -rw-r--r-- | src/crepe/system/AISystem.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 3 | ||||
| -rw-r--r-- | src/crepe/system/ParticleSystem.cpp | 60 | ||||
| -rw-r--r-- | src/crepe/system/ParticleSystem.h | 15 | ||||
| -rw-r--r-- | src/crepe/system/PhysicsSystem.cpp | 119 | 
11 files changed, 125 insertions, 138 deletions
| diff --git a/src/crepe/Particle.cpp b/src/crepe/Particle.cpp index 485a0d4..b340826 100644 --- a/src/crepe/Particle.cpp +++ b/src/crepe/Particle.cpp @@ -2,8 +2,8 @@  using namespace crepe; -void Particle::reset(uint32_t lifespan, const vec2 & position, const vec2 & velocity, -					 double angle) { +void Particle::reset(unsigned int lifespan, const vec2 & position, const vec2 & velocity, +					 float angle) {  	// Initialize the particle state  	this->time_in_life = 0;  	this->lifespan = lifespan; @@ -15,16 +15,17 @@ void Particle::reset(uint32_t lifespan, const vec2 & position, const vec2 & velo  	this->force_over_time = {0, 0};  } -void Particle::update() { +void Particle::update(double dt) {  	// Deactivate particle if it has exceeded its lifespan -	if (++time_in_life >= lifespan) { +	time_in_life += dt; +	if (time_in_life >= lifespan) {  		this->active = false;  		return;  	}  	// Update velocity based on accumulated force and update position -	this->velocity += force_over_time; -	this->position += velocity; +	this->velocity += force_over_time * dt; +	this->position += velocity * dt;  }  void Particle::stop_movement() { diff --git a/src/crepe/Particle.h b/src/crepe/Particle.h index d0397c9..49fec1f 100644 --- a/src/crepe/Particle.h +++ b/src/crepe/Particle.h @@ -24,13 +24,13 @@ public:  	//! Accumulated force affecting the particle over time.  	vec2 force_over_time;  	//! Total lifespan of the particle in milliseconds. -	uint32_t lifespan; +	float lifespan;  	//! Active state of the particle; true if it is in use, false otherwise.  	bool active = false;  	//! The time the particle has been alive, in milliseconds. -	uint32_t time_in_life = 0; +	float time_in_life = 0;  	//! The angle at which the particle is oriented or moving. -	double angle = 0; +	float angle = 0;  	/**  	 * \brief Resets the particle with new properties. @@ -43,14 +43,15 @@ public:  	 * \param velocity  The initial velocity of the particle.  	 * \param angle     The angle of the particle's trajectory or orientation.  	 */ -	void reset(uint32_t lifespan, const vec2 & position, const vec2 & velocity, double angle); +	void reset(unsigned int lifespan, const vec2 & position, const vec2 & velocity, float angle);  	/**  	 * \brief Updates the particle's state.  	 *  	 * Advances the particle's position based on its velocity and applies accumulated forces.  	 * Deactivates the particle if its lifespan has expired. +	 * \param dt The amount of fixed delta time that has passed.  	 */ -	void update(); +	void update(double dt);  	/**  	 * \brief Stops the particle's movement.  	 * diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index 6472270..cd27343 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -53,7 +53,7 @@ struct Config final {  		 *  		 * Gravity value of game.  		 */ -		double gravity = 1; +		float gravity = 1;  	} physics;  	//! default window settings diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp index 90b77a0..1cfdceb 100644 --- a/src/crepe/api/ParticleEmitter.cpp +++ b/src/crepe/api/ParticleEmitter.cpp @@ -1,10 +1,11 @@  #include "ParticleEmitter.h" +#include "api/Sprite.h"  using namespace crepe; -ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id, const Data & data) +ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id, const Sprite & sprite, const Data & data)  	: Component(game_object_id), -	  data(data) { +	  sprite(sprite), data(data) {  	for (size_t i = 0; i < this->data.max_particles; i++) {  		this->data.particles.emplace_back();  	} diff --git a/src/crepe/api/ParticleEmitter.h b/src/crepe/api/ParticleEmitter.h index b83fd61..48c7625 100644 --- a/src/crepe/api/ParticleEmitter.h +++ b/src/crepe/api/ParticleEmitter.h @@ -1,5 +1,6 @@  #pragma once +#include <cmath>  #include <vector>  #include "Component.h" @@ -26,15 +27,18 @@ public:  	 */  	struct Boundary {  		//! boundary width (midpoint is emitter location) -		double width = 0.0; +		float width = INFINITY;  		//! boundary height (midpoint is emitter location) -		double height = 0.0; +		float height = INFINITY;  		//! boundary offset from particle emitter location  		vec2 offset;  		//! reset on exit or stop velocity and set max postion  		bool reset_on_exit = false;  	}; +	//! sprite reference of displayed sprite +	const Sprite & sprite; +  	/**  	 * \brief Holds parameters that control particle emission.  	 * @@ -45,29 +49,30 @@ public:  		//! position of the emitter  		vec2 position;  		//! maximum number of particles -		const unsigned int max_particles = 0; +		const unsigned int max_particles = 256;  		//! rate of particle emission per update (Lowest value = 0.001 any lower is ignored) -		double emission_rate = 0; +		float emission_rate = 1; +		//! Saves time left over from last update event. +		float spawn_accumulator  = 0;  		//! min speed of the particles -		double min_speed = 0; +		float min_speed = 1;  		//! min speed of the particles -		double max_speed = 0; +		float max_speed = 2;  		//! min angle of particle emission -		double min_angle = 0; +		float min_angle = 0;  		//! max angle of particle emission -		double max_angle = 0; +		float max_angle = 0;  		//! begin Lifespan of particle (only visual) -		double begin_lifespan = 0.0; +		float begin_lifespan = 0.0;  		//! end Lifespan of particle -		double end_lifespan = 0.0; +		float end_lifespan = 10.0;  		//! force over time (physics)  		vec2 force_over_time;  		//! particle boundary  		Boundary boundary;  		//! collection of particles  		std::vector<Particle> particles; -		//! sprite reference -		const Sprite & sprite; +		  	};  public: @@ -75,7 +80,7 @@ public:  	 * \param game_object_id  Identifier for the game object using this emitter.  	 * \param data            Configuration data defining particle properties.  	 */ -	ParticleEmitter(game_object_id_t game_object_id, const Data & data); +	ParticleEmitter(game_object_id_t game_object_id, const Sprite & sprite,const Data & data);  public:  	//! Configuration data for particle emission settings. diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 40c6bf1..f641fff 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -79,7 +79,7 @@ public:  		//! Linear velocity of the object (speed and direction).  		vec2 linear_velocity;  		//! Maximum linear velocity of the object. This limits the object's speed. -		vec2 max_linear_velocity = {INFINITY, INFINITY}; +		float max_linear_velocity = INFINITY;  		//! Linear velocity coefficient. This scales the object's velocity for adjustment or damping.  		vec2 linear_velocity_coefficient = {1, 1};  		//! \} diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp index d231c7c..1d8ffb9 100644 --- a/src/crepe/system/AISystem.cpp +++ b/src/crepe/system/AISystem.cpp @@ -146,7 +146,7 @@ vec2 AISystem::arrive(const AI & ai, const Rigidbody & rigidbody,  		}  		float speed = distance / ai.arrive_deceleration; -		speed = std::min(speed, rigidbody.data.max_linear_velocity.length()); +		speed = std::min(speed, rigidbody.data.max_linear_velocity);  		vec2 desired_velocity = to_target * (speed / distance);  		return desired_velocity - rigidbody.data.linear_velocity; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 44a0431..dc5270e 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -290,7 +290,10 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co  	// Compute penetration depth  	float penetration_depth = circle_collider.radius - distance; +<<<<<<< HEAD +======= +>>>>>>> 05a33d4793520fa84a93bc79882ef29d39cd08e5  	// Compute the resolution vector  	vec2 resolution = collision_normal * penetration_depth; diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index b14c52f..3befb03 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -12,8 +12,10 @@ using namespace crepe;  void ParticleSystem::update() {  	// Get all emitters +	  	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<ParticleEmitter> emitters = mgr.get_components_by_type<ParticleEmitter>(); +	double dt = LoopTimer::get_instance().get_fixed_delta_time();  	for (ParticleEmitter & emitter : emitters) {  		// Get transform linked to emitter @@ -21,20 +23,21 @@ void ParticleSystem::update() {  			= mgr.get_components_by_id<Transform>(emitter.game_object_id).front().get();  		// Emit particles based on emission_rate -		int updates = calculate_update(this->update_count, emitter.data.emission_rate); -		for (size_t i = 0; i < updates; i++) { -			emit_particle(emitter, transform); -		} - +		emitter.data.spawn_accumulator = emitter.data.emission_rate * dt; +		while (emitter.data.spawn_accumulator >= 1.0) { +			this->emit_particle(emitter, transform); +			emitter.data.spawn_accumulator -= 1.0; +    } +		  		// Update all particles  		for (Particle & particle : emitter.data.particles) {  			if (particle.active) { -				particle.update(); +				particle.update(dt);  			}  		}  		// Check if within boundary -		check_bounds(emitter, transform); +		this->check_bounds(emitter, transform);  	}  	this->update_count = (this->update_count + 1) % this->MAX_UPDATE_COUNT; @@ -44,9 +47,9 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform &  	constexpr float DEG_TO_RAD = M_PI / 180.0;  	vec2 initial_position = emitter.data.position + transform.position; -	float random_angle = generate_random_angle(emitter.data.min_angle, emitter.data.max_angle); +	float random_angle = this->generate_random_angle(emitter.data.min_angle, emitter.data.max_angle); -	float random_speed = generate_random_speed(emitter.data.min_speed, emitter.data.max_speed); +	float random_speed = this->generate_random_speed(emitter.data.min_speed, emitter.data.max_speed);  	float angle_radians = random_angle * DEG_TO_RAD;  	vec2 velocity @@ -61,33 +64,20 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform &  	}  } -int ParticleSystem::calculate_update(int count, double emission) const { -	double integer_part = std::floor(emission); -	double fractional_part = emission - integer_part; - -	if (fractional_part > 0) { -		int denominator = static_cast<int>(1.0 / fractional_part); -		return (count % denominator == 0) ? 1 : 0; -	} - -	return static_cast<int>(emission); -} -  void ParticleSystem::check_bounds(ParticleEmitter & emitter, const Transform & transform) {  	vec2 offset = emitter.data.boundary.offset + transform.position + emitter.data.position; -	double half_width = emitter.data.boundary.width / 2.0; -	double half_height = emitter.data.boundary.height / 2.0; +	float half_width = emitter.data.boundary.width / 2.0; +	float half_height = emitter.data.boundary.height / 2.0; -	const double LEFT = offset.x - half_width; -	const double RIGHT = offset.x + half_width; -	const double TOP = offset.y - half_height; -	const double BOTTOM = offset.y + half_height; +	const float LEFT = offset.x - half_width; +	const float RIGHT = offset.x + half_width; +	const float TOP = offset.y - half_height; +	const float BOTTOM = offset.y + half_height;  	for (Particle & particle : emitter.data.particles) {  		const vec2 & position = particle.position;  		bool within_bounds = (position.x >= LEFT && position.x <= RIGHT && position.y >= TOP  							  && position.y <= BOTTOM); -  		if (!within_bounds) {  			if (emitter.data.boundary.reset_on_exit) {  				particle.active = false; @@ -102,25 +92,25 @@ void ParticleSystem::check_bounds(ParticleEmitter & emitter, const Transform & t  	}  } -double ParticleSystem::generate_random_angle(double min_angle, double max_angle) const { +float ParticleSystem::generate_random_angle(float min_angle, float max_angle) const {  	if (min_angle == max_angle) {  		return min_angle;  	} else if (min_angle < max_angle) {  		return min_angle -			   + static_cast<double>(std::rand() % static_cast<int>(max_angle - min_angle)); +			   + static_cast<float>(std::rand() % static_cast<int>(max_angle - min_angle));  	} else { -		double angle_offset = (360 - min_angle) + max_angle; -		double random_angle -			= min_angle + static_cast<double>(std::rand() % static_cast<int>(angle_offset)); +		float angle_offset = (360 - min_angle) + max_angle; +		float random_angle +			= min_angle + static_cast<float>(std::rand() % static_cast<int>(angle_offset));  		return (random_angle >= 360) ? random_angle - 360 : random_angle;  	}  } -double ParticleSystem::generate_random_speed(double min_speed, double max_speed) const { +float ParticleSystem::generate_random_speed(float min_speed, float max_speed) const {  	if (min_speed == max_speed) {  		return min_speed;  	} else {  		return min_speed -			   + static_cast<double>(std::rand() % static_cast<int>(max_speed - min_speed)); +			   + static_cast<float>(std::rand() % static_cast<int>(max_speed - min_speed));  	}  } diff --git a/src/crepe/system/ParticleSystem.h b/src/crepe/system/ParticleSystem.h index 068f01c..454b65f 100644 --- a/src/crepe/system/ParticleSystem.h +++ b/src/crepe/system/ParticleSystem.h @@ -23,6 +23,7 @@ public:  	void update() override;  private: +  	/**  	 * \brief Emits a particle from the specified emitter based on its emission properties.  	 * @@ -32,16 +33,6 @@ private:  	void emit_particle(ParticleEmitter & emitter, const Transform & transform);  	/** -	 * \brief Calculates the number of times particles should be emitted based on emission rate -	 * and update count. -	 * -	 * \param count Current update count. -	 * \param emission Emission rate. -	 * \return The number of particles to emit. -	 */ -	int calculate_update(int count, double emission) const; - -	/**  	 * \brief Checks whether particles are within the emitter’s boundary, resets or stops  	 * particles if they exit.  	 * @@ -57,7 +48,7 @@ private:  	 * \param max_angle Maximum emission angle in degrees.  	 * \return Random angle in degrees.  	 */ -	double generate_random_angle(double min_angle, double max_angle) const; +	float generate_random_angle(float min_angle, float max_angle) const;  	/**  	 * \brief Generates a random speed for particle emission within the specified range. @@ -66,7 +57,7 @@ private:  	 * \param max_speed Maximum emission speed.  	 * \return Random speed.  	 */ -	double generate_random_speed(double min_speed, double max_speed) const; +	float generate_random_speed(float min_speed, float max_speed) const;  private:  	//! Counter to count updates to determine how many times emit_particle is diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index ebf4439..be768f9 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -11,82 +11,77 @@  using namespace crepe;  void PhysicsSystem::update() { +	double dt = LoopTimer::get_instance().get_fixed_delta_time();  	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Rigidbody> rigidbodies = mgr.get_components_by_type<Rigidbody>(); -	RefVector<Transform> transforms = mgr.get_components_by_type<Transform>(); +	 -	double gravity = Config::get_instance().physics.gravity; +	float gravity = Config::get_instance().physics.gravity;  	for (Rigidbody & rigidbody : rigidbodies) {  		if (!rigidbody.active) continue; +		Transform & transform = mgr.get_components_by_id<Transform>(rigidbody.game_object_id).front().get();  		switch (rigidbody.data.body_type) {  			case Rigidbody::BodyType::DYNAMIC: -				for (Transform & transform : transforms) { -					if (transform.game_object_id == rigidbody.game_object_id) { - -						// Add gravity -						if (rigidbody.data.gravity_scale > 0) { -							rigidbody.data.linear_velocity.y -								+= (rigidbody.data.mass * rigidbody.data.gravity_scale -									* gravity); -						} -						// Add damping -						if (rigidbody.data.angular_velocity_coefficient > 0) { -							rigidbody.data.angular_velocity -								*= rigidbody.data.angular_velocity_coefficient; -						} -						if (rigidbody.data.linear_velocity_coefficient.x > 0 -							&& rigidbody.data.linear_velocity_coefficient.y > 0) { -							rigidbody.data.linear_velocity -								*= rigidbody.data.linear_velocity_coefficient; -						} +				if (transform.game_object_id == rigidbody.game_object_id) { +					// Add gravity +					if (rigidbody.data.gravity_scale > 0) { +						rigidbody.data.linear_velocity.y +							+= (rigidbody.data.mass * rigidbody.data.gravity_scale +								* gravity * dt); +					} +					// Add coefficient rotation +					if (rigidbody.data.angular_velocity_coefficient > 0) { +						rigidbody.data.angular_velocity +							*= std::pow(rigidbody.data.angular_velocity_coefficient, dt); +							 +					} -						// Max velocity check -						if (rigidbody.data.angular_velocity -							> rigidbody.data.max_angular_velocity) { -							rigidbody.data.angular_velocity -								= rigidbody.data.max_angular_velocity; -						} else if (rigidbody.data.angular_velocity -								   < -rigidbody.data.max_angular_velocity) { -							rigidbody.data.angular_velocity -								= -rigidbody.data.max_angular_velocity; -						} +					// Add coefficient movement horizontal +					if (rigidbody.data.linear_velocity_coefficient.x > 0) +					{ +						rigidbody.data.linear_velocity.x +								*= std::pow(rigidbody.data.linear_velocity_coefficient.x, dt); +					} -						if (rigidbody.data.linear_velocity.x -							> rigidbody.data.max_linear_velocity.x) { -							rigidbody.data.linear_velocity.x -								= rigidbody.data.max_linear_velocity.x; -						} else if (rigidbody.data.linear_velocity.x -								   < -rigidbody.data.max_linear_velocity.x) { -							rigidbody.data.linear_velocity.x -								= -rigidbody.data.max_linear_velocity.x; -						} +					// Add coefficient movement horizontal +					if (rigidbody.data.linear_velocity_coefficient.y > 0) +					{ +						rigidbody.data.linear_velocity.y +								*= std::pow(rigidbody.data.linear_velocity_coefficient.y, dt); +					} -						if (rigidbody.data.linear_velocity.y -							> rigidbody.data.max_linear_velocity.y) { -							rigidbody.data.linear_velocity.y -								= rigidbody.data.max_linear_velocity.y; -						} else if (rigidbody.data.linear_velocity.y -								   < -rigidbody.data.max_linear_velocity.y) { -							rigidbody.data.linear_velocity.y -								= -rigidbody.data.max_linear_velocity.y; -						} +					// Max velocity check +					if (rigidbody.data.angular_velocity +						> rigidbody.data.max_angular_velocity) { +						rigidbody.data.angular_velocity +							= rigidbody.data.max_angular_velocity; +					} else if (rigidbody.data.angular_velocity +									< -rigidbody.data.max_angular_velocity) { +						rigidbody.data.angular_velocity +							= -rigidbody.data.max_angular_velocity; +					} +					 +					// Set max velocity to maximum length +					if(rigidbody.data.linear_velocity.length() > rigidbody.data.max_linear_velocity) { +						rigidbody.data.linear_velocity.normalize(); +						rigidbody.data.linear_velocity *= rigidbody.data.max_linear_velocity; +					} -						// Move object -						if (!rigidbody.data.constraints.rotation) { -							transform.rotation += rigidbody.data.angular_velocity; -							transform.rotation = std::fmod(transform.rotation, 360.0); -							if (transform.rotation < 0) { -								transform.rotation += 360.0; -							} -						} -						if (!rigidbody.data.constraints.x) { -							transform.position.x += rigidbody.data.linear_velocity.x; -						} -						if (!rigidbody.data.constraints.y) { -							transform.position.y += rigidbody.data.linear_velocity.y; +					// Move object +					if (!rigidbody.data.constraints.rotation) { +						transform.rotation += rigidbody.data.angular_velocity * dt; +						transform.rotation = std::fmod(transform.rotation, 360.0); +						if (transform.rotation < 0) { +							transform.rotation += 360.0;  						}  					} +					if (!rigidbody.data.constraints.x) { +						transform.position.x += rigidbody.data.linear_velocity.x * dt; +					} +					if (!rigidbody.data.constraints.y) { +						transform.position.y += rigidbody.data.linear_velocity.y * dt; +					}  				}  				break;  			case Rigidbody::BodyType::KINEMATIC: |