Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // game.cpp
- // XML Game Engine
- // author: beefviper
- // date: Sept 18, 2020
- #include "game.h"
- xge::Game::Game(std::string game) :
- filename(game)
- {
- initXML();
- initEXPR();
- initSFML();
- }
- void xge::Game::initXML()
- {
- tx::XMLError xmlErrorCode = xml.LoadFile(filename.c_str());
- checkXMLResult(xml, xmlErrorCode);
- tx::XMLElement* xGame = getXMLRoot(xml.FirstChildElement("game"));
- tx::XMLElement* xWindow = getXMLElement(xGame, "window");
- tx::XMLElement* xVariables = getXMLElement(xGame, "variables");
- tx::XMLElement* xObjects = getXMLElement(xGame, "objects");
- tx::XMLElement* xStates = getXMLElement(xGame, "states");
- tx::XMLElement* xVariable = getXMLElement(xVariables, "variable");
- tx::XMLElement* xObject = getXMLElement(xObjects, "object");
- tx::XMLElement* xState = getXMLElement(xStates, "state");
- // load window description
- windowDesc.title = getXMLAttribute(xWindow, "title");
- windowDesc.width = getXMLAttributeFloat(xWindow, "width");
- windowDesc.height = getXMLAttributeFloat(xWindow, "height");
- windowDesc.background = getXMLAttribute(xWindow, "background");
- windowDesc.fullscreen = getXMLAttribute(xWindow, "fullscreen");
- windowDesc.framerate = getXMLAttributeInt(xWindow, "framerate");
- // load variables
- while (xVariable != nullptr)
- {
- std::string vName = getXMLAttribute(xVariable, "name");
- float vValue = getXMLAttributeFloat(xVariable, "value");
- variables[vName] = vValue;
- xVariable = xVariable->NextSiblingElement("variable");
- }
- // load objects
- while (xObject != nullptr)
- {
- std::string xName = getXMLAttribute(xObject, "name");
- tx::XMLElement* xSprite = getXMLElement(xObject, "sprite");
- std::string xSrc = getXMLAttribute(xSprite, "src");
- tx::XMLElement* xPosition = getXMLElement(xObject, "position");
- std::string xPosX = getXMLAttribute(xPosition, "x");
- std::string xPosY = getXMLAttribute(xPosition, "y");
- tx::XMLElement* xVelocity = getXMLElement(xObject, "velocity");
- std::string xVelX = getXMLAttribute(xVelocity, "x");
- std::string xVelY = getXMLAttribute(xVelocity, "y");
- xge::Vector2str position{ xPosX, xPosY };
- xge::Vector2str velocity{ xVelX, xVelY };
- // TODO: Add <movement> and <action> tags
- Object object;
- object.init(xName, xSrc, position, velocity);
- objects.push_back(object);
- xObject = xObject->NextSiblingElement("object");
- }
- // load states
- while (xState != nullptr)
- {
- std::string sName = getXMLAttribute(xState, "name");
- tx::XMLElement* sObject = getXMLElement(xState, "show");
- std::vector<std::string> sShows;
- while (sObject != nullptr)
- {
- std::string shName = getXMLAttribute(sObject, "object");
- sShows.push_back(shName);
- sObject = sObject->NextSiblingElement("show");
- }
- tx::XMLElement* xInputs = getXMLElement(xState, "inputs");
- tx::XMLElement* xInput = getXMLElement(xInputs, "input");
- std::map<std::string, std::string> sInputs;
- while (xInput != nullptr)
- {
- std::string iAction = getXMLAttribute(xInput, "action");
- std::string iButton = getXMLAttribute(xInput, "button");
- sInputs[iAction] = iButton;
- xInput = xInput->NextSiblingElement("input");
- }
- xge::State state;
- state.init(sName, sShows, sInputs);
- states.push_back(state);
- xState = xState->NextSiblingElement("state");
- }
- }
- void xge::Game::initEXPR(void)
- {
- // TODO: Write code to parse the rest of the text fields
- // -- exprtk lib will parse text variables and expressions
- randomNumber<float> randomNumberFloat;
- randomRange<float> randomRangeFloat;
- shapeCircle<float> shapeCircleFloat;
- shapeRectangle<float> shapeRectangleFloat;
- float recWidth{};
- float recHeight{};
- exprtk::symbol_table<float> symbolTable;
- symbolTable.add_function("random.number", randomNumberFloat);
- symbolTable.add_function("random.range", randomRangeFloat);
- symbolTable.add_function("shape.circle", shapeCircleFloat);
- symbolTable.add_function("shape.rectangle", shapeRectangleFloat);
- symbolTable.add_constant("screen.left", 0);
- symbolTable.add_constant("screen.right", windowDesc.width);
- symbolTable.add_constant("screen.width.center", windowDesc.width / 2);
- symbolTable.add_constant("screen.height.center", windowDesc.height / 2);
- for (auto variable : variables)
- {
- symbolTable.add_constant(variable.first, variable.second);
- }
- symbolTable.add_variable("recWidth", recWidth);
- symbolTable.add_variable("recHeight", recHeight);
- exprtk::expression<float> expression;
- expression.register_symbol_table(symbolTable);
- exprtk::parser<float> parser;
- std::string expression_str;
- for (auto& object : objects)
- {
- expression_str = object.sposition.x;
- parser.compile(expression_str, expression);
- object.position.x = expression.value();
- expression_str = object.sposition.y;
- parser.compile(expression_str, expression);
- object.position.y = expression.value();
- expression_str = object.svelocity.x;
- parser.compile(expression_str, expression);
- object.velocity.x = expression.value();
- expression_str = object.svelocity.y;
- parser.compile(expression_str, expression);
- object.velocity.y = expression.value();
- // TODO: finish coming up with to parse different types of assets: shape, file, data
- if (object.src.compare(0, 12, "shape.circle") == 0)
- {
- expression_str = object.src;
- parser.compile(expression_str, expression);
- object.params.push_back(expression.value());
- }
- else if (object.src.compare(0, 15, "shape.rectangle") == 0)
- {
- auto e_start = object.src.find("(") + 1;
- auto e_end = object.src.find(",");
- auto e_length = e_end - e_start;
- expression_str = "recWidth := " + object.src.substr(e_start, e_length);
- parser.compile(expression_str, expression);
- expression.value();
- object.params.push_back(recWidth);
- e_start = object.src.find(",") + 1;
- e_end = object.src.find(")");
- e_length = e_end - e_start;
- expression_str = "recHeight := " + object.src.substr(e_start, e_length);
- parser.compile(expression_str, expression);
- expression.value();
- object.params.push_back(recHeight);
- }
- }
- }
- void xge::Game::initSFML(void)
- {
- for (auto& object : objects)
- {
- sf::CircleShape circle;
- sf::RectangleShape rectangle;
- object.renderTexture = std::make_shared<sf::RenderTexture>();
- if (object.src.compare(0, 12, "shape.circle") == 0)
- {
- float radius = object.params.at(0);
- circle.setRadius(radius);
- circle.setFillColor(sf::Color::Green);
- int width = static_cast<int>(std::ceil(circle.getLocalBounds().width));
- int height = static_cast<int>(std::ceil(circle.getLocalBounds().height));
- object.renderTexture->create(width, height);
- object.renderTexture->draw(circle);
- }
- else if (object.src.compare(0, 15, "shape.rectangle") == 0)
- {
- float recWidth = object.params.at(0);
- float recHeight = object.params.at(1);
- rectangle.setSize(sf::Vector2f(recWidth, recHeight));
- rectangle.setFillColor(sf::Color::Magenta);
- int width = static_cast<int>(std::ceil(rectangle.getLocalBounds().width));
- int height = static_cast<int>(std::ceil(rectangle.getLocalBounds().height));
- object.renderTexture->create(width, height);
- object.renderTexture->draw(rectangle);
- }
- object.renderTexture->display();
- object.sprite = std::make_shared<sf::Sprite>();
- object.sprite->setTexture(object.renderTexture->getTexture());
- object.sprite->setPosition(object.position);
- }
- }
- void xge::Game::updateObjects(void)
- {
- // TODO: only objects in the current state should be updating
- for (auto& object : objects)
- {
- object.position.x += object.velocity.x;
- object.position.y += object.velocity.y;
- object.sprite->setPosition(object.position.x, object.position.y);
- }
- }
- void xge::Game::printGame(void)
- {
- // debug -- print out window description
- std::cout << "window: ";
- std::cout << "title=" << windowDesc.title;
- std::cout << ", width=" << windowDesc.width;
- std::cout << ", height=" << windowDesc.height << std::endl;
- std::cout << std::endl;
- // debug -- print out variables
- for (auto variable : variables)
- {
- std::cout << "variable: name=" << variable.first << ", value=" << variable.second << std::endl;
- }
- std::cout << std::endl;
- // debug -- print out objects
- for (auto object : objects)
- {
- std::cout << object << std::endl;
- std::cout << std::endl;
- }
- // debug -- print out states
- for (auto state : states)
- {
- std::cout << "state: ";
- std::cout << "name=" << state.name << ", show=";
- for (auto show : state.show)
- {
- std::cout << show << (show != state.show.back() ? ", " : "\n");
- }
- for (auto input : state.input)
- {
- std::cout << " action=" << input.first << ", button=" << input.second << std::endl;
- }
- std::cout << std::endl;
- }
- }
- xge::WindowDesc xge::Game::getWinowDesc(void)
- {
- return windowDesc;
- }
- std::vector<xge::Object>& xge::Game::getObjects(void)
- {
- return objects;
- }
- xge::Object xge::Game::getObject(std::string name)
- {
- auto result = std::find_if(std::begin(objects), std::end(objects), [&](xge::Object& obj) { return obj.name == name; });
- return *result;
- }
- xge::State xge::Game::getCurrentState(void)
- {
- return currentState.top();
- }
- void xge::Game::setCurrentState(int index)
- {
- currentState.push(states.at(index));
- }
- void xge::Game::setObjectParam(std::string name, std::string param, float value)
- {
- auto result = std::find_if(std::begin(objects), std::end(objects), [&](xge::Object& obj) { return obj.name == name; });
- if (param == "velocity")
- {
- result->velocity.y = value;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement