#include "game.h" #define ISPRESSED(ID, X) window.isPressed({confData.playerDefs[ID].keys.X, false}) void Game::manageOnePlayer(playerID pID){ if (ISPRESSED(pID, left)){ if(players[pID].x < confData.playersSpeed) players[pID].x = 0; else players[pID].x -= confData.playersSpeed; } if (ISPRESSED(pID, right)){ if(players[pID].x + confData.playersWidth + confData.playersSpeed >= pm.getScreenWidth()) players[pID].x = pm.getScreenWidth() - confData.playersWidth - 1; else players[pID].x += confData.playersSpeed; } if(players[pID].fireCooldown==0) { if (ISPRESSED(pID, shoot)) { torpedos.emplace_back(players[pID].x + confData.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT, pID); players[pID].fireCooldown = confData.playersFireCooldown; } }else --players[pID].fireCooldown; } /** Makes the players play once */ void Game::managePlayers(){ manageOnePlayer(0); if(playMode==PlayMode::TWO_LOCAL)manageOnePlayer(1); else if(playMode==PlayMode::TWO_TCPIP){ // TODO TCPIP } } /** Makes the invaders play once, and check lower bounds * * @return true if the invaders went down from one line (and we should check lower boundary), else false */ bool Game::manageInvaders(){ // shoot if(fireCooldown==0) { fireCooldown = confData.invadersFireCooldown + rand() % 60; unsigned rdCol = grid.randomValid(); // fire ! missiles.push_back(basePos + Position( confData.invadersSize * rdCol + confData.invadersDistance * (rdCol + 0.5), confData.invadersSize * (grid[rdCol].size() - 1) + confData.invadersDistance * (grid[rdCol].size() - 1) )); }else --fireCooldown; // moving if(direction){ // go to the right int end = basePos.getX(); // start Position end+= grid.size() * confData.invadersSize; // add the invaders end+= (grid.size()-1) * confData.invadersDistance; // add the invadersDistance between invaders // you got the end position of the invader crowd ! if(end + confData.invadersSpeed < pm.getScreenWidth()){ basePos.setX(basePos.getX() + confData.invadersSpeed); }else{ basePos.setY(basePos.getY() + confData.invadersSize + confData.invadersDistance); direction = !direction; return true; } }else{ if(basePos.getX() >= confData.invadersSpeed){ basePos.setX(basePos.getX() - confData.invadersSpeed); }else{ basePos.setY(basePos.getY() + confData.invadersSize + confData.invadersDistance); direction = !direction; return true; } } return false; } /** makes projectiles move, and manage collisions between them and everything * * @return 1 if the invaders are all dead, 2 if the player is dead, else 0 */ void Game::remCollidingProjectiles(){ auto miss = missiles.begin(); auto tor = torpedos.begin(); while(miss != missiles.end()){ bool wasColliding = false; while(tor != torpedos.end()){ // missiles can't be right under torpedos, so that must means they are colliding in Y if(miss->getY() + confData.missilesLength < tor->getY()){ } if(areLinesColliding( // now check if they collide in X miss->getX(), miss->getX() + confData.missilesWidth, tor->getX(), tor->getX() + confData.torpedosWidth)){ missiles.erase(miss); torpedos.erase(tor); wasColliding = true; break; } ++tor; } /* if it was colling, it was removed and his Position is now replaced by the next. * else, go to the next */ if(!wasColliding)++miss; } } void Game::moveMissiles() { auto miss = missiles.begin(); while (miss != missiles.end()) { if (miss->getY() >= pm.getScreenHeight())missiles.erase(miss); else { miss->setY(miss->getY()+confData.missilesSpeed); ++miss; } } } void Game::moveTorpedos() { auto tor = torpedos.begin(); while (tor != torpedos.end()) { if (tor->getY()+confData.torpedosLength <= 0)torpedos.erase(tor); else{ tor->setY(tor->getY()-confData.torpedosSpeed); ++tor; } } } bool Game::checkMissilesAndPlayers() { auto miss_ite = missiles.begin(); while(miss_ite!=missiles.end()){ bool wasColliding = false; if(miss_ite->getY()>=pm.getScreenHeight()-PLAYER_HEIGHT){ // check collision on Y // now check collision on X (with both players) for(Player& p : players){ if(areLinesColliding( 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; // TODO manage death animation } bool Game::checkTorpedosAndInvaders() { auto tor_ite = torpedos.begin(); while(tor_ite!=torpedos.end()){ size_t i=0; for(;i=tor_ite->getY() && pos.getY()<=tor_ite->getY()+confData.torpedosLength){ // now check collision on X if(areLinesColliding( // now check collision on X tor_ite->getX(), tor_ite->getX() + confData.torpedosWidth, pos.getX(), pos.getX() + confData.invadersSize)){ InvaderType invType = grid[i][grid[i].size()]; players[tor_ite->owner].score += confData.invadersDef[invType].points; torpedos.erase(tor_ite); grid[i][alienIndex] = InvaderType::NONE; updateColumns(); break; } } } if(i==grid.size()) ++tor_ite; } return false; } bool Game::invadersTouchPlayer() const { for(const InvadersColumn& line : grid){ if(basePos.getY() + line.size() * confData.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){ return true; } } return false; }