diff options
Diffstat (limited to 'src/crepe')
-rw-r--r-- | src/crepe/api/Button.cpp | 6 | ||||
-rw-r--r-- | src/crepe/api/Button.h | 49 | ||||
-rw-r--r-- | src/crepe/api/Event.h | 12 | ||||
-rw-r--r-- | src/crepe/api/LoopManager.h | 19 | ||||
-rw-r--r-- | src/crepe/api/Script.cpp | 2 | ||||
-rw-r--r-- | src/crepe/api/Script.h | 10 | ||||
-rw-r--r-- | src/crepe/api/Sprite.h | 10 | ||||
-rw-r--r-- | src/crepe/api/Text.cpp | 2 | ||||
-rw-r--r-- | src/crepe/api/Text.h | 2 | ||||
-rw-r--r-- | src/crepe/facade/DB.cpp | 12 | ||||
-rw-r--r-- | src/crepe/facade/DB.h | 2 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 74 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 23 | ||||
-rw-r--r-- | src/crepe/manager/SaveManager.cpp | 49 | ||||
-rw-r--r-- | src/crepe/manager/SaveManager.h | 6 | ||||
-rw-r--r-- | src/crepe/system/InputSystem.cpp | 32 | ||||
-rw-r--r-- | src/crepe/system/InputSystem.h | 33 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.cpp | 63 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.h | 30 | ||||
-rw-r--r-- | src/crepe/system/ScriptSystem.cpp | 5 |
20 files changed, 260 insertions, 181 deletions
diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp index 305922c..40153c9 100644 --- a/src/crepe/api/Button.cpp +++ b/src/crepe/api/Button.cpp @@ -2,9 +2,7 @@ namespace crepe { -Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::function<void()> & on_click) - : UIObject(id, dimensions, offset), - on_click(on_click) {} +Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset) + : UIObject(id, dimensions, offset) {} } // namespace crepe diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index 08f5dec..d42527e 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -2,11 +2,23 @@ #include <functional> +#include "Event.h" #include "UIObject.h" namespace crepe { -//! Represents a clickable UI button, derived from the UiObject class. +/** + * \brief Button component. + * + * This component creates a clickable surface at the transform location with the specified width and height. + * + * The Button can be used in scripts by subscribing a EventHandler to the following events: + * - ButtonPressEvent + * - ButtonEnterEvent + * - ButtonExitEvent + * \see EventManager + * + */ class Button : public UIObject { public: /** @@ -15,43 +27,22 @@ public: * \param id The unique ID of the game object associated with this button. * \param dimensions The width and height of the UIObject * \param offset The offset relative this GameObjects Transform - * \param on_click callback function that will be invoked when the button is clicked. */ - Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::function<void()> & on_click); - - // TODO: create separate toggle button class - /** - * \brief The callback function to be executed when the button is clicked. - * - * This function is invoked whenever the button is clicked. It can be set to any - * function that matches the signature `void()`. - */ - std::function<void()> on_click = nullptr; - + Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset); /** - * \brief Callback function to be executed when the mouse enters the button's boundaries. + * \brief Get the maximum number of instances for this component * - * This function is triggered when the mouse cursor moves over the button, allowing - * custom actions like visual effects, highlighting, or sound effects. + * Since the button Event transfers the GameObject Metadata it will be the same for each button so only one button is allowed per GameObject + * + * \return 1 */ - std::function<void()> on_mouse_enter = nullptr; - - /** - * \brief Callback function to be executed when the mouse exits the button's boundaries. - * - * This function is triggered when the mouse cursor moves out of the button's area, - * allowing custom actions like resetting visual effects or playing exit-related effects. - */ - std::function<void()> on_mouse_exit = nullptr; + virtual int get_instances_max() const { return 1; } private: - //! friend relation for is_pressed and hover variables + //! friend relation hover variable friend class InputSystem; //! Indicates whether the mouse is currently hovering over the button bool hover = false; - -public: }; } // namespace crepe diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index 73bf461..8e38280 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -3,9 +3,10 @@ #include <string> -#include "api/KeyCodes.h" #include "types.h" +#include "KeyCodes.h" + namespace crepe { /** @@ -95,15 +96,6 @@ public: }; /** - * \brief Event triggered when text is submitted, e.g., from a text input. - */ -class TextSubmitEvent : public Event { -public: - //! The submitted text. - std::string text = ""; -}; - -/** * \brief Event triggered to indicate the application is shutting down. */ class ShutDownEvent : public Event {}; diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 1d23cbf..124cd3a 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -71,9 +71,19 @@ private: private: //! Global context Mediator mediator; + /** + * \brief Collection of System instances + * + * This map holds System instances indexed by the system's class typeid. It is filled in the + * constructor of LoopManager using LoopManager::load_system. + */ + std::unordered_map<std::type_index, std::unique_ptr<System>> systems; //! SDLContext instance SDLContext sdl_context{mediator}; + //! Resource manager instance + ResourceManager resource_manager{mediator}; + //! Component manager instance ComponentManager component_manager{mediator}; //! Scene manager instance @@ -82,8 +92,6 @@ private: LoopTimerManager loop_timer{mediator}; //! EventManager instance EventManager event_manager{mediator}; - //! Resource manager instance - ResourceManager resource_manager{mediator}; //! Save manager instance SaveManager save_manager{mediator}; @@ -95,13 +103,6 @@ private: */ bool on_shutdown(const ShutDownEvent & e); /** - * \brief Collection of System instances - * - * This map holds System instances indexed by the system's class typeid. It is filled in the - * constructor of LoopManager using LoopManager::load_system. - */ - std::unordered_map<std::type_index, std::unique_ptr<System>> systems; - /** * \brief Initialize a system * \tparam T System type (must be derivative of \c System) */ diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp index 583c04f..7531388 100644 --- a/src/crepe/api/Script.cpp +++ b/src/crepe/api/Script.cpp @@ -26,6 +26,8 @@ void Script::set_next_scene(const string & name) { SaveManager & Script::get_save_manager() const { return this->mediator->save_manager; } +LoopTimerManager & Script::get_loop_timer() const { return this->mediator->loop_timer; } + const keyboard_state_t & Script::get_keyboard_state() const { SDLContext & sdl_context = this->mediator->sdl_context; return sdl_context.get_keyboard_state(); diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 65306cd..a87af4e 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -4,6 +4,7 @@ #include "../api/KeyCodes.h" #include "../manager/EventManager.h" +#include "../manager/LoopTimerManager.h" #include "../manager/Mediator.h" #include "../system/CollisionSystem.h" #include "../types.h" @@ -47,10 +48,12 @@ protected: /** * \brief Script update function (empty by default) * + * \param delta_time Time since last fixed update + * * This function is called during the ScriptSystem::update() routine if the \c BehaviorScript * component holding this script instance is active. */ - virtual void update() {} + virtual void update(duration_t delta_time) {} //! \} //! ScriptSystem calls \c init() and \c update() @@ -135,6 +138,10 @@ protected: //! Retrieve SaveManager reference SaveManager & get_save_manager() const; + + //! Retrieve LoopTimerManager reference + LoopTimerManager & get_loop_timer() const; + /** * \brief Utility function to retrieve the keyboard state * \see SDLContext::get_keyboard_state @@ -151,7 +158,6 @@ protected: * */ bool get_key_state(Keycode key) const noexcept; - //! \} private: /** diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index a2409c2..a3fc319 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -66,6 +66,16 @@ public: //! independent sprite offset position vec2 position_offset; + + /** + * \brief gives the user the option to render this in world space or in camera space + * + * - if true will this be rendered in world space this means that the sprite can be + * rendered off the screen + * - if false --> will the sprite be rendered in camera space. this means that the + * coordinates given on the \c Sprite and \c Transform will be inside the camera + */ + bool world_space = true; }; public: diff --git a/src/crepe/api/Text.cpp b/src/crepe/api/Text.cpp index 54a4370..4a94180 100644 --- a/src/crepe/api/Text.cpp +++ b/src/crepe/api/Text.cpp @@ -1,5 +1,3 @@ -#include "../facade/FontFacade.h" - #include "Text.h" using namespace crepe; diff --git a/src/crepe/api/Text.h b/src/crepe/api/Text.h index c30dc80..da40141 100644 --- a/src/crepe/api/Text.h +++ b/src/crepe/api/Text.h @@ -3,8 +3,6 @@ #include <optional> #include <string> -#include "../Component.h" - #include "Asset.h" #include "Color.h" #include "UIObject.h" diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp index 95cf606..ae2d4bc 100644 --- a/src/crepe/facade/DB.cpp +++ b/src/crepe/facade/DB.cpp @@ -21,12 +21,6 @@ DB::DB(const string & path) { const char * file = path.empty() ? NULL : path.c_str(); ret = this->db->open(this->db.get(), NULL, file, NULL, libdb::DB_BTREE, DB_CREATE, 0); if (ret != 0) throw runtime_error(format("db->open: {}", libdb::db_strerror(ret))); - - // create cursor - libdb::DBC * cursor; - ret = this->db->cursor(this->db.get(), NULL, &cursor, 0); - if (ret != 0) throw runtime_error(format("db->cursor: {}", libdb::db_strerror(ret))); - this->cursor = {cursor, [](libdb::DBC * cursor) { cursor->close(cursor); }}; } libdb::DBT DB::to_thing(const string & thing) const noexcept { @@ -42,10 +36,10 @@ string DB::get(const string & key) { libdb::DBT db_val; memset(&db_val, 0, sizeof(libdb::DBT)); - int ret = this->cursor->get(this->cursor.get(), &db_key, &db_val, DB_FIRST); + int ret = this->db->get(this->db.get(), NULL, &db_key, &db_val, 0); if (ret == 0) return {static_cast<char *>(db_val.data), db_val.size}; - string err = format("cursor->get: {}", libdb::db_strerror(ret)); + string err = format("db->get: {}", libdb::db_strerror(ret)); if (ret == DB_NOTFOUND) throw out_of_range(err); else throw runtime_error(err); } @@ -54,7 +48,7 @@ void DB::set(const string & key, const string & value) { libdb::DBT db_key = this->to_thing(key); libdb::DBT db_val = this->to_thing(value); int ret = this->db->put(this->db.get(), NULL, &db_key, &db_val, 0); - if (ret != 0) throw runtime_error(format("cursor->get: {}", libdb::db_strerror(ret))); + if (ret != 0) throw runtime_error(format("db->get: {}", libdb::db_strerror(ret))); } bool DB::has(const std::string & key) { diff --git a/src/crepe/facade/DB.h b/src/crepe/facade/DB.h index 115c0f1..84cdf19 100644 --- a/src/crepe/facade/DB.h +++ b/src/crepe/facade/DB.h @@ -61,8 +61,6 @@ public: private: //! RAII wrapper around \c DB struct std::unique_ptr<libdb::DB, std::function<void(libdb::DB *)>> db; - //! RAII wrapper around \c DBC struct - std::unique_ptr<libdb::DBC, std::function<void(libdb::DBC *)>> cursor; private: /** diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 4818c96..ca45b79 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -11,7 +11,6 @@ #include <array> #include <cmath> #include <cstddef> -#include <cstdint> #include <functional> #include <memory> #include <stdexcept> @@ -21,7 +20,11 @@ #include "../api/Config.h" #include "../api/Sprite.h" #include "../util/Log.h" +#include "api/Text.h" +#include "api/Transform.h" +#include "facade/Font.h" #include "manager/Mediator.h" +#include "util/AbsolutePosition.h" #include "SDLContext.h" #include "Texture.h" @@ -32,9 +35,6 @@ using namespace std; SDLContext::SDLContext(Mediator & mediator) { dbg_trace(); - if (TTF_Init() == -1) { - throw runtime_error(format("SDL_ttf initialization failed: {}", TTF_GetError())); - } if (SDL_Init(SDL_INIT_VIDEO) != 0) { throw runtime_error(format("SDLContext: SDL_Init error: {}", SDL_GetError())); } @@ -63,6 +63,10 @@ SDLContext::SDLContext(Mediator & mediator) { throw runtime_error("SDLContext: SDL_image could not initialize!"); } + if (TTF_Init() == -1) { + throw runtime_error(format("SDL_ttf initialization failed: {}", TTF_GetError())); + } + mediator.sdl_context = *this; } @@ -75,8 +79,8 @@ SDLContext::~SDLContext() { // TODO: how are we going to ensure that these are called from the same // thread that SDL_Init() was called on? This has caused problems for me // before. - IMG_Quit(); TTF_Quit(); + IMG_Quit(); SDL_Quit(); } @@ -137,6 +141,8 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const { = (ctx.sprite.aspect_ratio == 0) ? ctx.texture.get_ratio() : ctx.sprite.aspect_ratio; vec2 size = data.size; + vec2 screen_pos = ctx.pos + data.position_offset; + if (data.size.x == 0 && data.size.y != 0) { size.x = data.size.y * aspect_ratio; } @@ -145,9 +151,15 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const { } size *= cam_aux_data.render_scale * ctx.img_scale * data.scale_offset; - vec2 screen_pos = (ctx.pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2) - * cam_aux_data.render_scale - - size / 2 + cam_aux_data.bar_size; + if (ctx.sprite.data.world_space) { + screen_pos = (screen_pos - cam_aux_data.cam_pos + cam_aux_data.zoomed_viewport / 2) + * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; + } else { + screen_pos + = (screen_pos + cam_aux_data.zoomed_viewport / 2) * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; + } return SDL_FRect{ .x = screen_pos.x, @@ -187,6 +199,52 @@ void SDLContext::draw(const RenderContext & ctx) { angle, NULL, render_flip); } +void SDLContext::draw_text(const RenderText & data) { + + const Text & text = data.text; + const Font & font = data.font; + vec2 absoluut_pos = AbsolutePosition::get_position(data.transform, data.text.offset); + std::unique_ptr<SDL_Surface, std::function<void(SDL_Surface *)>> font_surface; + std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>> font_texture; + + 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 * tmp_font_surface + = TTF_RenderText_Solid(font.get_font(), text.text.c_str(), color); + if (tmp_font_surface == NULL) { + throw runtime_error(format("draw_text: font surface error: {}", SDL_GetError())); + } + font_surface = {tmp_font_surface, [](SDL_Surface * surface) { SDL_FreeSurface(surface); }}; + + SDL_Texture * tmp_font_texture + = SDL_CreateTextureFromSurface(this->game_renderer.get(), font_surface.get()); + if (tmp_font_texture == NULL) { + throw runtime_error(format("draw_text: font texture error: {}", SDL_GetError())); + } + font_texture + = {tmp_font_texture, [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }}; + + vec2 size = text.dimensions * cam_aux_data.render_scale * data.transform.scale; + vec2 screen_pos = (absoluut_pos - cam_aux_data.cam_pos + + (cam_aux_data.zoomed_viewport) / 2) + * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; + + SDL_FRect dstrect{ + .x = screen_pos.x, + .y = screen_pos.y, + .w = size.x, + .h = size.y, + }; + + SDL_RenderCopyExF(this->game_renderer.get(), font_texture.get(), NULL, &dstrect, + data.transform.rotation, NULL, SDL_FLIP_NONE); +} + 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 b687f87..e570073 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -12,18 +12,21 @@ #include <unordered_map> #include "../types.h" +#include "EventData.h" #include "api/Camera.h" #include "api/Color.h" #include "api/KeyCodes.h" #include "api/Sprite.h" #include "api/Transform.h" -#include "types.h" #include "EventData.h" #include "FontFacade.h" +#include "types.h" namespace crepe { class Texture; +class Text; +class Font; class Mediator; /** @@ -71,12 +74,11 @@ public: const double & scale; }; -public: - /** - * \brief Gets the singleton instance of SDLContext. - * \return Reference to the SDLContext instance. - */ - static SDLContext & get_instance(); + struct RenderText { + const Text & text; + const Font & font; + const Transform & transform; + }; public: SDLContext(const SDLContext &) = delete; @@ -186,6 +188,13 @@ public: */ void draw(const RenderContext & ctx); + /** + * \brief draws a text to the screen + * + * \param data Reference to the rendering data needed to draw + */ + void draw_text(const RenderText & data); + //! Clears the screen, preparing for a new frame. void clear_screen(); diff --git a/src/crepe/manager/SaveManager.cpp b/src/crepe/manager/SaveManager.cpp index 691ea2f..f313ed2 100644 --- a/src/crepe/manager/SaveManager.cpp +++ b/src/crepe/manager/SaveManager.cpp @@ -129,9 +129,32 @@ template void SaveManager::set(const string &, const float &); template void SaveManager::set(const string &, const double &); template <typename T> +T SaveManager::get(const string & key) { + return this->deserialize<T>(this->get_db().get(key)); +} +template uint8_t SaveManager::get(const string &); +template int8_t SaveManager::get(const string &); +template uint16_t SaveManager::get(const string &); +template int16_t SaveManager::get(const string &); +template uint32_t SaveManager::get(const string &); +template int32_t SaveManager::get(const string &); +template uint64_t SaveManager::get(const string &); +template int64_t SaveManager::get(const string &); +template float SaveManager::get(const string &); +template double SaveManager::get(const string &); +template string SaveManager::get(const string &); + +template <typename T> ValueBroker<T> SaveManager::get(const string & key, const T & default_value) { if (!this->has(key)) this->set<T>(key, default_value); - return this->get<T>(key); + T value; + return { + [this, key](const T & target) { this->set<T>(key, target); }, + [this, key, value]() mutable -> const T & { + value = this->get<T>(key); + return value; + }, + }; } template ValueBroker<uint8_t> SaveManager::get(const string &, const uint8_t &); template ValueBroker<int8_t> SaveManager::get(const string &, const int8_t &); @@ -144,27 +167,3 @@ template ValueBroker<int64_t> SaveManager::get(const string &, const int64_t &); template ValueBroker<float> SaveManager::get(const string &, const float &); template ValueBroker<double> SaveManager::get(const string &, const double &); template ValueBroker<string> SaveManager::get(const string &, const string &); - -template <typename T> -ValueBroker<T> SaveManager::get(const string & key) { - T value; - return { - [this, key](const T & target) { this->set<T>(key, target); }, - [this, key, value]() mutable -> const T & { - DB & db = this->get_db(); - value = this->deserialize<T>(db.get(key)); - return value; - }, - }; -} -template ValueBroker<uint8_t> SaveManager::get(const string &); -template ValueBroker<int8_t> SaveManager::get(const string &); -template ValueBroker<uint16_t> SaveManager::get(const string &); -template ValueBroker<int16_t> SaveManager::get(const string &); -template ValueBroker<uint32_t> SaveManager::get(const string &); -template ValueBroker<int32_t> SaveManager::get(const string &); -template ValueBroker<uint64_t> SaveManager::get(const string &); -template ValueBroker<int64_t> SaveManager::get(const string &); -template ValueBroker<float> SaveManager::get(const string &); -template ValueBroker<double> SaveManager::get(const string &); -template ValueBroker<string> SaveManager::get(const string &); diff --git a/src/crepe/manager/SaveManager.h b/src/crepe/manager/SaveManager.h index 61a978d..1e34bc0 100644 --- a/src/crepe/manager/SaveManager.h +++ b/src/crepe/manager/SaveManager.h @@ -36,17 +36,17 @@ public: ValueBroker<T> get(const std::string & key, const T & default_value); /** - * \brief Get a read/write reference to a value + * \brief Get a value directly * * \param key The value key * - * \return Read/write reference to the value + * \return The value * * \note Attempting to read this value before it is initialized (i.e. set) will result in an * exception */ template <typename T> - ValueBroker<T> get(const std::string & key); + T get(const std::string & key); /** * \brief Set a value directly diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index fca540f..60daa55 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -10,10 +10,8 @@ using namespace crepe; void InputSystem::update() { ComponentManager & mgr = this->mediator.component_manager; - SDLContext & context = this->mediator.sdl_context; std::vector<EventData> event_list = context.get_events(); - RefVector<Button> buttons = mgr.get_components_by_type<Button>(); RefVector<Camera> cameras = mgr.get_components_by_type<Camera>(); OptionalRef<Camera> curr_cam_ref; @@ -155,28 +153,25 @@ void InputSystem::handle_non_mouse_event(const EventData & event) { void InputSystem::handle_move(const EventData & event_data, const vec2 & mouse_pos) { ComponentManager & mgr = this->mediator.component_manager; - + EventManager & event_mgr = this->mediator.event_manager; RefVector<Button> buttons = mgr.get_components_by_type<Button>(); for (Button & button : buttons) { if (!button.active) continue; - RefVector<Transform> transform_vec - = mgr.get_components_by_id<Transform>(button.game_object_id); - Transform & transform(transform_vec.front().get()); - + Metadata & metadata + = mgr.get_components_by_id<Metadata>(button.game_object_id).front(); + Transform & transform + = mgr.get_components_by_id<Transform>(button.game_object_id).front(); bool was_hovering = button.hover; if (this->is_mouse_inside_button(mouse_pos, button, transform)) { button.hover = true; - if (!button.on_mouse_enter) continue; if (!was_hovering) { - button.on_mouse_enter(); + event_mgr.trigger_event<ButtonEnterEvent>(metadata); } } else { button.hover = false; - // Trigger the on_exit callback if the hover state just changed to false - if (!button.on_mouse_exit) continue; if (was_hovering) { - button.on_mouse_exit(); + event_mgr.trigger_event<ButtonExitEvent>(metadata); } } } @@ -184,19 +179,18 @@ void InputSystem::handle_move(const EventData & event_data, const vec2 & mouse_p void InputSystem::handle_click(const MouseButton & mouse_button, const vec2 & mouse_pos) { ComponentManager & mgr = this->mediator.component_manager; - + EventManager & event_mgr = this->mediator.event_manager; RefVector<Button> buttons = mgr.get_components_by_type<Button>(); for (Button & button : buttons) { if (!button.active) continue; - if (!button.on_click) continue; - RefVector<Transform> transform_vec - = mgr.get_components_by_id<Transform>(button.game_object_id); - Transform & transform = transform_vec.front().get(); + Metadata & metadata + = mgr.get_components_by_id<Metadata>(button.game_object_id).front(); + Transform & transform + = mgr.get_components_by_id<Transform>(button.game_object_id).front(); if (this->is_mouse_inside_button(mouse_pos, button, transform)) { - - button.on_click(); + event_mgr.trigger_event<ButtonPressEvent>(metadata); } } } diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index eefd9fe..e580d8e 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -3,6 +3,8 @@ #include "../api/Config.h" #include "../facade/EventData.h" +#include "../api/Event.h" +#include "../api/Metadata.h" #include "../types.h" #include "../util/OptionalRef.h" @@ -13,6 +15,37 @@ namespace crepe { class Camera; class Button; class Transform; +//! Event triggered when a button is clicked +class ButtonPressEvent : public Event { +public: + //! Metadata of the button. + const Metadata & metadata; + /** + * \param metadata Metadata of the button pressed + */ + ButtonPressEvent(const Metadata & metadata) : metadata(metadata){}; +}; +//! Event triggered when the mouse enters a button +class ButtonEnterEvent : public Event { +public: + //! Metadata of the button. + const Metadata & metadata; + /** + * \param metadata Metadata of the button pressed + */ + ButtonEnterEvent(const Metadata & metadata) : metadata(metadata){}; +}; +//! Event triggered when the mouse leaves a button +class ButtonExitEvent : public Event { +public: + //! Metadata of the button. + const Metadata & metadata; + /** + * \param metadata Metadata of the button pressed + */ + ButtonExitEvent(const Metadata & metadata) : metadata(metadata){}; +}; + /** * \brief Handles the processing of input events created by SDLContext * diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index d76a122..9d8e683 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -17,6 +17,8 @@ #include "../manager/ComponentManager.h" #include "../manager/ResourceManager.h" #include "util/AbsolutePosition.h" +#include "api/Text.h" +#include "facade/Font.h" #include "RenderSystem.h" #include "types.h" @@ -71,11 +73,34 @@ RefVector<Sprite> RenderSystem::sort(RefVector<Sprite> & objs) const { void RenderSystem::update() { this->clear_screen(); this->render(); + this->render_text(); this->present_screen(); } -bool RenderSystem::render_particle(const Sprite & sprite, const double & scale) { +void RenderSystem::render_text() { + SDLContext & ctx = this->mediator.sdl_context; + ComponentManager & mgr = this->mediator.component_manager; + ResourceManager & resource_manager = this->mediator.resource_manager; + RefVector<Text> texts = mgr.get_components_by_type<Text>(); + + for (Text & text : texts) { + if (!text.active) continue; + if (!text.font.has_value()) + text.font.emplace(ctx.get_font_from_name(text.font_family)); + + const Font & font = resource_manager.get<Font>(text.font.value()); + const auto & transform + = mgr.get_components_by_id<Transform>(text.game_object_id).front().get(); + ctx.draw_text(SDLContext::RenderText{ + .text = text, + .font = font, + .transform = transform, + }); + } +} + +bool RenderSystem::render_particle(const Sprite & sprite, const Transform & transform) { ComponentManager & mgr = this->mediator.component_manager; SDLContext & ctx = this->mediator.sdl_context; ResourceManager & resource_manager = this->mediator.resource_manager; @@ -93,29 +118,30 @@ bool RenderSystem::render_particle(const Sprite & sprite, const double & scale) for (const Particle & p : em.particles) { if (!p.active) continue; + if (p.time_in_life < em.data.begin_lifespan) continue; ctx.draw(SDLContext::RenderContext{ .sprite = sprite, .texture = res, .pos = p.position, - .angle = p.angle, - .scale = scale, + .angle = p.angle + transform.rotation, + .scale = transform.scale, }); } } return rendering_particles; } -void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { +void RenderSystem::render_normal(const Sprite & sprite, const Transform & transform) { SDLContext & ctx = this->mediator.sdl_context; ResourceManager & resource_manager = this->mediator.resource_manager; const Texture & res = resource_manager.get<Texture>(sprite.source); - vec2 pos = AbsolutePosition::get_position(tm, sprite.data.position_offset); + vec2 pos = AbsolutePosition::get_position(transform, sprite.data.position_offset); ctx.draw(SDLContext::RenderContext{ .sprite = sprite, .texture = res, .pos = pos, - .angle = tm.rotation, - .scale = tm.scale, + .angle = transform.rotation, + .scale = transform.scale, }); } @@ -127,35 +153,16 @@ void RenderSystem::render() { ResourceManager & resource_manager = this->mediator.resource_manager; RefVector<Sprite> sorted_sprites = this->sort(sprites); RefVector<Text> text_components = mgr.get_components_by_type<Text>(); - for (Text & text : text_components) { - const Transform & transform - = mgr.get_components_by_id<Transform>(text.game_object_id).front().get(); - this->render_text(text, transform); - } + for (const Sprite & sprite : sorted_sprites) { if (!sprite.active) continue; const Transform & transform = mgr.get_components_by_id<Transform>(sprite.game_object_id).front().get(); - bool rendered_particles = this->render_particle(sprite, transform.scale); + bool rendered_particles = this->render_particle(sprite, transform); if (rendered_particles) continue; this->render_normal(sprite, transform); } } -void RenderSystem::render_text(Text & text, const Transform & tm) { - SDLContext & ctx = this->mediator.sdl_context; - - if (!text.font.has_value()) { - text.font.emplace(ctx.get_font_from_name(text.font_family)); - } - - ResourceManager & resource_manager = this->mediator.resource_manager; - - if (!text.font.has_value()) { - return; - } - const Asset & font_asset = text.font.value(); - const Font & res = resource_manager.get<Font>(font_asset); -} diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 56a0553..14e5c2d 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -36,34 +36,28 @@ private: //! Updates the active camera used for rendering. void update_camera(); - //! Renders the whole screen + //! Renders all the sprites and particles void render(); + //! Renders all Text components + void render_text(); + +private: /** * \brief Renders all the particles on the screen from a given sprite. * * \param sprite renders the particles with given texture - * \param tm the Transform component for scale. This is not a const reference because each - * particle has a position and rotation that needs to overwrite the transform position and - * rotation without overwriting the current transform. and because the transform - * constructor is now protected i cannot make tmp inside + * \param transform the component that holds the position, rotation, and scale. * \return true if particles have been rendered */ - bool render_particle(const Sprite & sprite, const double & scale); - /** - * \brief Renders all Text components - * - * \param text The text component to be rendered. - * \param tm the Transform component that holds the position,rotation and scale - */ - void render_text(Text & text, const Transform & tm); + bool render_particle(const Sprite & sprite, const Transform & transform); /** * \brief renders a sprite with a Transform component on the screen * * \param sprite the sprite component that holds all the data - * \param tm the Transform component that holds the position,rotation and scale + * \param transform the Transform component that holds the position,rotation and scale */ - void render_normal(const Sprite & sprite, const Transform & tm); + void render_normal(const Sprite & sprite, const Transform & transform); /** * \brief sort a vector sprite objects with @@ -72,12 +66,6 @@ private: * \return returns a sorted reference vector */ RefVector<Sprite> sort(RefVector<Sprite> & objs) const; - - /** - * \todo Add text rendering using SDL_ttf for text components. - * \todo Implement a text component and a button component. - * \todo Consider adding text input functionality. - */ }; } // namespace crepe diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index d6b2ca1..0605c7a 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -11,6 +11,7 @@ void ScriptSystem::update() { dbg_trace(); ComponentManager & mgr = this->mediator.component_manager; + LoopTimerManager & timer = this->mediator.loop_timer; RefVector<BehaviorScript> behavior_scripts = mgr.get_components_by_type<BehaviorScript>(); for (BehaviorScript & behavior_script : behavior_scripts) { @@ -23,6 +24,8 @@ void ScriptSystem::update() { script->init(); script->initialized = true; } - script->update(); + + duration_t delta_time = timer.get_scaled_fixed_delta_time(); + script->update(delta_time); } } |