diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 45ce3e1..a741a75 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,2 +1,2 @@ # Add examples as a subdirectory -add_subdirectory(first) \ No newline at end of file +add_subdirectory(snake) \ No newline at end of file diff --git a/examples/first/CMakeLists.txt b/examples/first/CMakeLists.txt deleted file mode 100644 index 6c2cb0f..0000000 --- a/examples/first/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required (VERSION 3.6) -project(first_example) - -add_executable(first_example src/main.cpp) - -# Link headers and source files. -file(GLOB_RECURSE source_list src/*.cpp) -target_sources(first_example PRIVATE ${source_list}) -target_include_directories(first_example PUBLIC include) - -# Link simpleengine -target_link_libraries(first_example PUBLIC simpleengine) - -# Set standard to C++17 -set_target_properties(first_example PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF) \ No newline at end of file diff --git a/examples/first/src/main.cpp b/examples/first/src/main.cpp deleted file mode 100644 index efe1374..0000000 --- a/examples/first/src/main.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// Created by SeanOMik on 7/2/2020. -// Github: https://github.com/SeanOMik -// Email: seanomik@gmail.com -// - -#include - -#include -#include -#include - -class PlayerEntity : public simpleengine::Entity { -private: - sf::RectangleShape shape; - float movement_speed; -public: - PlayerEntity() { - shape = sf::RectangleShape(sf::Vector2f(50, 50)); - shape.setFillColor(sf::Color::White); - - movement_speed = 250; - } - - void Move(const float& delta_time, const float& x, const float& y) override { - shape.move(x * movement_speed * delta_time, y * movement_speed * delta_time); - } - - void Update(const float& delta_time) override { - if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - Move(delta_time, -1, 0); - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - Move(delta_time, 0, -1); - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - Move(delta_time, 1, 0); - } - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - Move(delta_time, 0, 1); - } - } - - void Render(sf::RenderTarget* target = nullptr) override { - target->draw(shape); - } -}; - -class PlayerEvent : public simpleengine::Event { -private: - PlayerEntity entity; -public: - explicit PlayerEvent(sf::RenderWindow* window = nullptr) : simpleengine::Event(window) {} - - void CheckForQuit() override { - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { - quit = true; - } - } - - void Update(const float& delta_time) override { - entity.Update(delta_time); - } - - void Render(sf::RenderTarget* target = nullptr) override { - entity.Render(target); - } -}; - -int main(int argc, char *argv[]) { - simpleengine::Game game(500, 500, "First Example"); - game.AddEvent(new PlayerEvent()); - - return game.Run(); -} \ No newline at end of file diff --git a/examples/snake/CMakeLists.txt b/examples/snake/CMakeLists.txt new file mode 100644 index 0000000..2523cc7 --- /dev/null +++ b/examples/snake/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required (VERSION 3.6) +project(Snake) + +add_executable(snake src/main.cpp) + +# Link headers and source files. +file(GLOB_RECURSE source_list src/*.cpp) +target_sources(snake PRIVATE ${source_list}) +target_include_directories(snake PUBLIC include) + +# Link simpleengine +target_link_libraries(snake PUBLIC simpleengine) + +# Set standard to C++17 +set_target_properties(snake PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF) \ No newline at end of file diff --git a/examples/snake/src/main.cpp b/examples/snake/src/main.cpp new file mode 100644 index 0000000..d87ff76 --- /dev/null +++ b/examples/snake/src/main.cpp @@ -0,0 +1,113 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include + +#include +#include +#include +#include +#include + +class SnakeMovementComponent : public simpleengine::Component { +public: + explicit SnakeMovementComponent(simpleengine::Entity* owning_entity, float movement_speed) : simpleengine::Component(owning_entity), movement_speed(movement_speed) { + + } + + void Update(const float &delta_time) override { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { + movement_direction.x = -1; + movement_direction.y = 0; + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { + movement_direction.x = 0; + movement_direction.y = -1; + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { + movement_direction.x = 1; + movement_direction.y = 0; + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { + movement_direction.x = 0; + movement_direction.y = 1; + } + + owning_entity->Move(delta_time, movement_direction.x, movement_direction.y); + } +private: + float movement_speed; + sf::Vector2f movement_direction; +}; + +class SnakePlayerEntity : public simpleengine::Entity { +private: + sf::RectangleShape shape; + float movement_speed = 100; + sf::Vector2u window_size; + sf::Vector2f loc; +public: + explicit SnakePlayerEntity(sf::Vector2u window_size) : window_size(window_size) { + shape = sf::RectangleShape(sf::Vector2f(15, 15)); + shape.setFillColor(sf::Color::White); + + this->AddComponent(new SnakeMovementComponent(this, movement_speed)); + loc = sf::Vector2f(0, 0); + } + + void Move(const float& delta_time, const float& x, const float& y) override { + shape.move(x * movement_speed * delta_time, y * movement_speed * delta_time); + } + + void Update(const float& delta_time) override { + UpdateComponents(delta_time); + + if (loc.x >= window_size.x) { + DestroyEntity(); + } + + if (loc.y >= window_size.y) { + DestroyEntity(); + } + } + + void Render(sf::RenderTarget* target = nullptr) override { + target->draw(shape); + } +}; + +/*class PlayerEvent : public simpleengine::Event { +private: + SnakePlayerEntity snake_player; +public: + explicit PlayerEvent(sf::RenderWindow* window) : simpleengine::Event(window), + snake_player(SnakePlayerEntity(window->getSize())) { + } + + void CheckForQuit() override { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { + quit = true; + } + } + + void Update(const float& delta_time) override { + snake_player.Update(delta_time); + } + + void Render(sf::RenderTarget* target = nullptr) override { + snake_player.Render(target); + } +};*/ + +int main(int argc, char *argv[]) { + simpleengine::Game game(500, 500, "First Example"); + game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), new SnakePlayerEntity(game.GetWindow()->getSize()))); + + return game.Run(); +} \ No newline at end of file diff --git a/include/simpleengine/component.h b/include/simpleengine/component.h new file mode 100644 index 0000000..a82853e --- /dev/null +++ b/include/simpleengine/component.h @@ -0,0 +1,26 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#ifndef SIMPLEENGINE_COMPONENT_H +#define SIMPLEENGINE_COMPONENT_H + +#include + +namespace simpleengine { + class Entity; + class Component { + public: + explicit Component(Entity* owning_entity = nullptr) : owning_entity(owning_entity) {} + virtual ~Component() = default; + + virtual void Update(const float& delta_time) = 0; + virtual void Render(sf::RenderTarget* target = nullptr) {}; // Most components won't need to be rendered. + protected: + Entity* owning_entity; + }; +} + +#endif //SIMPLEENGINE_COMPONENT_H diff --git a/include/simpleengine/components/movement/movement_component.h b/include/simpleengine/components/movement/movement_component.h new file mode 100644 index 0000000..2cb4c04 --- /dev/null +++ b/include/simpleengine/components/movement/movement_component.h @@ -0,0 +1,27 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#ifndef SIMPLEENGINE_MOVEMENT_COMPONENT_H +#define SIMPLEENGINE_MOVEMENT_COMPONENT_H + +#include "../../component.h" + +#include + +namespace simpleengine { + class Entity; + + class MovementComponent : public Component { + public: + explicit MovementComponent(Entity* owning_entity, float movement_speed); + + void Update(const float &delta_time) override; + private: + float movement_speed; + }; +} + +#endif //SIMPLEENGINE_MOVEMENT_COMPONENT_H diff --git a/include/simpleengine/entity.h b/include/simpleengine/entity.h index 75999f6..120ea06 100644 --- a/include/simpleengine/entity.h +++ b/include/simpleengine/entity.h @@ -9,8 +9,15 @@ #include +#include + namespace simpleengine { + class Component; + class Game; + class Event; class Entity { + friend class Game; + friend class Event; public: Entity() = default; virtual ~Entity() = default; @@ -18,6 +25,28 @@ namespace simpleengine { virtual void Move(const float& delta_time, const float& x, const float& y) {}; virtual void Update(const float& delta_time) = 0; virtual void Render(sf::RenderTarget* target = nullptr) = 0; + virtual void Destroying() {}; // Called when the entity is about to be destroyed. + + void DestroyEntity() { + destroying = true; + } + + const bool& IsGettingDestroyed() const { + return destroying; + } + + // If your event does not extend from EntityEvent, you will need to execute this yourself inside Event::Update. + void UpdateComponents(const float& delta_time); + + void AddComponent(Component* component); + private: + // This is ran from class `Game` and `Event`. It runs the `UpdateComponents` method and then the `Update` method. + void UpdateEntity(const float& delta_time) { + UpdateComponents(delta_time); + } + + std::vector components; + bool destroying = false; }; } diff --git a/include/simpleengine/events/entity_event.h b/include/simpleengine/events/entity_event.h new file mode 100644 index 0000000..b082438 --- /dev/null +++ b/include/simpleengine/events/entity_event.h @@ -0,0 +1,42 @@ +// +// Created by SeanOMik on 7/3/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#ifndef SIMPLEENGINE_ENTITY_EVENT_H +#define SIMPLEENGINE_ENTITY_EVENT_H + +#include "../event.h" +#include "../entity.h" + +namespace simpleengine { + class EntityEvent : public Event { + public: + explicit EntityEvent(sf::RenderWindow* window, Entity* entity) : simpleengine::Event(window), entity(entity) { + + } + + ~EntityEvent() override { + delete entity; + } + + void CheckForQuit() override { + /*if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { + quit = true; + }*/ + } + + void Update(const float& delta_time) override { + entity->Update(delta_time); + } + + void Render(sf::RenderTarget* target = nullptr) override { + entity->Render(target); + } + private: + Entity* entity; + }; +} + +#endif //SIMPLEENGINE_ENTITY_EVENT_H diff --git a/src/components/movement/movement_component.cpp b/src/components/movement/movement_component.cpp new file mode 100644 index 0000000..b1f7eb8 --- /dev/null +++ b/src/components/movement/movement_component.cpp @@ -0,0 +1,31 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include "components/movement/movement_component.h" +#include "entity.h" + +simpleengine::MovementComponent::MovementComponent(simpleengine::Entity *owning_entity, float movement_speed) : + Component(owning_entity), movement_speed(movement_speed) { + +} + +void simpleengine::MovementComponent::Update(const float &delta_time) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { + owning_entity->Move(delta_time, -1, 0); + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { + owning_entity->Move(delta_time, 0, -1); + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { + owning_entity->Move(delta_time, 1, 0); + } + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { + owning_entity->Move(delta_time, 0, 1); + } +} diff --git a/src/entity.cpp b/src/entity.cpp new file mode 100644 index 0000000..5fcba48 --- /dev/null +++ b/src/entity.cpp @@ -0,0 +1,18 @@ +// +// Created by SeanOMik on 7/3/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include "entity.h" +#include "component.h" + +void simpleengine::Entity::UpdateComponents(const float& delta_time) { + for (Component* component : components) { + component->Update(delta_time); + } +} + +void simpleengine::Entity::AddComponent(simpleengine::Component *component) { + components.emplace_back(component); +}