From 387bf02833c610f93326bf743db463eea8032a62 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 16:43:02 +0100 Subject: added collision features --- src/crepe/api/Rigidbody.h | 3 ++ src/crepe/system/CollisionSystem.cpp | 79 ++++++++++++++++++++++++++++++++---- src/crepe/system/CollisionSystem.h | 18 ++++++++ 3 files changed, 92 insertions(+), 8 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index b08c8db..8169f0c 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -132,6 +132,9 @@ public: */ vec2 offset; + //! Enable collision handeling in collision system + bool kinematic_collision = true; + /** * \brief Defines the collision layers of a GameObject. * diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index af8adce..4e84d8b 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -63,7 +63,7 @@ void CollisionSystem::update() { // For both objects call the collision handler for (auto & collision_pair : collided) { this->collision_handler_request(collision_pair.first, collision_pair.second); - this->collision_handler_request(collision_pair.second, collision_pair.first); + // this->collision_handler_request(collision_pair.second, collision_pair.first); } } @@ -302,16 +302,57 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co } void CollisionSystem::determine_collision_handler(CollisionInfo & info) { - // Check rigidbody type for static - if (info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; - // If second body is static perform the static collision handler in this system - if (info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) { - this->static_collision_handler(info); - }; - // Call collision event for user + // If both objects are static skip handle call collision script + if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + + // First body is not dynamic + if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) + { + bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; + bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; + // Inverted collision info + CollisionInfo inverted = { + .this_collider = info.other_collider, + .this_transform = info.other_transform, + .this_rigidbody = info.other_rigidbody, + .this_metadata = info.other_metadata, + .other_collider = info.this_collider, + .other_transform = info.this_transform, + .other_rigidbody = info.this_rigidbody, + .other_metadata = info.this_metadata, + .resolution = -info.resolution, + .resolution_direction = info.resolution_direction, + }; + + if(static_collision || kinematic_collision){ + // Static collision + this->static_collision_handler(inverted); + }; + // Call scripts + this->call_collision_events(inverted); + return; + } + + // Second body is not dynamic + if(info.other_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) + { + bool static_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC; + bool kinematic_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.kinematic_collision; + if(static_collision || kinematic_collision) this->static_collision_handler(info); + this->call_collision_events(info); + return; + } + + //dynamic + this->dynamic_collision_handler(info); + this->call_collision_events(info); +} + +void CollisionSystem::call_collision_events(CollisionInfo & info){ CollisionEvent data(info); EventManager & emgr = this->mediator.event_manager; emgr.trigger_event(data, info.this_collider.game_object_id); + emgr.trigger_event(data, info.other_collider.game_object_id); } void CollisionSystem::static_collision_handler(CollisionInfo & info) { @@ -363,6 +404,28 @@ void CollisionSystem::static_collision_handler(CollisionInfo & info) { } } +void CollisionSystem::dynamic_collision_handler(CollisionInfo & info){ + info.this_transform.position += info.resolution/2; + info.other_transform.position += -(info.resolution/2); + + switch (info.resolution_direction) { + case Direction::BOTH: + info.this_rigidbody.data.linear_velocity = {0, 0}; + break; + case Direction::Y_DIRECTION: + info.this_rigidbody.data.linear_velocity.y = 0; + info.this_transform.position.x -= info.resolution.x; + break; + case Direction::X_DIRECTION: + info.this_rigidbody.data.linear_velocity.x = 0; + info.this_transform.position.y -= info.resolution.y; + break; + case Direction::NONE: + // Not possible + break; + } +} + std::vector> CollisionSystem::gather_collisions(std::vector & colliders) { diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 5b136c6..aebb59b 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -194,6 +194,15 @@ private: */ void determine_collision_handler(CollisionInfo & info); + /** + * \brief Calls both collision script + * + * Calls both collision script to let user add additonal handeling or handle full collision. + * + * \param info Collision information containing data about both colliders. + */ + void call_collision_events(CollisionInfo & info); + /** * \brief Handles collisions involving static objects. * @@ -203,6 +212,15 @@ private: */ void static_collision_handler(CollisionInfo & info); + /** + * \brief Handles collisions involving dynamic objects. + * + * Resolves collisions by adjusting positions and modifying velocities if bounce is enabled. + * + * \param info Collision information containing data about both colliders. + */ + void dynamic_collision_handler(CollisionInfo & info); + private: /** * \brief Checks for collisions between colliders. -- cgit v1.2.3 From b3f0e0da03a3cd4976a5a90d040cbe7fd7472987 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 18:32:26 +0100 Subject: added dynamic bounce --- src/crepe/system/CollisionSystem.cpp | 64 +++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 4e84d8b..0cd6f5c 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -410,15 +410,69 @@ void CollisionSystem::dynamic_collision_handler(CollisionInfo & info){ switch (info.resolution_direction) { case Direction::BOTH: - info.this_rigidbody.data.linear_velocity = {0, 0}; + 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; + } + else { + info.this_rigidbody.data.linear_velocity = {0, 0}; + } + + if (info.other_rigidbody.data.elastisity_coefficient > 0) { + info.other_rigidbody.data.linear_velocity + = -info.other_rigidbody.data.linear_velocity + * info.other_rigidbody.data.elastisity_coefficient; + } + else { + info.other_rigidbody.data.linear_velocity = {0, 0}; + } break; case Direction::Y_DIRECTION: - info.this_rigidbody.data.linear_velocity.y = 0; - info.this_transform.position.x -= info.resolution.x; + 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; + } + + if (info.other_rigidbody.data.elastisity_coefficient > 0) { + info.other_rigidbody.data.linear_velocity.y + = -info.other_rigidbody.data.linear_velocity.y + * info.other_rigidbody.data.elastisity_coefficient; + } + // Stop movement + else { + info.other_rigidbody.data.linear_velocity.y = 0; + info.other_transform.position.x -= info.resolution.x; + } break; case Direction::X_DIRECTION: - info.this_rigidbody.data.linear_velocity.x = 0; - info.this_transform.position.y -= info.resolution.y; + 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; + } + + if (info.other_rigidbody.data.elastisity_coefficient > 0) { + info.other_rigidbody.data.linear_velocity.x + = -info.other_rigidbody.data.linear_velocity.x + * info.other_rigidbody.data.elastisity_coefficient; + } + // Stop movement + else { + info.other_rigidbody.data.linear_velocity.x = 0; + info.other_transform.position.y -= info.resolution.y; + } break; case Direction::NONE: // Not possible -- cgit v1.2.3 From 17587d6b3d57c7e063514701f88d22a9a50e402f Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 18:38:44 +0100 Subject: scale collider by transform --- src/crepe/system/CollisionSystem.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 0cd6f5c..cb6fe2c 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -609,11 +609,15 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxC vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); vec2 final_position2 = this->get_current_position(box2.offset, transform2, rigidbody2); + // Scale dimensions + vec2 scaled_box1 = box1.dimensions * transform1.scale; + vec2 scaled_box2 = box2.dimensions * transform2.scale; + // Calculate half-extents (half width and half height) - float half_width1 = box1.dimensions.x / 2.0; - float half_height1 = box1.dimensions.y / 2.0; - float half_width2 = box2.dimensions.x / 2.0; - float half_height2 = box2.dimensions.y / 2.0; + float half_width1 = scaled_box1.x / 2.0; + float half_height1 = scaled_box1.y / 2.0; + float half_width2 = scaled_box2.x / 2.0; + float half_height2 = scaled_box2.y / 2.0; // Check if the boxes overlap along the X and Y axes return (final_position1.x + half_width1 > final_position2.x - half_width2 @@ -632,9 +636,13 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); + // Scale dimensions + vec2 scaled_box = box1.dimensions * transform1.scale; + float scaled_circle = circle2.radius * transform2.scale; + // Calculate box half-extents - float half_width = box1.dimensions.x / 2.0; - float half_height = box1.dimensions.y / 2.0; + float half_width = scaled_box.x / 2.0; + float half_height = scaled_box.y / 2.0; // Find the closest point on the box to the circle's center float closest_x = std::max(final_position1.x - half_width, @@ -648,7 +656,7 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, float distance_squared = distance_x * distance_x + distance_y * distance_y; // Compare distance squared with the square of the circle's radius - return distance_squared < circle2.radius * circle2.radius; + return distance_squared < scaled_circle * scaled_circle; } bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1, @@ -661,12 +669,16 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 vec2 final_position1 = this->get_current_position(circle1.offset, transform1, rigidbody1); vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); + // Scale dimensions + float scaled_circle1 = circle1.radius * transform1.scale; + float scaled_circle2 = circle2.radius * transform2.scale; + float distance_x = final_position1.x - final_position2.x; float distance_y = final_position1.y - final_position2.y; float distance_squared = distance_x * distance_x + distance_y * distance_y; // Calculate the sum of the radii - float radius_sum = circle1.radius + circle2.radius; + float radius_sum = scaled_circle1 + scaled_circle2; // Check if the distance between the centers is less than or equal to the sum of the radii return distance_squared < radius_sum * radius_sum; -- cgit v1.2.3 From b2a7105fa88b7d23dcb5b698c3c10b76c19c789b Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 18:52:06 +0100 Subject: removed rigidbody offset --- src/crepe/api/Rigidbody.h | 10 ------ src/crepe/system/CollisionSystem.cpp | 70 ++++++++++++++++-------------------- src/crepe/system/CollisionSystem.h | 13 ------- 3 files changed, 31 insertions(+), 62 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 8169f0c..8566d00 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -122,16 +122,6 @@ public: */ float elastisity_coefficient = 0.0; - /** - * \brief Offset of all colliders relative to the object's transform position. - * - * The `offset` defines a positional shift applied to all colliders associated with the object, relative to the object's - * transform position. This allows for the colliders to be placed at a different position than the object's actual - * position, without modifying the object's transform itself. - * - */ - vec2 offset; - //! Enable collision handeling in collision system bool kinematic_collision = true; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index cb6fe2c..fc8c430 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -23,6 +23,23 @@ using namespace crepe; +vec2 get_current_position(const Transform & transform,const vec2 & offset) { + // Get the rotation in radians + float radians1 = transform.rotation * (M_PI / 180.0); + + // Calculate total offset with scale + vec2 total_offset = offset * transform.scale; + + // Rotate + float rotated_total_offset_x1 + = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); + float rotated_total_offset_y1 + = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); + + // Final positions considering scaling and rotation + return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); +} + void CollisionSystem::update() { std::vector all_colliders; game_object_id_t id = 0; @@ -138,10 +155,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, - data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, - data2.rigidbody); + vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); + vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); resolution = this->get_box_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -151,10 +166,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, - data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, - data2.rigidbody); + vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); + vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2, collider_pos1); break; @@ -164,10 +177,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, - data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, - data2.rigidbody); + vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); + vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); resolution = this->get_circle_circle_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -177,10 +188,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, - data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, - data2.rigidbody); + vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); + vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -606,8 +615,8 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxC const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); - vec2 final_position2 = this->get_current_position(box2.offset, transform2, rigidbody2); + vec2 final_position1 = get_current_position(transform1,box1.offset); + vec2 final_position2 = get_current_position(transform2,box2.offset); // Scale dimensions vec2 scaled_box1 = box1.dimensions * transform1.scale; @@ -633,8 +642,8 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); - vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); + vec2 final_position1 = get_current_position(transform1,box1.offset); + vec2 final_position2 = get_current_position(transform2,circle2.offset); // Scale dimensions vec2 scaled_box = box1.dimensions * transform1.scale; @@ -666,8 +675,8 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = this->get_current_position(circle1.offset, transform1, rigidbody1); - vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); + vec2 final_position1 = get_current_position(transform1,circle1.offset); + vec2 final_position2 = get_current_position(transform2,circle2.offset); // Scale dimensions float scaled_circle1 = circle1.radius * transform1.scale; @@ -684,21 +693,4 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 return distance_squared < radius_sum * radius_sum; } -vec2 CollisionSystem::get_current_position(const vec2 & collider_offset, - const Transform & transform, - const Rigidbody & rigidbody) const { - // Get the rotation in radians - float radians1 = transform.rotation * (M_PI / 180.0); - - // Calculate total offset with scale - vec2 total_offset = (rigidbody.data.offset + collider_offset) * transform.scale; - - // Rotate - float rotated_total_offset_x1 - = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); - float rotated_total_offset_y1 - = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); - // Final positions considering scaling and rotation - return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); -} diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index aebb59b..78fce46 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -100,19 +100,6 @@ private: CollisionInternalType get_collider_type(const collider_variant & collider1, const collider_variant & collider2) const; - /** - * \brief Calculates the current position of a collider. - * - * Combines the Collider offset, Transform position, and Rigidbody offset to compute the position of the collider. - * - * \param collider_offset The offset of the collider. - * \param transform The Transform of the associated game object. - * \param rigidbody The Rigidbody of the associated game object. - * \return The calculated position of the collider. - */ - vec2 get_current_position(const vec2 & collider_offset, const Transform & transform, - const Rigidbody & rigidbody) const; - private: /** * \brief Handles collision resolution between two colliders. -- cgit v1.2.3 From 8abc6008880dd9ed0c16a68a126b49f0eb03caa2 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 16 Dec 2024 20:52:43 +0100 Subject: fonting --- src/crepe/api/Config.h | 2 +- src/crepe/api/Text.cpp | 5 ++++- src/crepe/facade/Font.cpp | 10 ++++++++-- src/crepe/facade/Font.h | 1 + src/crepe/facade/SDLContext.cpp | 24 ++++++++++++++++++++++++ src/crepe/facade/SDLContext.h | 4 ++++ src/crepe/system/RenderSystem.cpp | 19 +++++++++++++++++++ src/crepe/system/RenderSystem.h | 2 ++ src/example/rendering_particle.cpp | 25 +++++-------------------- 9 files changed, 68 insertions(+), 24 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index 47a81b7..c20287d 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -26,7 +26,7 @@ struct Config final { * * Only messages with equal or higher priority than this value will be logged. */ - Log::Level level = Log::Level::INFO; + Log::Level level = Log::Level::DEBUG; /** * \brief Colored log output * diff --git a/src/crepe/api/Text.cpp b/src/crepe/api/Text.cpp index 5b2befe..07d1705 100644 --- a/src/crepe/api/Text.cpp +++ b/src/crepe/api/Text.cpp @@ -1,4 +1,5 @@ #include "../facade/FontFacade.h" +#include "util/Log.h" #include "Text.h" @@ -9,4 +10,6 @@ Text::Text(game_object_id_t id, const vec2 & dimensions, const vec2 & offset, : UIObject(id, dimensions, offset), text(text), data(data), - font(FontFacade::get_font_asset(font_family)) {} + font(FontFacade::get_font_asset(font_family)) { + dbg_trace(); +} diff --git a/src/crepe/facade/Font.cpp b/src/crepe/facade/Font.cpp index 1ee3de1..83e8519 100644 --- a/src/crepe/facade/Font.cpp +++ b/src/crepe/facade/Font.cpp @@ -1,4 +1,5 @@ #include "../api/Config.h" +#include "util/Log.h" #include "Font.h" @@ -6,8 +7,8 @@ using namespace std; using namespace crepe; Font::Font(const Asset & src, Mediator & mediator) - : Resource(src, mediator), - font(nullptr, TTF_CloseFont) { + : Resource(src, mediator) { + dbg_trace(); Config & config = Config::get_instance(); const std::string FONT_PATH = src.get_path(); TTF_Font * font = TTF_OpenFont(FONT_PATH.c_str(), config.font.size); @@ -16,4 +17,9 @@ Font::Font(const Asset & src, Mediator & mediator) this->font = {font, [](TTF_Font * font) { TTF_CloseFont(font); }}; } +Font::~Font(){ + dbg_trace(); + this->font.reset(); +} + TTF_Font * Font::get_font() const { return this->font.get(); } diff --git a/src/crepe/facade/Font.h b/src/crepe/facade/Font.h index e93bfe9..e9f5fa1 100644 --- a/src/crepe/facade/Font.h +++ b/src/crepe/facade/Font.h @@ -22,6 +22,7 @@ public: * \param mediator The Mediator object used for managing the SDL context or related systems. */ Font(const Asset & src, Mediator & mediator); + ~Font(); /** * \brief Gets the underlying TTF_Font resource. diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index d1d109c..4e969b9 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -21,6 +21,8 @@ #include "../api/Config.h" #include "../api/Sprite.h" #include "../util/Log.h" +#include "api/Text.h" +#include "facade/Font.h" #include "manager/Mediator.h" #include "SDLContext.h" @@ -283,6 +285,28 @@ void SDLContext::draw(const RenderContext & ctx) { angle, NULL, render_flip); } + +void SDLContext::draw_text(const Text & text, const Font & font){ + SDL_Color color { + .r = text.data.text_color.r, + .g = text.data.text_color.g, + .b = text.data.text_color.b, + .a = text.data.text_color.a, + }; + SDL_Surface * font_surface = TTF_RenderText_Solid(font.get_font(), text.text.c_str(), color); + SDL_Texture * font_texture = SDL_CreateTextureFromSurface(this->game_renderer.get(), font_surface); + SDL_FreeSurface(font_surface); + + SDL_FRect dstrect { + .x = text.offset.x, + .y = text.offset.y, + .w = text.dimensions.x, + .h = text.dimensions.y, + }; + SDL_RenderCopyExF(this->game_renderer.get(), font_texture, NULL, &dstrect , 0 , NULL, SDL_FLIP_NONE); + SDL_DestroyTexture(font_texture); +} + void SDLContext::update_camera_view(const Camera & cam, const vec2 & new_pos) { const Camera::Data & cam_data = cam.data; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index efdd6fe..3f9f9ee 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -20,6 +20,8 @@ namespace crepe { class Texture; +class Text; +class Font; class Mediator; /** @@ -183,6 +185,8 @@ public: */ void draw(const RenderContext & ctx); + void draw_text(const Text & text, const Font & font); + //! Clears the screen, preparing for a new frame. void clear_screen(); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index afd9548..7f00891 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -15,6 +15,8 @@ #include "../manager/ResourceManager.h" #include "RenderSystem.h" +#include "api/Text.h" +#include "facade/Font.h" #include "types.h" using namespace crepe; @@ -67,9 +69,26 @@ RefVector RenderSystem::sort(RefVector & objs) const { void RenderSystem::update() { this->clear_screen(); this->render(); + this->render_text(); this->present_screen(); } + +void RenderSystem::render_text(){ + SDLContext & ctx = this->mediator.sdl_context; + ComponentManager & mgr = this->mediator.component_manager; + ResourceManager & resource_manager = this->mediator.resource_manager; + + RefVector texts = mgr.get_components_by_type(); + + for (Text & text : texts) { + if (!text.active) continue; + resource_manager.get(text.font); + //ctx.draw_text(text, font); + } + +} + bool RenderSystem::render_particle(const Sprite & sprite, const double & scale) { ComponentManager & mgr = this->mediator.component_manager; diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index fc7b46e..ae55404 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -27,6 +27,8 @@ public: void update() override; private: + + void render_text(); //! Clears the screen in preparation for rendering. void clear_screen(); diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 13e625f..3857acc 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -1,4 +1,5 @@ #include "api/Asset.h" +#include "api/Text.h" #include #include #include @@ -43,11 +44,7 @@ using namespace std; class TestScene : public Scene { public: void load_scene() { - - cout << "TestScene" << endl; - Mediator & mediator = this->mediator; - ComponentManager & mgr = mediator.component_manager; - GameObject game_object = mgr.new_object("", "", vec2{0, 0}, 0, 1); + GameObject game_object = new_object("", "", vec2{0, 0}, 0, 1); Color color(255, 255, 255, 255); @@ -59,29 +56,17 @@ public: .flip = Sprite::FlipSettings{false, false}, .sorting_in_layer = 2, .order_in_layer = 2, - .size = {0, 100}, + .size = {0, 0}, .angle_offset = 0, .position_offset = {0, 0}, }); - //auto & anim = game_object.add_component(test_sprite,ivec2{32, 64}, uvec2{4,1}, Animator::Data{}); - //anim.set_anim(0); - - auto & cam = game_object.add_component(ivec2{720, 1280}, vec2{400, 400}, + auto & cam = game_object.add_component(ivec2{400, 400}, vec2{400, 400}, Camera::Data{ .bg_color = Color::WHITE, }); - function on_click = [&]() { cout << "button clicked" << std::endl; }; - function on_enter = [&]() { cout << "enter" << std::endl; }; - function on_exit = [&]() { cout << "exit" << std::endl; }; - - auto & button - = game_object.add_component