diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cb9de2..44f62ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.18) project(Space) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) file(GLOB_RECURSE SRC src/*) file(GLOB_RECURSE LIB_HEADERS lib_headers/*) diff --git a/config.yaml b/config.yaml deleted file mode 100644 index 7ebb652..0000000 --- a/config.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Players config -players: - width: 250 - startPositionX: 0 - speed: 5 - user1_keys: - moveLeft: '4' - moveRight: '6' - shoot: '5' - user2_keys: - moveLeft: 'k' - moveRight: 'l' - shoot: 'm' - - -# Enemies config -enemies: - startPositionX: 0 - startPositionY: 0 - speed: 2 - size: 4 - distance: 10 # distance pixels between invaders - -missiles: - speed: 2 - width: 10 -torpedos: - speed: 2 - width: 10 diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..c3ff9ba --- /dev/null +++ b/config.yml @@ -0,0 +1,33 @@ +# Players config +players: + width: 250 + startXPosition: 0 + speed: 1 + user1: + color: red + keys: + left: 4 + right: 6 + shoot: 5 + user2: + color: blue + keys: + left: q + right: d + shoot: s + + +# Enemies config +invaders: + size: 4 + speed: 2 + distance: 10 # distance in pixels between invaders + +# Projectiles config +projectiles: + missiles: + speed: 2 + width: 10 + torpedos: + speed: 2 + width: 10 diff --git a/headers/config.h b/headers/config.h index 5913878..469d72c 100644 --- a/headers/config.h +++ b/headers/config.h @@ -2,6 +2,8 @@ #define GUARD_CONFIG_H #include +#include +#include #include "utils.h" #include "player_def.h" @@ -13,26 +15,32 @@ class Config{ public: aliensGrid grid; - unsigned alien_size; - unsigned distance; + unsigned invadersSize; + unsigned invadersDistance; - unsigned missile_width; - unsigned missile_length; // auto defined from width - unsigned torpedo_width; - unsigned torpedo_length; // auto defined from width - unsigned player_width; + unsigned missilesWidth; + unsigned missilesLength; // auto defined from width + unsigned torpedosWidth; + unsigned torpedosLength; // auto defined from width + unsigned playersWidth; - unsigned alien_speed; - unsigned player_speed; + unsigned invadersSpeed; + unsigned playersSpeed; 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(); - string getString(configKey& key); - int getInt(configKey& key); - nsGraphics::RGBAcolor getColor(configKey& key); }; #endif \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 89addb3..4c52f75 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,38 +1,120 @@ +#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); } -nsGraphics::RGBAcolor Config::getColor(configKey& key) { +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); + string colorStr = *getString(key); if (colorStr == "black")return nsGraphics::KBlack; else if (colorStr == "white")return nsGraphics::KWhite; else if (colorStr == "red")return nsGraphics::KRed; diff --git a/src/game_basics.cpp b/src/game_basics.cpp index 469254b..60edd03 100644 --- a/src/game_basics.cpp +++ b/src/game_basics.cpp @@ -7,7 +7,7 @@ Game::Game() : WININIT, pm(window) { - conf.loadConfig(); + conf.reloadConfig(); } void Game::managedGames() { @@ -52,7 +52,7 @@ bool Game::deathMenuHandler(){ bool Game::invadersTouchPlayer(){ for(aliensLine& line : grid){ - if(basePos.getY()+line.size()*conf.alien_size>=pm.getScreenHeight()-PLAYER_HEIGHT){ + if(basePos.getY()+line.size()*conf.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){ return true; } } @@ -73,7 +73,7 @@ WinValue Game::playGame(){ // returns when game is finished if(playMode!=SINGLE){ // mirror the start X position for the other - p2.x = pm.getScreenWidth()-conf.startXPosition-conf.player_width; + p2.x = pm.getScreenWidth()-conf.startXPosition-conf.playersWidth; } basePos = position(0,0); @@ -112,26 +112,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.alien_size+i*conf.distance, - basePos.getY()+j*conf.alien_size+j*conf.distance + basePos.getX() +i*conf.invadersSize + i * conf.invadersDistance, + basePos.getY() +j*conf.invadersSize + j * conf.invadersDistance ); switch(grid[i][j]){ case 0:{ - pm.dessinerInvader1(vec, conf.alien_size); + pm.dessinerInvader1(vec, conf.invadersSize); break; } case 1:{ - pm.dessinerInvader2(vec, conf.alien_size); + pm.dessinerInvader2(vec, conf.invadersSize); break; } case 2:{ - pm.dessinerInvader3(vec, conf.alien_size); + pm.dessinerInvader3(vec, conf.invadersSize); break; } } } } - cout << p1.x << endl; - pm.dessinerJoueur(position(p1.x, 0), conf.player_width, conf.p1Def.color); - if(playMode!=SINGLE)pm.dessinerJoueur(position(p2.x, 0), conf.player_width, conf.p2Def.color); + 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); } \ No newline at end of file diff --git a/src/game_managers.cpp b/src/game_managers.cpp index 63827bb..ae5d27e 100644 --- a/src/game_managers.cpp +++ b/src/game_managers.cpp @@ -8,15 +8,15 @@ void Game::managePlayerMoves(PlayerDef& pdef, unsigned& playerX){ if (ISPRESSED(pdef.keys.left)){ - if(playerX < conf.player_speed) playerX = 0; - else playerX = playerX-conf.player_speed; + if(playerX < conf.playersSpeed) playerX = 0; + else playerX = playerX-conf.playersSpeed; } if (ISPRESSED(pdef.keys.right)){ - if(playerX+conf.player_speed>=pm.getScreenWidth()) playerX = pm.getScreenWidth()-1; - else playerX = playerX+conf.player_speed; + if(playerX+conf.playersSpeed >= pm.getScreenWidth()) playerX = pm.getScreenWidth() - 1; + else playerX = playerX+conf.playersSpeed; } if(ISPRESSED(pdef.keys.shoot)){ - torpedos.emplace_back(playerX+conf.player_width/2, pm.getScreenHeight()-PLAYER_HEIGHT); + torpedos.emplace_back(playerX+ conf.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT); } } @@ -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.alien_size; // add the aliens - end+= (grid.size()-1)*conf.distance; // add the distance between aliens + end+= grid.size()*conf.invadersSize; // add the aliens + end+= (grid.size()-1)*conf.invadersDistance; // add the invadersDistance between aliens // you got the end position of the alien crowd ! - if(end+conf.alien_speed=conf.alien_speed){ - basePos.setX(basePos.getX()-conf.alien_speed); + if(basePos.getX()>=conf.invadersSpeed){ + basePos.setX(basePos.getX()-conf.invadersSpeed); }else{ - basePos.setY(basePos.getY()+conf.alien_size); + basePos.setY(basePos.getY()+conf.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.missile_lengthgetY()){ + if(miss->getY()+conf.missilesLength < tor->getY()){ } if(lineCollideCheck( // now check if they collide in X - miss->getX(), miss->getX()+conf.missile_width, - tor->getX(), tor->getX()+conf.torpedo_width)){ + miss->getX(), miss->getX()+conf.missilesWidth, + tor->getX(), tor->getX()+conf.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.missile_width, - p1.x, p1.x+conf.player_width)){ + miss.getX(), miss.getX()+conf.missilesWidth, + p1.x, p1.x+conf.playersWidth)){ return true; } }