diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ad8b0b6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.14) +project(project_maat) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) + +add_subdirectory(src) +add_subdirectory(tests) + +# Detect and add SFML +find_package(SFML COMPONENTS system window graphics network audio REQUIRED) +if(NOT SFML_FOUND) + message(FATAL_ERROR "SFML could not be found") +endif() + +# Detect and add GTest +find_package(GTest REQUIRED) +if(GTest_FOUND) + enable_testing() +else() + message(FATAL_ERROR "GTest could not be found") +endif() + +# Find PugiXML +find_path(PugiXML_INCLUDE_DIR pugixml.hpp) +if(NOT IS_DIRECTORY ${PugiXML_INCLUDE_DIR}) + message(FATAL_ERROR "PugiXML could not be found") +endif() \ No newline at end of file diff --git a/README.md b/README.md index 4a5b38f..576b9e4 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,18 @@ Project Maat is the codename of my C++ course "mini-project" based on the quote This game is aimed to be a puzzle game in which the player sets different laws for the world and the people within it as to control what happens after hitting "play" and achieve the level's goal. I was inspired both by [The Incredible Machine](https://en.wikipedia.org/wiki/The_Incredible_Machine_(video_game)) and its successors and by a much more recent game : [Baba is you](https://en.wikipedia.org/wiki/Baba_Is_You). +## Structure + +![UML Diagram](UML_Class_Diagram.png) + ## TODO - [ ] Level - - [ ] Structure + - [x] Structure - [ ] Parsing from XML - [ ] A* - [ ] Entities - - [ ] Strucutre + - [x] Structure - [ ] Parsing from XML - [ ] Moving - [ ] Decorators (Rules) diff --git a/UML_Class_Diagram.png b/UML_Class_Diagram.png new file mode 100644 index 0000000..5f40a3d Binary files /dev/null and b/UML_Class_Diagram.png differ diff --git a/resources/test_level.xml b/resources/test_level.xml new file mode 100644 index 0000000..7b4af30 --- /dev/null +++ b/resources/test_level.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..df21f86 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.14) +project(project_maat) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) + +add_library(engine Level.cpp Level.h Entity.cpp Entity.h Game.cpp Game.h Utils.h Utils.h) + +target_link_libraries(engine + sfml-window + sfml-graphics + sfml-system) \ No newline at end of file diff --git a/src/Entity.cpp b/src/Entity.cpp new file mode 100644 index 0000000..fd4cfca --- /dev/null +++ b/src/Entity.cpp @@ -0,0 +1,41 @@ +// +// Created by trotfunky on 06/06/19. +// + +#include "Entity.h" + +const std::map Entity::entityTypeLookup = { + {"Citizen",EntityType::Citizen}, + {"Player",EntityType::Player}, + {"House",EntityType::House}, + {"Car",EntityType::Car}}; + +Entity::Entity(int x, int y, EntityType type, int width, int height) +{ + +} + +Entity::Entity(const pugi::xml_node& entityNode) +{ + +} + +void Entity::render(sf::RenderWindow& renderWindow) const +{ + +} + +void Entity::move() +{ + +} + +void Entity::update() +{ + +} + +const sf::RectangleShape& Entity::getShape() const +{ + return(shape); +} diff --git a/src/Entity.h b/src/Entity.h new file mode 100644 index 0000000..be52d46 --- /dev/null +++ b/src/Entity.h @@ -0,0 +1,69 @@ +// +// Created by trotfunky on 06/06/19. +// + +#ifndef SRC_ENTITY_H +#define SRC_ENTITY_H + +#include +#include + +#include "Utils.h" + + +enum class EntityType +{ + Citizen, + Player, + House, + Car, +}; + +enum class State +{ + Moving, + Fleeing, + Waiting, + Idle, +}; + +enum class Orientation +{ + Nort, + East, + South, + West, +}; + + +class Entity +{ +public: + /// x,y, width and height are in grid coordinates + Entity(int x, int y, EntityType type, int width = 1, int height = 1); + Entity(const pugi::xml_node& entityNode); + + void render(sf::RenderWindow& renderWindow) const; + void move(); + void update(); + + const sf::RectangleShape& getShape() const; + + /// Position of the target of the current action on the map + sf::Vector2i target; +private: + static const std::map entityTypeLookup; + + // As it contains position, size and orientation, we do not need anything more + sf::RectangleShape shape; + + State currentState; + /// Used with rules : last to update has priority + State nextState; + + /// Used with rules : last to update has priority + sf::Vector2i nextTarget; +}; + + +#endif //SRC_ENTITY_H diff --git a/src/Game.cpp b/src/Game.cpp new file mode 100644 index 0000000..6983d39 --- /dev/null +++ b/src/Game.cpp @@ -0,0 +1,44 @@ +#include + +// +// Created by trotfunky on 06/06/19. +// + +#include "Game.h" + + +Game::Game(const std::vector& levels, const std::vector& textures) +{ + + + loadTextures(); +} + +void Game::loadLevel(int levelId) +{ + pugi::xml_document document; + pugi::xml_parse_result result = document.load_file(levelFiles.at(levelId).c_str()); + + if(!result) + { + std::cerr << "Error while loading level :\n" << "\t" << result.description() << std::endl; + exit(-1); + } + + currentLevel = std::make_unique(document,textures); +} + +void Game::loadTextures() +{ + textures.reserve(textureFiles.size()); + for(const std::string& filePath : textureFiles) + { + textures.emplace_back(std::make_unique()); + textures.back()->loadFromFile(filePath); + } +} + +void Game::runGame() +{ + +} diff --git a/src/Game.h b/src/Game.h new file mode 100644 index 0000000..da9f7b2 --- /dev/null +++ b/src/Game.h @@ -0,0 +1,44 @@ +// +// Created by trotfunky on 06/06/19. +// + +#ifndef SRC_GAME_H +#define SRC_GAME_H + +#include +#include +#include + +#include "Level.h" +#include "Entity.h" + + +// Used for convenience +using TextureStore = std::vector>; + +class Game { +public: + Game(const std::vector& levels, const std::vector& textures); + + /// Loads the level of corresponding ID from Game::levelFiles + /// Closes the program if there is a fatal error (Missing file, bad file...) + void loadLevel(int levelId); + + std::unique_ptr currentLevel; + + // This should not be called before a level has been loaded + void runGame(); + +private: + /// Store the paths to level files + const std::vector levelFiles; + /// Store the paths to texture files + const std::vector textureFiles; + /// Stores pointers to textures for future use + TextureStore textures; + + void loadTextures(); +}; + + +#endif //SRC_GAME_H diff --git a/src/Level.cpp b/src/Level.cpp new file mode 100644 index 0000000..1c0903b --- /dev/null +++ b/src/Level.cpp @@ -0,0 +1,30 @@ +// +// Created by trotfunky on 06/06/19. +// + +#include "Level.h" + + +Level::Level(const pugi::xml_document& xmlDoc, const TextureStore& textureStore) + : textures(textureStore), + size(xmlDoc.child("Level").attribute("width").as_int(),xmlDoc.child("Level").attribute("width").as_int()) +{ + pugi::xml_node levelNode = xmlDoc.child("Level"); + for(const pugi::xml_node& child : levelNode.children()) + { + if(!strncmp(child.name(),"Entity",6)) + { + entities.emplace_back(child); + } + } +} + +void Level::render(sf::RenderWindow& renderWindow) const +{ + +} + +void Level::runStep() const +{ + +} diff --git a/src/Level.h b/src/Level.h new file mode 100644 index 0000000..63379f9 --- /dev/null +++ b/src/Level.h @@ -0,0 +1,34 @@ +// +// Created by trotfunky on 06/06/19. +// + +#ifndef SRC_LEVEL_H +#define SRC_LEVEL_H + +#include +#include +#include +#include + +#include "Utils.h" +#include "Entity.h" + +using TextureStore = std::vector>; + +class Level { +public: + Level(const pugi::xml_document& xmlDoc, const TextureStore& textureStore); + + void render(sf::RenderWindow& renderWindow) const; + void runStep() const; + +private: + const sf::Vector2i size; + + std::vector entities; + + const TextureStore& textures; +}; + + +#endif //SRC_LEVEL_H diff --git a/src/Utils.h b/src/Utils.h new file mode 100644 index 0000000..8fa40a5 --- /dev/null +++ b/src/Utils.h @@ -0,0 +1,18 @@ +// +// Created by trotfunky on 07/06/19. +// + +#ifndef PROJECT_MAAT_UTILS_H +#define PROJECT_MAAT_UTILS_H + +#include + + +namespace pro_maat +{ + +static constexpr uint8_t pixelsPerUnit = 20; + +} + +#endif //PROJECT_MAAT_UTILS_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..0924c9a --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.14) +project(project_maat) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) + +add_executable(gTests gTests.cpp gTests.cpp) + +target_link_libraries(gTests + engine + gtest + pthread) \ No newline at end of file diff --git a/tests/gTests.cpp b/tests/gTests.cpp new file mode 100644 index 0000000..0eccc74 --- /dev/null +++ b/tests/gTests.cpp @@ -0,0 +1,11 @@ +// +// Created by Teo-CD on 06/06/19. +// + +#include + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc,argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file