From 3d9c50bf6ec3d394e9c1546259c07b96ece8bc31 Mon Sep 17 00:00:00 2001 From: Thomas R Date: Fri, 31 Dec 2021 18:28:33 +0100 Subject: [PATCH] oriented object config --- headers/{config.h => configData.h} | 24 +---- headers/game.h | 6 +- src/config.cpp | 135 ------------------------ src/configManagement.cpp | 159 +++++++++++++++++++++++++++++ src/game_basics.cpp | 26 ++--- src/game_managers.cpp | 40 ++++---- 6 files changed, 202 insertions(+), 188 deletions(-) rename headers/{config.h => configData.h} (58%) delete mode 100644 src/config.cpp create mode 100644 src/configManagement.cpp diff --git a/headers/config.h b/headers/configData.h similarity index 58% rename from headers/config.h rename to headers/configData.h index 469d72c..0d0d38a 100644 --- a/headers/config.h +++ b/headers/configData.h @@ -1,18 +1,15 @@ -#ifndef GUARD_CONFIG_H -#define GUARD_CONFIG_H +#ifndef GUARD_CONFIGDATA_H +#define GUARD_CONFIGDATA_H -#include -#include #include #include "utils.h" #include "player_def.h" -using namespace std; - typedef string configKey; -class Config{ -public: +struct ConfigData { + map internalValues; + aliensGrid grid; unsigned invadersSize; @@ -30,17 +27,6 @@ public: PlayerDef p1Def; PlayerDef p2Def; unsigned startXPosition; - - bool reloadConfig(); - string* getString(const configKey& key); - char getChar(const configKey& key); - int getInt(const configKey& key); - nsGraphics::RGBAcolor getColor(const configKey& key); - -private: - map internalValues; - bool parseConfig(); - bool loadConfig(); }; #endif \ No newline at end of file diff --git a/headers/game.h b/headers/game.h index dd670c7..b94eb95 100644 --- a/headers/game.h +++ b/headers/game.h @@ -3,12 +3,12 @@ #include #include "mingl/mingl.h" #include "pixel_manager.h" -#include "config.h" #include "utils.h" #include "position.h" #include "player_def.h" #include "player.h" #include "play_mode.h" +#include "configData.h" using namespace std; @@ -16,7 +16,7 @@ class Game { private: MinGL window; PixelManager pm; - Config conf; + ConfigData confData; position basePos; aliensGrid grid; @@ -42,6 +42,7 @@ private: bool invadersTouchPlayer(); void managePlayerMoves(PlayerDef&, unsigned&); + public: // in case someone wants to mess with the code, here's a minimal API, costs nothing to us Game(); @@ -50,6 +51,7 @@ public: PlayMode initialMenuHandler(); bool deathMenuHandler(); + bool reloadConfig(); }; #endif \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp deleted file mode 100644 index 4c52f75..0000000 --- a/src/config.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include "config.h" - -/** - * - * @return false if there was an error - */ -bool Config::reloadConfig() { - internalValues.clear(); - if(!parseConfig())return false; - if(!loadConfig()) return false; - return true; -} - -void trimSpaces(string& str){ - str.erase(0, str.find_first_not_of(' ')); -} - -bool Config::parseConfig() { - ifstream file("config.yml"); - if(!file.is_open())throw runtime_error("Error while opening config.yml. Check file location ?"); - - vector keyParts; - while (!file.eof()) { - string line; - getline(file, line); - auto match = line.find('#'); - if (match != string::npos)line.erase(match); - if (line.empty())continue; - - unsigned currentIndent = 0; - while (line[currentIndent] == ' ')++currentIndent; - - - match = line.find(':'); - if (match == string::npos)throw runtime_error("Invalid line : " + line); - string key = line.substr(0, match); - string value = line.substr(match + 1); - trimSpaces(key); - trimSpaces(value); - if (value.empty()) { - keyParts.resize(currentIndent); - keyParts.push_back(key); - } else { - string fullKey; - for (unsigned i = 0; i < currentIndent; ++i) { - fullKey.append(keyParts[i]); - fullKey.append("."); - } - fullKey.append(key); - internalValues[fullKey] = value; - } - } - - file.close(); - return true; -} - -bool Config::loadConfig() { - // TODO PUT THAT IN CONFIG ?? -#define S 48 - grid.resize(S); - for(unsigned i=0;iat(0); -} - -string* Config::getString(const configKey& key) { - if(internalValues.contains(key)){ - return &internalValues.at(key); - }else{ - cerr << "Non-existent key requested : " << key << endl; - return nullptr; // invalid reference returned, - } -} - -nsGraphics::RGBAcolor Config::getColor(const configKey& key) { - // switch do not work with strings, and I don't want to implement a constexpr hash function - string colorStr = *getString(key); - if (colorStr == "black")return nsGraphics::KBlack; - else if (colorStr == "white")return nsGraphics::KWhite; - else if (colorStr == "red")return nsGraphics::KRed; - else if (colorStr == "lime")return nsGraphics::KLime; - else if (colorStr == "blue")return nsGraphics::KBlue; - else if (colorStr == "yellow")return nsGraphics::KYellow; - else if (colorStr == "cyan")return nsGraphics::KCyan; - else if (colorStr == "magenta")return nsGraphics::KMagenta; - else if (colorStr == "silver")return nsGraphics::KSilver; - else if (colorStr == "gray")return nsGraphics::KGray; - else if (colorStr == "maroon")return nsGraphics::KMaroon; - else if (colorStr == "olive")return nsGraphics::KOlive; - else if (colorStr == "green")return nsGraphics::KGreen; - else if (colorStr == "purple")return nsGraphics::KPurple; - else if (colorStr == "teal")return nsGraphics::KTeal; - else if (colorStr == "navy")return nsGraphics::KNavy; - else throw runtime_error("Invalid color string : "+colorStr); -} diff --git a/src/configManagement.cpp b/src/configManagement.cpp new file mode 100644 index 0000000..bb56c34 --- /dev/null +++ b/src/configManagement.cpp @@ -0,0 +1,159 @@ +#include +#include "game.h" + +class ConfigBuilder{ +public: + ConfigData collectedData; + void parseFile(const string& fname); + void readConfig(); + +private: + map internalValues; + + string& getString(const configKey& key); + char getChar(const configKey& key); + int getInt(const configKey& key); + nsGraphics::RGBAcolor getColor(const configKey& key); + +}; + +void trimSpaces(string& str){ + str.erase(0, str.find_first_not_of(' ')); +} + +void ConfigBuilder::parseFile(const string& fname) { + ifstream file(fname); + if(!file.is_open())throw runtime_error("Error while opening config.yml. Check file location ?"); + + vector keyParts; + while (!file.eof()) { + string line; + getline(file, line); + auto match = line.find('#'); + if (match != string::npos)line.erase(match); + if (line.empty())continue; + + unsigned currentIndent = 0; + while (line[currentIndent] == ' ')++currentIndent; + + + match = line.find(':'); + if (match == string::npos)throw runtime_error("Invalid line : " + line); + string key = line.substr(0, match); + string value = line.substr(match + 1); + trimSpaces(key); + trimSpaces(value); + if (value.empty()) { + keyParts.resize(currentIndent); + keyParts.push_back(key); + } else { + string fullKey; + for (unsigned i = 0; i < currentIndent; ++i) { + fullKey.append(keyParts[i]); + fullKey.append("."); + } + fullKey.append(key); + internalValues[fullKey] = value; + } + } + + file.close(); +} + +void ConfigBuilder::readConfig() { + // TODO PUT THAT IN CONFIG ?? +#define S 48 + collectedData.grid.resize(S); + for(unsigned i=0;i strValues; + ConfigBuilder builder; + bool parsed = false; + try{ + builder.parseFile("config.yml"); + parsed = true; + builder.readConfig(); + }catch(runtime_error& e){ + if(parsed)cerr << "An error occured while reading the configuration :" << endl; + else cerr << "An error occured while parsind the configuration :" << endl; + cerr << e.what() << endl; + return false; + } + confData = builder.collectedData; + return true; +} diff --git a/src/game_basics.cpp b/src/game_basics.cpp index 60edd03..fbfb35b 100644 --- a/src/game_basics.cpp +++ b/src/game_basics.cpp @@ -7,7 +7,9 @@ Game::Game() : WININIT, pm(window) { - conf.reloadConfig(); + if(!reloadConfig()){ + throw runtime_error("Initial config loading failed. Please check the error above and fix the configuration"); + } } void Game::managedGames() { @@ -52,7 +54,7 @@ bool Game::deathMenuHandler(){ bool Game::invadersTouchPlayer(){ for(aliensLine& line : grid){ - if(basePos.getY()+line.size()*conf.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){ + if(basePos.getY()+ line.size() * confData.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){ return true; } } @@ -67,13 +69,13 @@ bool Game::invadersTouchPlayer(){ WinValue Game::playGame(){ // returns when game is finished // INIT // we assume the game has been played before, and so we need to clean used members - grid = conf.grid; // will copy the vector + grid = confData.grid; // will copy the vector - p1.x = conf.startXPosition; + p1.x = confData.startXPosition; if(playMode!=SINGLE){ // mirror the start X position for the other - p2.x = pm.getScreenWidth()-conf.startXPosition-conf.playersWidth; + p2.x = pm.getScreenWidth() - confData.startXPosition - confData.playersWidth; } basePos = position(0,0); @@ -112,25 +114,25 @@ void Game::display() { for (unsigned i = 0; i < this->grid.size(); ++i){ for (unsigned j = 0; j < this->grid[i].size(); ++j){ nsGraphics::Vec2D vec =nsGraphics::Vec2D( - basePos.getX() +i*conf.invadersSize + i * conf.invadersDistance, - basePos.getY() +j*conf.invadersSize + j * conf.invadersDistance + basePos.getX() + i * confData.invadersSize + i * confData.invadersDistance, + basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance ); switch(grid[i][j]){ case 0:{ - pm.dessinerInvader1(vec, conf.invadersSize); + pm.dessinerInvader1(vec, confData.invadersSize); break; } case 1:{ - pm.dessinerInvader2(vec, conf.invadersSize); + pm.dessinerInvader2(vec, confData.invadersSize); break; } case 2:{ - pm.dessinerInvader3(vec, conf.invadersSize); + pm.dessinerInvader3(vec, confData.invadersSize); break; } } } } - pm.dessinerJoueur(position(p1.x, 0), conf.playersWidth, conf.p1Def.color); - if(playMode!=SINGLE)pm.dessinerJoueur(position(p2.x, 0), conf.playersWidth, conf.p2Def.color); + pm.dessinerJoueur(position(p1.x, 0), confData.playersWidth, confData.p1Def.color); + if(playMode!=SINGLE)pm.dessinerJoueur(position(p2.x, 0), confData.playersWidth, confData.p2Def.color); } \ No newline at end of file diff --git a/src/game_managers.cpp b/src/game_managers.cpp index ae5d27e..f3e1d54 100644 --- a/src/game_managers.cpp +++ b/src/game_managers.cpp @@ -8,23 +8,23 @@ void Game::managePlayerMoves(PlayerDef& pdef, unsigned& playerX){ if (ISPRESSED(pdef.keys.left)){ - if(playerX < conf.playersSpeed) playerX = 0; - else playerX = playerX-conf.playersSpeed; + if(playerX < confData.playersSpeed) playerX = 0; + else playerX = playerX - confData.playersSpeed; } if (ISPRESSED(pdef.keys.right)){ - if(playerX+conf.playersSpeed >= pm.getScreenWidth()) playerX = pm.getScreenWidth() - 1; - else playerX = playerX+conf.playersSpeed; + if(playerX + confData.playersSpeed >= pm.getScreenWidth()) playerX = pm.getScreenWidth() - 1; + else playerX = playerX + confData.playersSpeed; } if(ISPRESSED(pdef.keys.shoot)){ - torpedos.emplace_back(playerX+ conf.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT); + torpedos.emplace_back(playerX + confData.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT); } } /** Makes the players play once */ void Game::managePlayers(){ - managePlayerMoves(conf.p1Def, p1.x); - if(playMode==PlayMode::TWO_LOCAL)managePlayerMoves(conf.p2Def, p2.x); + managePlayerMoves(confData.p1Def, p1.x); + if(playMode==PlayMode::TWO_LOCAL)managePlayerMoves(confData.p2Def, p2.x); } /** Makes the invaders play once, and check lower bounds @@ -34,23 +34,23 @@ void Game::managePlayers(){ bool Game::manageInvaders(){ if(direction){ // go to the right int end = basePos.getX(); // start position - end+= grid.size()*conf.invadersSize; // add the aliens - end+= (grid.size()-1)*conf.invadersDistance; // add the invadersDistance between aliens + end+= grid.size() * confData.invadersSize; // add the aliens + end+= (grid.size()-1) * confData.invadersDistance; // add the invadersDistance between aliens // you got the end position of the alien crowd ! - if(end+conf.invadersSpeed < pm.getScreenWidth()){ - basePos.setX(basePos.getX()+conf.invadersSpeed); + if(end + confData.invadersSpeed < pm.getScreenWidth()){ + basePos.setX(basePos.getX() + confData.invadersSpeed); }else{ - basePos.setY(basePos.getY()+conf.invadersSize); + basePos.setY(basePos.getY() + confData.invadersSize); direction = !direction; return true; } }else{ - if(basePos.getX()>=conf.invadersSpeed){ - basePos.setX(basePos.getX()-conf.invadersSpeed); + if(basePos.getX() >= confData.invadersSpeed){ + basePos.setX(basePos.getX() - confData.invadersSpeed); }else{ - basePos.setY(basePos.getY()+conf.invadersSize); + basePos.setY(basePos.getY() + confData.invadersSize); direction = !direction; return true; } @@ -73,12 +73,12 @@ void Game::remCollidingProjectiles(){ while(tor != torpedos.end()){ // missiles can't be right under torpedos, so that must means they are colliding in Y - if(miss->getY()+conf.missilesLength < tor->getY()){ + if(miss->getY() + confData.missilesLength < tor->getY()){ } if(lineCollideCheck( // now check if they collide in X - miss->getX(), miss->getX()+conf.missilesWidth, - tor->getX(), tor->getX()+conf.torpedosWidth)){ + miss->getX(), miss->getX() + confData.missilesWidth, + tor->getX(), tor->getX() + confData.torpedosWidth)){ missiles.erase(miss); torpedos.erase(tor); wasColling = true; @@ -119,8 +119,8 @@ bool Game::checkMissilesAndPlayers() { for(missile& miss : missiles){ if(miss.getY()<=PLAYER_HEIGHT){ // colliding on Y if(lineCollideCheck( // now check collision on X - miss.getX(), miss.getX()+conf.missilesWidth, - p1.x, p1.x+conf.playersWidth)){ + miss.getX(), miss.getX() + confData.missilesWidth, + p1.x, p1.x + confData.playersWidth)){ return true; } }