From 36cceabfc5ddd22d9ae0d6c4dee9d4041bf2e348 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 28 Apr 2018 18:52:55 -0400 Subject: Implemented map object sprites Map objects cannot be interacted with or collided with yet but the sprites are loaded. --- src/components/realizable.h | 7 +++ src/game.cpp | 5 ++- src/systems/realizing.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++-- src/systems/realizing.h | 7 ++- 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/src/components/realizable.h b/src/components/realizable.h index f6a7eb4..0858e7a 100644 --- a/src/components/realizable.h +++ b/src/components/realizable.h @@ -18,6 +18,13 @@ public: */ std::string worldFile; + /** + * Path to the XML file containing the map object prototype definitions. + * + * @managed_by RealizingSystem + */ + std::string prototypeFile; + /** * Starting map and player location for a new game. * diff --git a/src/game.cpp b/src/game.cpp index b7dd200..d10c52c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -40,7 +40,10 @@ Game::Game() systemManager_.emplaceSystem(*this); systemManager_.emplaceSystem(*this); - systemManager_.getSystem().initSingleton("res/maps.xml"); + systemManager_.getSystem().initSingleton( + "res/maps.xml", + "res/entities.xml"); + systemManager_.getSystem().initPlayer(); glfwSwapInterval(1); diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index 09c38f3..c86dd5e 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp @@ -2,8 +2,10 @@ #include #include #include +#include #include "game.h" #include "consts.h" +#include "animation.h" #include "components/realizable.h" #include "components/mappable.h" #include "components/animatable.h" @@ -27,16 +29,58 @@ inline xmlChar* getProp(xmlNodePtr node, const char* attr) // TODO: neither the XML doc nor any of the emplaced entities are properly // destroyed if this method throws an exception. -EntityManager::id_type RealizingSystem::initSingleton(std::string filename) +EntityManager::id_type RealizingSystem::initSingleton( + std::string worldFile, + std::string prototypeFile) { id_type world = game_.getEntityManager().emplaceEntity(); auto& realizable = game_.getEntityManager(). emplaceComponent(world); + realizable.worldFile = worldFile; + realizable.prototypeFile = prototypeFile; + auto& mapping = game_.getSystemManager().getSystem(); - xmlDocPtr doc = xmlParseFile(filename.c_str()); + xmlChar* key = nullptr; + + // Create a mapping between prototype names and the XML trees defining them. + xmlDocPtr protoXml = xmlParseFile(prototypeFile.c_str()); + if (protoXml == nullptr) + { + throw std::invalid_argument("Cannot find prototypes file"); + } + + xmlNodePtr protoTop = xmlDocGetRootElement(protoXml); + if (protoTop == nullptr) + { + throw std::invalid_argument("Error parsing prototypes file"); + } + + if (xmlStrcmp(protoTop->name, reinterpret_cast("entities"))) + { + throw std::invalid_argument("Error parsing prototypes file"); + } + + std::map prototypes; + + for (xmlNodePtr node = protoTop->xmlChildrenNode; + node != nullptr; + node = node->next) + { + if (!xmlStrcmp(node->name, reinterpret_cast("entity"))) + { + key = getProp(node, "id"); + std::string prototypeId = reinterpret_cast(key); + xmlFree(key); + + prototypes[prototypeId] = node; + } + } + + // Create entities from the world definition. + xmlDocPtr doc = xmlParseFile(worldFile.c_str()); if (doc == nullptr) { throw std::invalid_argument("Cannot find world file"); @@ -53,8 +97,6 @@ EntityManager::id_type RealizingSystem::initSingleton(std::string filename) throw std::invalid_argument("Error parsing world file"); } - xmlChar* key = nullptr; - key = getProp(top, "startx"); realizable.startingX = atoi(reinterpret_cast(key)); xmlFree(key); @@ -113,6 +155,59 @@ EntityManager::id_type RealizingSystem::initSingleton(std::string filename) } xmlFree(key); + } else if (!xmlStrcmp( + mapNode->name, + reinterpret_cast("entity"))) + { + id_type mapObject = game_.getEntityManager().emplaceEntity(); + + key = getProp(mapNode, "type"); + std::string prototypeId = reinterpret_cast(key); + xmlFree(key); + + xmlNodePtr prototypeNode = prototypes[prototypeId]; + + // Set the coordinates from the object definition. + auto& transformable = game_.getEntityManager(). + emplaceComponent(mapObject); + + key = getProp(mapNode, "x"); + transformable.origX = atoi(reinterpret_cast(key)); + xmlFree(key); + + key = getProp(mapNode, "y"); + transformable.origY = atoi(reinterpret_cast(key)); + xmlFree(key); + + // Set the sprite and size using the prototype definition. + key = getProp(prototypeNode, "sprite"); + std::string spritePath = reinterpret_cast(key); + xmlFree(key); + + key = getProp(prototypeNode, "width"); + transformable.origW = atoi(reinterpret_cast(key)); + xmlFree(key); + + key = getProp(prototypeNode, "height"); + transformable.origH = atoi(reinterpret_cast(key)); + xmlFree(key); + + AnimationSet objectAnim( + spritePath.c_str(), + transformable.origW, + transformable.origH, + 1); + + objectAnim.emplaceAnimation("static", 0, 1, 1); + + auto& animatable = game_.getEntityManager(). + emplaceComponent( + mapObject, + std::move(objectAnim)); + + animatable.origAnimation = "static"; + + mappable.objects.push_back(mapObject); } else if (!xmlStrcmp( mapNode->name, reinterpret_cast("adjacent"))) @@ -172,6 +267,7 @@ EntityManager::id_type RealizingSystem::initSingleton(std::string filename) } xmlFreeDoc(doc); + xmlFreeDoc(protoXml); loadMap(realizable.entityByMapId[realizable.startingMapId]); diff --git a/src/systems/realizing.h b/src/systems/realizing.h index c681892..595c58f 100644 --- a/src/systems/realizing.h +++ b/src/systems/realizing.h @@ -1,6 +1,7 @@ #ifndef REALIZING_H_6853748C #define REALIZING_H_6853748C +#include #include "system.h" class RealizingSystem : public System { @@ -12,9 +13,11 @@ public: /** * Creates the singleton realizable entity and initializes it with the - * provided world definition. + * provided world definition and map object prototype definition. */ - id_type initSingleton(std::string filename); + id_type initSingleton( + std::string worldFile, + std::string prototypeFile); /** * Helper method that returns the entity ID of the (assumed) singleton entity -- cgit 1.4.1