diff --git a/examples/snake/src/main.cpp b/examples/snake/src/main.cpp index 4c68b50..494355f 100644 --- a/examples/snake/src/main.cpp +++ b/examples/snake/src/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -41,9 +42,45 @@ private: std::chrono::high_resolution_clock::time_point last_movement; sf::Vector2u window_size; const sf::Vector2f& entity_pos; + + simpleengine::Game& game; public: - explicit SnakeMovementComponent(simpleengine::Entity& owning_entity, float movement_speed, const sf::Vector2u& window_size) - : simpleengine::Component(owning_entity), movement_speed(movement_speed), window_size(window_size), entity_pos(owning_entity.GetTransformable().getPosition()) { + explicit SnakeMovementComponent(simpleengine::Entity& owning_entity, float movement_speed, const sf::Vector2u& window_size, simpleengine::Game& game) + : simpleengine::Component(owning_entity), movement_speed(movement_speed), window_size(window_size), + entity_pos(owning_entity.GetTransformable().getPosition()), game(game) { + + game.AddEventCallback(std::function([this](sf::Event::KeyEvent event) { + this->OnKeyPress(event); + })); + } + + void OnKeyPress(sf::Event::KeyEvent event) { + sf::Keyboard::Key key = event.code; + + switch (key) { + case sf::Keyboard::W: + movement_direction.x = 0; + movement_direction.y = -15; + break; + case sf::Keyboard::A: + movement_direction.x = -15; + movement_direction.y = 0; + break; + case sf::Keyboard::S: + movement_direction.x = 0; + movement_direction.y = 15; + break; + case sf::Keyboard::D: + movement_direction.x = 15; + movement_direction.y = 0; + break; + case sf::Keyboard::Space: + movement_direction.x = 0; + movement_direction.y = 0; + break; + default: + break; + } } const sf::Vector2i& GetDirection() { @@ -51,32 +88,6 @@ public: } void Update(const float& delta_time) override { - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - movement_direction.x = -15; - movement_direction.y = 0; - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - movement_direction.x = 0; - movement_direction.y = -15; - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - movement_direction.x = 15; - movement_direction.y = 0; - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - movement_direction.x = 0; - movement_direction.y = 15; - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) { - movement_direction.x = 0; - movement_direction.y = 0; - } - long long duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - last_movement).count(); // Only move every 115 ticks. @@ -118,7 +129,7 @@ private: public: explicit SnakeFoodEntity(sf::Vector2u window_size, std::shared_ptr snake_player) : Entity(shape), window_size(window_size), snake_player(snake_player) { - //shape = sf::RectangleShape(sf::Vector2f(15, 15)); + shape.setSize(sf::Vector2f(15, 15)); shape.setPosition(45, 45); shape.setFillColor(sf::Color::Red); @@ -173,11 +184,12 @@ private: bool alive = true; public: - explicit SnakePlayerEntity(sf::Vector2u window_size, sf::Text& score_text) : Entity(head), window_size(window_size), score_text(score_text) { + explicit SnakePlayerEntity(sf::Vector2u window_size, sf::Text& score_text, simpleengine::Game& game) : + Entity(head), window_size(window_size), score_text(score_text) { head = sf::RectangleShape(sf::Vector2f(15, 15)); head.setFillColor(sf::Color(220, 220, 220)); - movement_component = std::make_shared(*this, movement_speed, window_size); + movement_component = std::make_shared(*this, movement_speed, window_size, game); AddComponent(movement_component); collision_component = std::make_shared(*this, head, 0, 0, 15, 15); @@ -283,7 +295,7 @@ int main(int argc, char *argv[]) { score_text.setFillColor(sf::Color::Green); score_text.setPosition(window_size.x - 50, 0); - auto snake_player = std::make_shared(window_size, score_text); + auto snake_player = std::make_shared(window_size, score_text, std::ref(game)); auto snake_food = std::make_shared(window_size, snake_player); game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), snake_food)); game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), snake_player)); diff --git a/include/simpleengine/game.h b/include/simpleengine/game.h index b2db1b4..d7f437f 100644 --- a/include/simpleengine/game.h +++ b/include/simpleengine/game.h @@ -11,12 +11,20 @@ #include #include -#include +#include + +#include + #include "entity.h" namespace simpleengine { class Event; + /* template + auto Deduce(F f) -> std::void_t{ + std::function{f}; + } */ + class Game { public: Game(int w, int h, const std::string& window_name); @@ -32,13 +40,107 @@ namespace simpleengine { void AddEvent(Event* event); sf::RenderWindow* GetWindow(); + + template + void AddEventCallback(const std::function<_Fty>& func) { + if constexpr (type == sf::Event::Closed) { + close_event.Add(func); + } else if constexpr (type == sf::Event::Resized) { + resized_event.Add(func); + } else if constexpr (type == sf::Event::LostFocus) { + lost_focus_event.Add(func); + } else if constexpr (type == sf::Event::GainedFocus) { + gained_focus_event.Add(func); + } else if constexpr (type == sf::Event::TextEntered) { + text_entered_event.Add(func); + } else if constexpr (type == sf::Event::KeyPressed) { + key_pressed_event.Add(func); + } else if constexpr (type == sf::Event::KeyReleased) { + key_released_event.Add(func); + } else if constexpr (type == sf::Event::MouseWheelMoved) { + mouse_wheel_moved_event.Add(func); + } else if constexpr (type == sf::Event::MouseWheelScrolled) { + mouse_wheel_scrolled_event.Add(func); + } else if constexpr (type == sf::Event::MouseButtonPressed) { + mouse_button_pressed_event.Add(func); + } else if constexpr (type == sf::Event::MouseButtonReleased) { + mouse_button_released_event.Add(func); + } else if constexpr (type == sf::Event::MouseMoved) { + mouse_move_event.Add(func); + } else if constexpr (type == sf::Event::MouseEntered) { + mouse_entered_event.Add(func); + } else if constexpr (type == sf::Event::MouseLeft) { + mouse_left_event.Add(func); + } else if constexpr (type == sf::Event::JoystickButtonPressed) { + joy_btn_pressed_event.Add(func); + } else if constexpr (type == sf::Event::JoystickButtonReleased) { + joy_btn_released_event.Add(func); + } else if constexpr (type == sf::Event::JoystickMoved) { + joy_moved_event.Add(func); + } else if constexpr (type == sf::Event::JoystickConnected) { + joy_connected_event.Add(func); + } else if constexpr (type == sf::Event::JoystickDisconnected) { + joy_disconnected_event.Add(func); + } else if constexpr (type == sf::Event::TouchBegan) { + touch_began_event.Add(func); + } else if constexpr (type == sf::Event::TouchMoved) { + touch_moved_event.Add(func); + } else if constexpr (type == sf::Event::TouchEnded) { + touch_ended_event.Add(func); + } else if constexpr (type == sf::Event::SensorChanged) { + sensor_event.Add(func); + } else if constexpr (type == sf::Event::Count) { + + } + } private: + template + class EventHolder { + public: + template + void Trigger(Args... args) { + for(const std::function<_Fty>& func : callbacks) { + func(std::forward(args)...); + } + } + + void Add(const std::function<_Fty>& func) { + callbacks.emplace_back(func); + } + private: + std::vector> callbacks; + }; + + // Window event callbacks: + EventHolder close_event; + EventHolder resized_event; + EventHolder lost_focus_event; + EventHolder gained_focus_event; + EventHolder text_entered_event; + EventHolder key_pressed_event; + EventHolder key_released_event; + EventHolder mouse_wheel_moved_event; + EventHolder mouse_wheel_scrolled_event; + EventHolder mouse_button_pressed_event; + EventHolder mouse_button_released_event; + EventHolder mouse_move_event; + EventHolder mouse_entered_event; + EventHolder mouse_left_event; + EventHolder joy_btn_pressed_event; + EventHolder joy_btn_released_event; + EventHolder joy_moved_event; + EventHolder joy_connected_event; + EventHolder joy_disconnected_event; + EventHolder touch_began_event; + EventHolder touch_moved_event; + EventHolder touch_ended_event; + EventHolder sensor_event; + sf::RenderWindow* window; sf::Clock delta_time_clock; // Delta time clock float delta_time; // Delta time - //std::stack events; std::vector events; }; } diff --git a/src/game.cpp b/src/game.cpp index c8be998..43dec75 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -8,7 +8,6 @@ #include "entity.h" #include "event.h" -#include #include simpleengine::Game::Game(int w, int h, const std::string& window_name) { @@ -40,30 +39,75 @@ void simpleengine::Game::UpdateSFMLEvents() { while (window->pollEvent(event)) { switch (event.type) { case sf::Event::Closed: + close_event.Trigger(); window->close(); break; case sf::Event::Resized: + resized_event.Trigger(event.size); + break; case sf::Event::LostFocus: + lost_focus_event.Trigger(); + break; case sf::Event::GainedFocus: + gained_focus_event.Trigger(); + break; case sf::Event::TextEntered: + text_entered_event.Trigger(event.text); + break; case sf::Event::KeyPressed: + key_pressed_event.Trigger(event.key); + break; case sf::Event::KeyReleased: + key_released_event.Trigger(event.key); + break; case sf::Event::MouseWheelMoved: + mouse_wheel_moved_event.Trigger(event.mouseWheel); + break; case sf::Event::MouseWheelScrolled: + mouse_wheel_scrolled_event.Trigger(event.mouseWheelScroll); + break; case sf::Event::MouseButtonPressed: + mouse_button_pressed_event.Trigger(event.mouseButton); + break; case sf::Event::MouseButtonReleased: + mouse_button_released_event.Trigger(event.mouseButton); + break; case sf::Event::MouseMoved: + mouse_move_event.Trigger(event.mouseMove); + break; case sf::Event::MouseEntered: + mouse_entered_event.Trigger(); + break; case sf::Event::MouseLeft: + mouse_left_event.Trigger(); + break; case sf::Event::JoystickButtonPressed: + joy_btn_pressed_event.Trigger(event.joystickButton); + break; case sf::Event::JoystickButtonReleased: + joy_btn_released_event.Trigger(event.joystickButton); + break; case sf::Event::JoystickMoved: + joy_moved_event.Trigger(event.joystickMove); + break; case sf::Event::JoystickConnected: + joy_connected_event.Trigger(event.joystickConnect); + break; case sf::Event::JoystickDisconnected: + joy_disconnected_event.Trigger(event.joystickConnect); + break; case sf::Event::TouchBegan: + touch_began_event.Trigger(event.touch); + break; case sf::Event::TouchMoved: + touch_moved_event.Trigger(event.touch); + break; case sf::Event::TouchEnded: + touch_ended_event.Trigger(event.touch); + break; case sf::Event::SensorChanged: + sensor_event.Trigger(event.sensor); + break; case sf::Event::Count: break; }