diff --git a/headers/configData.h b/headers/configData.h index 0d0d38a..52e8f5c 100644 --- a/headers/configData.h +++ b/headers/configData.h @@ -8,9 +8,8 @@ typedef string configKey; struct ConfigData { - map internalValues; - aliensGrid grid; + invadersGrid grid; unsigned invadersSize; unsigned invadersDistance; @@ -24,8 +23,7 @@ struct ConfigData { unsigned invadersSpeed; unsigned playersSpeed; - PlayerDef p1Def; - PlayerDef p2Def; + vector playerDefs; unsigned startXPosition; }; diff --git a/headers/errors.h b/headers/errors.h deleted file mode 100644 index 1cd82c1..0000000 --- a/headers/errors.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef SPACE_ERRORS_H -#define SPACE_ERRORS_H - - - -#endif diff --git a/headers/game.h b/headers/game.h index b94eb95..170c9e7 100644 --- a/headers/game.h +++ b/headers/game.h @@ -4,11 +4,11 @@ #include "mingl/mingl.h" #include "pixel_manager.h" #include "utils.h" -#include "position.h" #include "player_def.h" #include "player.h" #include "play_mode.h" #include "configData.h" +#include "projectiles.h" using namespace std; @@ -19,15 +19,14 @@ private: ConfigData confData; position basePos; - aliensGrid grid; + invadersGrid grid; bool direction = true; vector missiles; vector torpedos; PlayMode playMode; - Player p1; - Player p2; + vector players; void managePlayers(); bool manageInvaders(); @@ -41,7 +40,7 @@ private: bool checkTorpedosAndInvaders(); bool invadersTouchPlayer(); - void managePlayerMoves(PlayerDef&, unsigned&); + void managePlayerMoves(PlayerDef&, unsigned&, unsigned); public: // in case someone wants to mess with the code, here's a minimal API, costs nothing to us diff --git a/headers/player.h b/headers/player.h index b4e905b..41e8a8a 100644 --- a/headers/player.h +++ b/headers/player.h @@ -5,7 +5,9 @@ struct Player{ unsigned lives; unsigned x; unsigned id; - unsigned score; + unsigned score=0; + + unsigned deathAnimCounter=0; }; #endif \ No newline at end of file diff --git a/headers/position.h b/headers/position.h deleted file mode 100644 index e757520..0000000 --- a/headers/position.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef GUARD_POSITION_H -#define GUARD_POSITION_H - -#include - -class position : public nsGraphics::Vec2D { -public: - position() = default; - position(int x, int y); - bool isColliding(position& p, int rx, int ry); -}; - -#endif diff --git a/headers/projectiles.h b/headers/projectiles.h new file mode 100644 index 0000000..f30583f --- /dev/null +++ b/headers/projectiles.h @@ -0,0 +1,14 @@ +#ifndef GUARD_PROJECTILES_H +#define GUARD_PROJECTILES_H + +#include "utils.h" + +typedef position missile; + +class torpedo : public position { +public: + playerID owner; + torpedo(int x, int y, playerID owner); +}; + +#endif diff --git a/headers/utils.h b/headers/utils.h index 3879830..9eea98c 100644 --- a/headers/utils.h +++ b/headers/utils.h @@ -1,9 +1,8 @@ -#ifndef GUARD_STRUCTS_H -#define GUARD_STRUCTS_H +#ifndef GUARD_UTILS_H +#define GUARD_UTILS_H #include #include -#include"position.h" // hardcoded values #define PLAYER_HEIGHT 100 @@ -17,17 +16,11 @@ enum WinValue{ using namespace std; -typedef unsigned Alien; -typedef vector aliensLine; -typedef vector aliensGrid; - -typedef position missile; - -class torpedo : public nsGraphics::Vec2D { -public: - topedo(int x, int y); - unsigned playerID; -}; +typedef unsigned Invader; +typedef vector invadersColumn; +typedef vector invadersGrid; +typedef nsGraphics::Vec2D position; +typedef unsigned playerID; // didn't want to use position because of the semantic with x and y bool lineCollideCheck(unsigned start1, unsigned end1, unsigned start2, unsigned end2); diff --git a/src/configManagement.cpp b/src/configManagement.cpp index 1ff8118..80343c5 100644 --- a/src/configManagement.cpp +++ b/src/configManagement.cpp @@ -78,15 +78,18 @@ void ConfigBuilder::readConfig() { collectedData.startXPosition = getInt("players.startXPosition"); collectedData.playersSpeed = getInt("players.speed"); - collectedData.p1Def.color = getColor("players.user1.color"); - collectedData.p1Def.keys.left = getChar("players.user1.keys.left"); - collectedData.p1Def.keys.right = getChar("players.user1.keys.right"); - collectedData.p1Def.keys.shoot = getChar("players.user1.keys.shoot"); + // the scalability behind the vector of players is only an illusion, because we force player count to be 1 or 2 + // It was done so the 2+ players implementation could be easier in the future, if wanted + collectedData.playerDefs.resize(2); + collectedData.playerDefs[1].color = getColor("players.user1.color"); + collectedData.playerDefs[1].keys.left = getChar("players.user1.keys.left"); + collectedData.playerDefs[1].keys.right = getChar("players.user1.keys.right"); + collectedData.playerDefs[1].keys.shoot = getChar("players.user1.keys.shoot"); - collectedData.p2Def.color = getColor("players.user2.color"); - collectedData.p2Def.keys.left = getChar("players.user2.keys.left"); - collectedData.p2Def.keys.right = getChar("players.user2.keys.right"); - collectedData.p2Def.keys.shoot = getChar("players.user2.keys.shoot"); + collectedData.playerDefs[2].color = getColor("players.user2.color"); + collectedData.playerDefs[2].keys.left = getChar("players.user2.keys.left"); + collectedData.playerDefs[2].keys.right = getChar("players.user2.keys.right"); + collectedData.playerDefs[2].keys.shoot = getChar("players.user2.keys.shoot"); // invaders collectedData.invadersSize = getInt("invaders.size"); diff --git a/src/game_basics.cpp b/src/game_basics.cpp index 2c21dd7..dbb57f0 100644 --- a/src/game_basics.cpp +++ b/src/game_basics.cpp @@ -58,7 +58,7 @@ bool Game::deathMenuHandler(){ } bool Game::invadersTouchPlayer(){ - for(aliensLine& line : grid){ + for(invadersColumn& line : grid){ if(basePos.getY()+ line.size() * confData.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){ return true; } @@ -76,12 +76,15 @@ WinValue Game::playGame(){ // returns when game is finished // we assume the game has been played before, and so we need to clean used members grid = confData.grid; // will copy the vector - p1.x = confData.startXPosition; - if(playMode!=SINGLE){ + if(playMode==SINGLE){ + players.resize(1); + }else{ + players.resize(2); // mirror the start X position for the other - p2.x = pm.getScreenWidth() - confData.startXPosition - confData.playersWidth; + players[1].x = pm.getScreenWidth() - confData.startXPosition - confData.playersWidth; } + players[0].x = confData.startXPosition; basePos = position(0,0); @@ -118,7 +121,7 @@ WinValue Game::playGame(){ // returns when game is finished 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( + nsGraphics::Vec2D vec( basePos.getX() + i * confData.invadersSize + i * confData.invadersDistance, basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance ); @@ -138,6 +141,8 @@ void Game::display() { } } } - 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); + + for(size_t i=0;igetX(), tor->getX() + confData.torpedosWidth)){ missiles.erase(miss); torpedos.erase(tor); - wasColling = true; + wasColliding = true; break; } ++tor; @@ -89,7 +92,7 @@ void Game::remCollidingProjectiles(){ /* if it was colling, it was removed and his position is now replaced by the next. * else, go to the next */ - if(!wasColling)++miss; + if(!wasColliding)++miss; } } @@ -116,18 +119,51 @@ void Game::moveTorpedos() { } 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() + confData.missilesWidth, - p1.x, p1.x + confData.playersWidth)){ - return true; + auto miss_ite = missiles.begin(); + while(miss_ite!=missiles.end()){ + if(miss_ite->getY()<=PLAYER_HEIGHT){ // check collision on Y + // now check collision on X (with both players) + bool wasColliding = false; + for(Player& p : players){ + if(lineCollideCheck( + miss_ite->getX(), miss_ite->getX() + confData.missilesWidth, + p.x, p.x + confData.playersWidth)){ + wasColliding = true; + if(p.deathAnimCounter)p.deathAnimCounter = 1; + // do not break, the second player also deserves to be hit + } } + if(wasColliding)missiles.erase(miss_ite); + else ++miss_ite; } } - return false; } bool Game::checkTorpedosAndInvaders() { + auto tor_ite = torpedos.begin(); + while(tor_ite!=torpedos.end()){ + unsigned i=0; + for(;i=tor_ite->getY() && + pos.getY()<=tor_ite->getY()+confData.torpedosLength){ + // now check collision on X + if(lineCollideCheck( // now check collision on X + tor_ite->getX(), tor_ite->getX() + confData.torpedosWidth, + pos.getX(), pos.getX() + confData.invadersSize)){ + break; + } + } + } + if(i==grid.size()) ++tor_ite; + else{ + torpedos.erase(tor_ite); + grid[i].pop_back(); + } + } return false; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 6b49215..c5d06ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "game.h" using namespace std; +// TODO changer tout les unsigned par des size_t dans les boucles int main(){ Game g; g.managedGames(); diff --git a/src/position.cpp b/src/position.cpp deleted file mode 100644 index 3cea989..0000000 --- a/src/position.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "position.h" -#include - -bool position::isColliding(position& p, int rx, int ry) { - return nsGraphics::Vec2D::isColliding(p, p+nsGraphics::Vec2D(rx, ry)); -} - -position::position(int x, int y) : Vec2D(x, y) {} diff --git a/src/projectiles.cpp b/src/projectiles.cpp new file mode 100644 index 0000000..f7afa18 --- /dev/null +++ b/src/projectiles.cpp @@ -0,0 +1,5 @@ +#include "projectiles.h" + +torpedo::torpedo(int x, int y, playerID owner) : position(x, y) { + this->owner = owner; +} diff --git a/src/utils.cpp b/src/utils.cpp index 42910ad..b39d7ae 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,7 +1,5 @@ #include "utils.h" -torpedo::torpedo(int x, int y) : position(x, y) {} - bool lineCollideCheck(unsigned start1, unsigned end1, unsigned start2, unsigned end2){ return start1 < end2 != start2 < end1; // if true, are colliding. I like truth tables