diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..41cfbe8 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,34 @@ +target_sources (SuperMario PRIVATE "main.cpp" + "GameWindow.cpp" + "Controller.cpp" + "Board.cpp" + "GameObject.cpp" + "MovingObject.cpp" + "Platforms.cpp" + "SuperMushroom.cpp" + "Player.cpp" + "Enemy.cpp" + "BadMushroom.cpp" + "PiranaPlants.cpp" + "FlyingTortoise.cpp" + "Tortoise.cpp" + "Obstacle.cpp" + "FireBall.cpp" + "FirePole.cpp" + "StaticObject.cpp" + "Pickable.cpp" + "Coin.cpp" + "UnPickable.cpp" + "Floor.cpp" + "Brick.cpp" + "QuestionBlock.cpp" + "Pipe.cpp" + "Block.cpp" + "GoalFlag.cpp" + "AudioHolder.cpp" + "TextureHolder.cpp" + "Animation.cpp" + "Collision.cpp" + "GoalPole.cpp" + "Fireworks.cpp") + \ No newline at end of file diff --git a/src/Enemys/BadMushroom.cpp b/src/Enemys/BadMushroom.cpp new file mode 100644 index 0000000..4c1710e --- /dev/null +++ b/src/Enemys/BadMushroom.cpp @@ -0,0 +1,28 @@ +#include "BadMushroom.h" + +BadMushroom::BadMushroom(int row, int col) + : Enemy(TextureHolder::instance().getEnemy(I_BADMUSHROOM), LEFT, BAD_MUSH_SIZE, row ,col) +{ +} + +//----------------------------------------------------------------------------- +void BadMushroom::move(sf::Time deltaTime) +{ + if (!m_dead) + { + sideMove(deltaTime, ENEMY_SPEED); + m_animation.staticShift(deltaTime, SWITCH); + m_animation.setDirection(m_dir); + } + else if (m_tortoiseKill) + handleDeathTortoise(deltaTime); + + else + handleDeath(deltaTime); +} + +//----------------------------------------------------------------------------- +BadMushroom::~BadMushroom() +{ +} + diff --git a/src/Enemys/Enemy.cpp b/src/Enemys/Enemy.cpp new file mode 100644 index 0000000..d7b8bc0 --- /dev/null +++ b/src/Enemys/Enemy.cpp @@ -0,0 +1,11 @@ +#include "Enemy.h" + +Enemy::Enemy(const sf::Texture& data, bool dir, int size, int row, int col) + : MovingObject(data, dir, size,row,col) +{ +} + +//----------------------------------------------------------------------------- +Enemy::~Enemy() +{ +} diff --git a/src/Enemys/FlyingTortoise.cpp b/src/Enemys/FlyingTortoise.cpp new file mode 100644 index 0000000..25e8192 --- /dev/null +++ b/src/Enemys/FlyingTortoise.cpp @@ -0,0 +1,35 @@ +#include "FlyingTortoise.h" + +FlyingTortoise::FlyingTortoise(int row, int col) + : Enemy(TextureHolder::instance().getEnemy(I_F_TORTOISE), RIGHT, F_TORTOISE_SIZE,row,col) +{ +} + +//----------------------------------------------------------------------------- +void FlyingTortoise::move(sf::Time deltaTime) +{ + if (!m_dead) + upDownMove(deltaTime, ENEMY_SPEED, MAX_HEIGHT, MIN_HEIGHT, SWITCH); + else + handleDeath(deltaTime); +} + +//----------------------------------------------------------------------------- +void FlyingTortoise::handleDeath(sf::Time deltaTime) +{ + if (m_deathTimePassed == 0) + m_velocity.y = 0; + + fall(deltaTime); + m_sprite.move(m_velocity); + m_deathTimePassed += deltaTime.asSeconds(); + + // His death is ended + if (m_deathTimePassed > DEATH_TIME) + isDelete(); +} + +//----------------------------------------------------------------------------- +FlyingTortoise::~FlyingTortoise() +{ +} diff --git a/src/Enemys/PiranaPlants.cpp b/src/Enemys/PiranaPlants.cpp new file mode 100644 index 0000000..c8cf480 --- /dev/null +++ b/src/Enemys/PiranaPlants.cpp @@ -0,0 +1,23 @@ +#include "PiranaPlants.h" + +PiranaPlants::PiranaPlants(int row, int col) + : Enemy(TextureHolder::instance().getEnemy(I_PIRANA), LEFT, PIRANA_SIZE,row,col) +{ + m_sprite.setScale(PIRANA_SCALE, PIRANA_SCALE); + m_sprite.setPosition((float)(col * ICON_SIZE+ PIPE_X_POS), + (float)((row * ICON_SIZE + PIPE_Y_POS))); + m_lastPos = m_sprite.getPosition(); +} + +//----------------------------------------------------------------------------- +void PiranaPlants::move(sf::Time deltaTime) +{ + if (m_dead) + m_delete = true; + upDownMove(deltaTime, PIRANA_SPEED, m_lastPos.y, m_lastPos.y + ICON_SIZE * PIRANA_MOV, SWITCH_PIRANA); +} + +//----------------------------------------------------------------------------- +PiranaPlants::~PiranaPlants() +{ +} diff --git a/src/Enemys/Tortoise.cpp b/src/Enemys/Tortoise.cpp new file mode 100644 index 0000000..90a2195 --- /dev/null +++ b/src/Enemys/Tortoise.cpp @@ -0,0 +1,65 @@ +#include "Tortoise.h" + +Tortoise::Tortoise(int row, int col) + : Enemy(TextureHolder::instance().getEnemy(I_TORTOISE), LEFT, TORTOISE_SIZE, row ,col), + m_shell(false), m_jumped(false) +{ + m_sprite.setPosition((float)(col * ICON_SIZE), + (float)((row * ICON_SIZE)) + TORTOISE_Y_POS); +} + +//----------------------------------------------------------------------------- +void Tortoise::move(sf::Time deltaTime) +{ + if (!m_shell) + { + sideMove(deltaTime, ENEMY_SPEED); + m_animation.staticShift(deltaTime, SWITCH); + m_animation.setDirection(m_dir); + } + + else if (m_jumped) + sideMove(deltaTime, SHELL_SPEED); + + if (m_tortoiseKill) + handleDeathTortoise(deltaTime); +} + +//----------------------------------------------------------------------------- +void Tortoise::setShell() +{ + m_shell = true; + m_animation.setDeadSprite(); +} + +//----------------------------------------------------------------------------- +bool Tortoise::getShell() const +{ + return m_shell; +} + +//----------------------------------------------------------------------------- +void Tortoise::setJumped(bool condition) +{ + m_jumped = condition; +} + +//----------------------------------------------------------------------------- +bool Tortoise::getJumped() const +{ + return m_jumped; +} + +//----------------------------------------------------------------------------- +void Tortoise::setDirection(float playerPosX) +{ + if (playerPosX > getPos().x) + m_dir = LEFT; + else + m_dir = RIGHT; +} + +//----------------------------------------------------------------------------- +Tortoise::~Tortoise() +{ +} \ No newline at end of file diff --git a/src/GameHandlers/Board.cpp b/src/GameHandlers/Board.cpp new file mode 100644 index 0000000..5af6081 --- /dev/null +++ b/src/GameHandlers/Board.cpp @@ -0,0 +1,307 @@ +#include "Board.h" + +Board::Board() : m_player(nullptr), m_releasedShift(true) +{ + m_inputFile.open("Levels.txt"); + if(!m_inputFile.is_open()) + throw std::exception("maps file couldn't be open.\n"); +} + +//----------------------------------------------------------------------------- +void Board::moveObject(sf::Time deltaTime) +{ + shootFireWorks(); // In case we are shooting fireworks + for (int i = 0; i < m_moving.size(); i++) + { + if (m_moving[i]->isShouldMove()) // Explained in README + tryMove(i, deltaTime); // Moving the objects and check collisions + + if (tryToDelete(m_moving[i].get()) && i != m_moving.size() - 1) // Checking if there is no longer use for an object. + { + m_player->addPoints(m_moving[i]->getGatheredPoints()); // In case we got points indirectly here we pick them. + + if (m_moving[i]->getGatheredPoints() == COIN_POINTS) // In case we got Coins indirectly here we pick them. + m_player->addCoin(); + + m_moving[i].release(); + m_moving.erase(m_moving.begin() + i--); + } + } + + for (int i = 0; i < m_static.size(); i++) + if (tryToDelete(m_static[i].get())) // Checking if there is no longer use for an object. + { + m_static[i].release(); + m_static.erase(m_static.begin() + i--); + } +} + +//----------------------------------------------------------------------------- +// This function is called to try and shoot a firework if the player is +// fiery Mario and pressed shift. +void Board::shootFireWorks() +{ + // In this function we ask if shift is released so we wont spam fireworks. + + if (m_player->isFiery() && m_releasedShift && + sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift)) + { + m_releasedShift = false; + AudioHolder::instance().playSound(AUDIO_FIRE); + m_moving.emplace(m_moving.begin(), std::make_unique(m_player->getPos(), m_player->getDirection())); + } + + if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift)) + m_releasedShift = true; +} + +//----------------------------------------------------------------------------- +// The main function that handles movement. +void Board::tryMove(int index, sf::Time deltaTime) +{ + // Checking if the moving object is in the view, if it isn't we shouldn't move him. + if (m_moving[index]->getPos().x >= m_player->getLeftBorder() - ICON_SIZE && + m_moving[index]->getPos().x < m_player->getLeftBorder() + VIEW_WIDTH) + { + m_moving[index]->move(deltaTime); + m_moving[index]->setToAir(); + + if (index == m_moving.size() - 1 && m_player->isDead()) + return; + + checkCollision(m_moving[index]); + } +} + +//----------------------------------------------------------------------------- +// In case the object is no longer on the screen forever, or his delete +// flag is up - we return true to delete him. +bool Board::tryToDelete(GameObject* Obj) +{ + if (Obj->isDelete() || + Obj->getPos().x < m_player->getLeftBorder() - (ICON_SIZE * 2) || + Obj->getPos().y > VIEW_HEIGHT + ICON_SIZE * 2) + return true; + return false; +} + +//----------------------------------------------------------------------------- +// Here a moving object check collision with static and moving object +void Board::checkCollision(std::unique_ptr& object) +{ + for (auto& moving : m_moving) // Checking collisions with static + if (object != moving) + if (object->draw().getGlobalBounds().intersects(moving->draw().getGlobalBounds())) + m_collision.processMovCollision(*object, *moving); + + for (auto& staticObj : m_static) // Checking collisions with moving + if (object->draw().getGlobalBounds().intersects(staticObj->draw().getGlobalBounds())) + m_collision.processStaticCollision(*object, *staticObj); +} + +//----------------------------------------------------------------------------- +bool Board::readMap(bool restart) +{ + if (restart) // In case we started a new game + m_inputFile.seekg(0); + + if (m_inputFile.eof()) // If we finished all maps + return true; + + auto line = std::string(); + for (int i = 0; i < ROWS; i++) + { + m_map[i].clear(); + std::getline(m_inputFile, line); + m_map[i] = line; + } + + if(m_map.size() != ROWS) + throw std::exception("Map size isn't correct.\n"); + + createObjects(); // Creating all the objects. + return false; +} + +//----------------------------------------------------------------------------- +// This function is used to send the sprite to print the map from GameWindow class. +// The function sends specific sprite by the boolean that was sent. +const sf::Sprite& Board::drawToWindow(int& index_moving, int& index_static, + bool& moving, bool& statics, bool& firePoles) const +{ + sf::Sprite temp; + + // sending the specific sprite - moving object by the index given. + if (moving) + { + if (m_moving.size() - 1 == index_moving) + moving = false; + else if (!m_moving[index_moving]->isFirePole()) + return m_moving[index_moving++]->draw(); + else + index_moving++; + } + + // sending the specific sprite - static object by the index given. + else if (statics) + { + if (m_static.size() == index_static) + statics = false; + else + return m_static[index_static++]->draw(); + } + else + { + if (m_moving.size() == index_moving) + firePoles = false; + else if (m_moving[index_moving]->isFirePole() || index_moving == m_moving.size() - 1) + return m_moving[index_moving++]->draw(); + else + index_moving++; + } + return temp; +} + +//----------------------------------------------------------------------------- +void Board::createObjects() +{ + for (int row = 0; row < ROWS; row++) + for (int col = 0; col < m_map[row].size(); col++) + if (m_map[row][col] != AIR) + buildObject(row, col, m_map[row][col]); +} + +//----------------------------------------------------------------------------- +void Board::buildObject(int row, int col, char element) +{ + std::unique_ptr movable; + std::unique_ptr unmovable; + + movable = createMovingObj(row, col, element); + + if (movable) + { + m_moving.push_back(std::move(movable)); + return; + } + + unmovable = createStaticObj(row, col, element); + if (unmovable) + { + m_static.push_back(std::move(unmovable)); + return; + } + + throw std::exception("No such element was declared.\n"); +} + +//----------------------------------------------------------------------------- +static std::unique_ptr createMovingObj(int row, int col, char element) +{ + switch (element) + { + case PLATFORM: return std::make_unique(row, col); + case TORTOISE:return std::make_unique(row, col); + case FLYING_TORTOISE:return std::make_unique(row, col); + case BAD_MUSHROOM:return std::make_unique(row, col); + case PIRANA_PLANT:return std::make_unique(row, col); + case SUPER_MUSH:return std::make_unique(row, col); + case FIRE_BALL:return std::make_unique(row, col); + case FIRE_POLE:return std::make_unique(row, col); + case BRICK:return std::make_unique(row, col); + case COIN: return std::make_unique(row, col); + case QUESTION:return std::make_unique(row, col); + case GOAL_FLAG:return std::make_unique(row, col); + } + return nullptr; +} + +//----------------------------------------------------------------------------- +static std::unique_ptr createStaticObj(int row, int col, char element) +{ + switch (element) + { + case FLOOR:return std::make_unique(row, col); + case PIPE:return std::make_unique(row, col); + case BLOCK:return std::make_unique(row, col); + case GOAL_POLE:return std::make_unique(row, col); + } + return nullptr; +} + +//----------------------------------------------------------------------------- +// This function create the player object +void Board::createPlayer(int life,int coins, int score, int condition) +{ + m_moving.push_back(std::make_unique(life,score,coins,condition)); + + if (auto p = dynamic_cast(m_moving[m_moving.size() - 1].get())) + m_player = p; +} + +//----------------------------------------------------------------------------- +// restarting the stage in case the player have died. +int Board::restartStage() +{ + int condition = 0; + condition = marioState(); + + for (int i = 0; i < m_moving.size(); i++) + { + m_moving[i].release(); + m_moving.erase(m_moving.begin() + i--); + } + for (int i = 0; i < m_static.size(); i++) + { + m_static[i].release(); + m_static.erase(m_static.begin() + i--); + } + + return condition; +} + +//----------------------------------------------------------------------------- +int Board::marioState() const +{ + if (m_player) + { + if (m_player->isFiery()) + return I_F_MARIO; + else if (m_player->isFieryOrSuper()) + return I_S_MARIO; + return I_MARIO; + } +} + +//----------------------------------------------------------------------------- +void Board::getGameData(int& score, int& coins, int& life) +{ + score = m_player->getPoints(); + coins = m_player->getCoins(); + life = m_player->getLife(); +} + +//----------------------------------------------------------------------------- +float Board::WindowLeftBorder() const +{ + return m_player->getLeftBorder(); +} + +//----------------------------------------------------------------------------- +bool Board::isStageCleared() const +{ + return m_player->isStageCleared(); +} + +//----------------------------------------------------------------------------- +bool Board::isPlayerDead() const +{ + if (m_player && m_player->isDelete()) + return true; + return false; +} + +//----------------------------------------------------------------------------- +Board::~Board() +{ +} diff --git a/src/GameHandlers/Collision.cpp b/src/GameHandlers/Collision.cpp new file mode 100644 index 0000000..a49d9d5 --- /dev/null +++ b/src/GameHandlers/Collision.cpp @@ -0,0 +1,574 @@ +#include "Collision.h" + +Collision::Collision() +{ +} + +//----------------------------------------------------------------------------- +void Collision::processMovCollision(MovingObject& object1, + MovingObject& object2) +{ + auto phf = lookupMove(typeid(object1), typeid(object2)); + if (!phf) + return; + + phf(object1, object2); +} + +//----------------------------------------------------------------------------- +HitFunctionPtrMove Collision::lookupMove(const std::type_index& class1, const std::type_index& class2) +{ + static HitMapMove collisionMoveMap = initializeMovingCollision(); + auto mapEntry = collisionMoveMap.find(std::make_pair(class1, class2)); + if (mapEntry == collisionMoveMap.end()) + return nullptr; + + return mapEntry->second; +} + +//----------------------------------------------------------------------------- +void Collision::processStaticCollision(MovingObject& object1, + StaticObject& object2) +{ + auto phf = lookupStatic(typeid(object1), typeid(object2)); + if (!phf) + return; + + phf(object1, object2); +} + +//----------------------------------------------------------------------------- +HitFunctionPtrStatic Collision::lookupStatic(const std::type_index& class1, const std::type_index& class2) +{ + static HitMapStatic collisionStaticMap = initializeStaticCollision(); + auto mapEntry = collisionStaticMap.find(std::make_pair(class1, class2)); + if (mapEntry == collisionStaticMap.end()) + return nullptr; + + return mapEntry->second; +} + + +//----------------------------------------------------------------------------- +HitMapMove Collision::initializeMovingCollision() +{ + HitMapMove phm; + + // ----------- Enemy Collisions ---------- + phm[Key(typeid(BadMushroom), typeid(Tortoise))] = &badMushroomTortoise; + phm[Key(typeid(BadMushroom), typeid(BadMushroom))] = &badMushroomBadMushroom; + phm[Key(typeid(Tortoise), typeid(Tortoise))] = &tortoiseTortoise; + phm[Key(typeid(BadMushroom), typeid(Brick))] = &MovingBrick; + phm[Key(typeid(Tortoise), typeid(Brick))] = &MovingBrick; + phm[Key(typeid(BadMushroom), typeid(QuestionBlock))] = &MovingBrick; + phm[Key(typeid(Tortoise), typeid(QuestionBlock))] = &MovingBrick; + + // ----------- Object Collisions ---------- + phm[Key(typeid(SuperMushroom), typeid(QuestionBlock))] = &MovingBrick; + phm[Key(typeid(SuperMushroom), typeid(Brick))] = &MovingBrick; + phm[Key(typeid(QuestionBlock), typeid(SuperMushroom))] = &questionBlockSupMush; + phm[Key(typeid(Coin), typeid(QuestionBlock))] = &questionBlockCoin; + + // ----------- Player Collisions ---------- + phm[Key(typeid(Player), typeid(Brick))] = &MovingBrick; + phm[Key(typeid(Player), typeid(Platforms))] = &playerPlatforms; + phm[Key(typeid(Player), typeid(Tortoise))] = &playerTortoise; + phm[Key(typeid(Player), typeid(SuperMushroom))] = &playerSupermushroom; + phm[Key(typeid(Player), typeid(BadMushroom))] = &playerBadMushroomOrFly; + phm[Key(typeid(Player), typeid(PiranaPlants))] = &playerPiranaPlants; + phm[Key(typeid(Player), typeid(FlyingTortoise))] = &playerBadMushroomOrFly; + phm[Key(typeid(Player), typeid(FireBall))] = &playerFireBallPole; + phm[Key(typeid(Player), typeid(FirePole))] = &playerFireBallPole; + phm[Key(typeid(Player), typeid(QuestionBlock))] = &PlayerQuestionBlock; + phm[Key(typeid(Player), typeid(Coin))] = &PlayerCoin; + + // ----------- Fireworks Collisions ---------- + phm[Key(typeid(Fireworks), typeid(BadMushroom))] = &fireworksEnemy; + phm[Key(typeid(Fireworks), typeid(PiranaPlants))] = &fireworksEnemy; + phm[Key(typeid(Fireworks), typeid(FlyingTortoise))] = &fireworksEnemy; + phm[Key(typeid(Fireworks), typeid(Tortoise))] = &fireworksEnemy; + + phm[Key(typeid(Fireworks), typeid(Brick))] = &fireworksObj; + phm[Key(typeid(Fireworks), typeid(QuestionBlock))] = &fireworksObj; + phm[Key(typeid(Fireworks), typeid(Platforms))] = &fireworksObj; + + return phm; +} + +//----------------------------------------------------------------------------- +HitMapStatic Collision::initializeStaticCollision() +{ + HitMapStatic phm; + + // ----------- Enemy Collisions --------- + phm[Key(typeid(BadMushroom), typeid(Floor))] = &EnemyStatic; + phm[Key(typeid(BadMushroom), typeid(Pipe))] = &EnemyStatic; + phm[Key(typeid(BadMushroom), typeid(Block))] = &EnemyStatic; + phm[Key(typeid(Tortoise), typeid(Floor))] = &EnemyStatic; + phm[Key(typeid(Tortoise), typeid(Pipe))] = &EnemyStatic; + phm[Key(typeid(Tortoise), typeid(Block))] = &EnemyStatic; + phm[Key(typeid(SuperMushroom), typeid(Block))] = &EnemyStatic; + phm[Key(typeid(SuperMushroom), typeid(Floor))] = &EnemyStatic; + phm[Key(typeid(SuperMushroom), typeid(Pipe))] = &EnemyStatic; + + // ----------- Object Collisions ---------- + phm[Key(typeid(GoalFlag), typeid(GoalPole))] = &FlagPole; + + // ----------- Player Collisions ---------- + phm[Key(typeid(Player), typeid(Pipe))] = &PlayerPipeBlock; + phm[Key(typeid(Player), typeid(Floor))] = &PlayerStaticCollision; + phm[Key(typeid(Player), typeid(Block))] = &PlayerPipeBlock; + phm[Key(typeid(Player), typeid(GoalPole))] = &PlayerPole; + + + // ----------- Fireworks Collisions ---------- + phm[Key(typeid(Fireworks), typeid(Floor))] = &fireworksStaticObj; + phm[Key(typeid(Fireworks), typeid(Pipe))] = &fireworksStaticObj; + phm[Key(typeid(Fireworks), typeid(Block))] = &fireworksStaticObj; + + return phm; +} + +//----------------------------------------------------------------------------- +void fireworksStaticObj(MovingObject& fireworks, StaticObject& staticObj) +{ + if (checkAbove(fireworks, getHeightStatic(fireworks, staticObj))) + fireworks.bump(); + else + fireworks.kill(); +} + +//----------------------------------------------------------------------------- +void fireworksEnemy(MovingObject& fireworks, MovingObject& enemy) +{ + AudioHolder::instance().playSound(AUDIO_KILL); + fireworks.kill(); + enemy.setUniqueKill(); +} + +//----------------------------------------------------------------------------- +void fireworksObj(MovingObject& fireworks, MovingObject& Obj) +{ + if (checkAbove(fireworks, getHeightMoving(fireworks, Obj))) + fireworks.bump(); + else + fireworks.kill(); +} + +//----------------------------------------------------------------------------- +void badMushroomTortoise(MovingObject& badMushroom, + MovingObject& tortoise) +{ + Tortoise& newTortoise = static_cast(tortoise); + + if (newTortoise.getShell() && newTortoise.getJumped()) + badMushroom.setUniqueKill(); + else + { + badMushroom.decideDirection(); + tortoise.decideDirection(); + } +} + +//----------------------------------------------------------------------------- +void tortoiseTortoise(MovingObject& tortoise1, + MovingObject& tortoise2) +{ + Tortoise& newTortoise1 = static_cast(tortoise1); + Tortoise& newTortoise2 = static_cast(tortoise2); + + if (newTortoise1.getShell() && newTortoise2.getShell()|| + !newTortoise1.getShell() && !newTortoise2.getShell()) + { + newTortoise1.decideDirection(); + newTortoise2.decideDirection(); + } + else if (newTortoise1.getShell() && newTortoise1.getJumped() && !newTortoise2.getShell()) + newTortoise2.setUniqueKill(); + else if (!newTortoise1.getShell() && newTortoise2.getJumped() && newTortoise2.getShell()) + newTortoise1.setUniqueKill(); +} + +//----------------------------------------------------------------------------- +void badMushroomBadMushroom(MovingObject& badMushroom1, + MovingObject& badMushroom2) +{ + badMushroom1.decideDirection(); + badMushroom2.decideDirection(); +} + +//----------------------------------------------------------------------------- +void playerPlatforms(MovingObject& player, + MovingObject& platform) +{ + Player& newPlayer = static_cast(player); + // In case the player is by the side of the platform + if (checkAbove(player, getHeightMoving(player, platform))) + newPlayer.elevate(platform); + + // In case the player is under the playform + else if (player.getPos().y - platform.getPos().y > (ICON_SIZE/2 - 2)) + newPlayer.setBrickCond(true); + + // The player is above the platform + else + checkSides(player, true); +} + +//----------------------------------------------------------------------------- +void playerTortoise(MovingObject& player, + MovingObject& tortoise) +{ + if (tortoise.isDead()) + return; + + Player& newPlayer = static_cast(player); + Tortoise& newTortoise = static_cast(tortoise); + + if (std::abs(player.getPos().y - getHeightMoving(player, tortoise)) < TORTOISE_GAP) + { + if (newTortoise.getShell()) // In case the tortoise is closed + { + if (newTortoise.getJumped()) // In case he is closed and moving + newTortoise.setJumped(false); + + else // In case he is closed and static + { + newTortoise.setJumped(true); + newTortoise.setDirection(player.getPos().x); + } + } // In case he was alive, now we close him + else + { + AudioHolder::instance().playSound(AUDIO_BUMP); + newPlayer.addPoints(KILL_POINTS); + newTortoise.setShell(); + } + + newPlayer.bump(); + } + + // In case we hit the Tortoise by his side. + else if (!newTortoise.getShell() || (newTortoise.getShell() && newTortoise.getJumped())) + { + if (newPlayer.isFieryOrSuper()) + newPlayer.transformMario(); + + else if (!newPlayer.isInvincible()) + { + newPlayer.kill(); + newPlayer.decLife(); + } + } +} + +//----------------------------------------------------------------------------- +void playerSupermushroom(MovingObject& player, + MovingObject& superMushroom) +{ + SuperMushroom& newSuperMush = static_cast(superMushroom); + + if (newSuperMush.isShouldMove()) + { + Player& newPlayer = static_cast(player); + if (!newPlayer.isFieryOrSuper()) // SuperMushroom + newPlayer.transformSuperMario(); + + else if (!newPlayer.isFiery()) // FireFlower + newPlayer.transformFieryMario(); + superMushroom.setDelete(); + + newPlayer.addPoints(SUPER_POINTS); + AudioHolder::instance().playSound(AUDIO_SUPER); + } +} + +//----------------------------------------------------------------------------- +void playerBadMushroomOrFly(MovingObject& player, + MovingObject& badMushroom) +{ + if (badMushroom.isDead()) + return; + + Player& newPlayer = static_cast(player); + if (badMushroom.isDead() || newPlayer.isInvincible()) + return; + + // In case we jumped over the mushroom. + if (std::abs(player.getPos().y - getHeightMoving(player, badMushroom)) < MUSHROOM_GAP) + { + badMushroom.kill(); + newPlayer.bump(); + newPlayer.addPoints(KILL_POINTS); + AudioHolder::instance().playSound(AUDIO_BUMP); + } + + // In case the mushroom hit us. + else if (newPlayer.isFieryOrSuper()) + newPlayer.transformMario(); + + else + { + newPlayer.kill(); + newPlayer.decLife(); + } +} + +//----------------------------------------------------------------------------- +void playerPiranaPlants(MovingObject& player, + MovingObject& PiranaPlants) +{ + Player& newPlayer = static_cast(player); + + if (newPlayer.isFieryOrSuper()) + newPlayer.transformMario(); + + else if (!newPlayer.isInvincible()) + { + newPlayer.kill(); + newPlayer.decLife(); + } +} + +//----------------------------------------------------------------------------- +void playerFireBallPole(MovingObject& player, + MovingObject& FireBall) +{ + Player& newPlayer = static_cast(player); + sf::Vector2f bottomLeft, bottomRight, middlePoint; + + // Calling the function to calculate where the obstacle is. + InitializePoints(FireBall.draw(), bottomLeft, bottomRight, middlePoint); + + if (player.draw().getGlobalBounds().contains(bottomLeft)|| + player.draw().getGlobalBounds().contains(bottomRight)|| + player.draw().getGlobalBounds().contains(middlePoint)) + { + if (newPlayer.isFieryOrSuper()) + newPlayer.transformMario(); + else if (!newPlayer.isInvincible()) + { + newPlayer.kill(); + newPlayer.decLife(); + } + } +} + +//----------------------------------------------------------------------------- +// The questionBlock will hold mario's state to know what to pull out. +void PlayerQuestionBlock(MovingObject& player, + MovingObject& questionBlock) +{ + QuestionBlock& newquestionBlock = static_cast(questionBlock); + if (checkBeneath(player, questionBlock) && !newquestionBlock.isOpen()) + { + if (questionBlock.draw().getGlobalBounds().contains(player.getPos().x + ICON_SIZE / 2, player.getPos().y)) + { + Player& newPlayer = static_cast(player); + newquestionBlock.squareBump(); + newquestionBlock.setOpen(newPlayer.isFieryOrSuper()); + AudioHolder::instance().playSound(AUDIO_BUMP); + } + } + else if(!checkAbove(player,getHeightMoving(player,questionBlock))) + checkSides(player,true); +} + +//----------------------------------------------------------------------------- +void PlayerCoin(MovingObject& player, + MovingObject& coin) +{ + Coin& newCoin = static_cast(coin); + if (!newCoin.getTaken()) + { + Player& newPlayer = static_cast(player); + newCoin.setTaken(); + newPlayer.addCoin(); + newPlayer.addPoints(COIN_POINTS); + AudioHolder::instance().playSound(AUDIO_COIN); + } +} + +//----------------------------------------------------------------------------- +// Telling the supermushroom which object to pull out. +void questionBlockSupMush(MovingObject& questionBlock, MovingObject& superMushroom) +{ + QuestionBlock& newquestionBlock = static_cast(questionBlock); + SuperMushroom& newSuperMush = static_cast(superMushroom); + if (newquestionBlock.isOpen() && !newSuperMush.isShouldMove() && + questionBlock.draw().getGlobalBounds().contains(newSuperMush.getPos().x + ICON_SIZE / 2, newSuperMush.getPos().y)) + { + newSuperMush.setKind(newquestionBlock.getKind()); + newSuperMush.setShouldMove(); + } +} + +//----------------------------------------------------------------------------- +void questionBlockCoin(MovingObject& coin, MovingObject& questionBlock) +{ + QuestionBlock& newquestionBlock = static_cast(questionBlock); + Coin& newCoin = static_cast(coin); + if (newquestionBlock.isOpen() && !newCoin.getTaken()) + { + newCoin.setTaken(); + newCoin.addGatheredPoints(COIN_POINTS); + AudioHolder::instance().playSound(AUDIO_COIN); + } +} + +//------------------------- Moving and Static Functions ----------------------- + +//----------------------------------------------------------------------------- +void FlagPole(MovingObject& flag, StaticObject& pole) +{ + GoalPole& newPole = static_cast(pole); + if (newPole.isPlayerReached()) // If the player reached the pole, the flag will go down. + { + GoalFlag& newFlag = static_cast(flag); + newFlag.setShouldMove(); + } +} + +//----------------------------------------------------------------------------- +void PlayerPole(MovingObject& player, StaticObject& pole) +{ + if (player.draw().getGlobalBounds().contains(pole.getPos().x + ICON_SIZE*2, player.getPos().y)) + { + Player& newPlayer = static_cast(player); + GoalPole& newPole = static_cast(pole); + newPlayer.setPoleDown(); + newPole.setPlayerReached(); + } +} + +//----------------------------------------------------------------------------- +void EnemyStatic(MovingObject& enemy, + StaticObject& staticObj) +{ + if (!enemy.isShouldMove()) + return; + + if (!checkAbove(enemy, getHeightStatic(enemy, staticObj))) + enemy.decideDirection(); +} + +//----------------------------------------------------------------------------- +void PlayerPipeBlock(MovingObject& player, + StaticObject& obj) +{ + bool condition; + + // We are above the Pipe + condition = checkAbove(player, getHeightStatic(player, obj)); + + // We are by the side of the Pipe + if (!condition) + checkSides(player, true); +} + +//----------------------------------------------------------------------------- +void PlayerFloor(MovingObject& player, + StaticObject& floor) +{ + player.setGrounded(); +} + +//----------------------------------------------------------------------------- +void MovingBrick(MovingObject& movable, MovingObject& brick) +{ + if (movable.isDead()) + return; + + // In case there is an enemy above the brick we can kill it. + if (brick.getDirectionVec().y < 0 && movable.getPos().y < brick.getPos().y) + { + movable.setUniqueKill(); + if (movable.getDirectionVec().x > 0) + movable.setDirection(LEFT); + else + movable.setDirection(RIGHT); + movable.elevate(brick); + } + + bool condition = checkBeneath(movable, brick); + int neededheight = getHeightMoving(movable, brick); + + if (condition && + brick.draw().getGlobalBounds().contains(movable.getPos().x + ICON_SIZE / 2, movable.getPos().y)) + brick.squareBump(); + + if (!condition) + condition = checkAbove(movable, neededheight); + + if (!condition) + checkSides(movable, false); +} +//----------------------------------------------------------------------------- +void PlayerStaticCollision(MovingObject& player, + StaticObject& staticObj) +{ + int neededheight = getHeightStatic(player, staticObj); + if(!checkAbove(player, neededheight)) + checkSides(player, false); +} + +//----------------------------------------------------------------------------- +int getHeightStatic(MovingObject& player, StaticObject& staticObj) +{ + return staticObj.getPos().y - player.draw().getScale().y * player.draw().getTexture()->getSize().y; +} + +//----------------------------------------------------------------------------- +int getHeightMoving(MovingObject& player, MovingObject& Obj) +{ + return Obj.getPos().y - player.draw().getScale().y * player.draw().getTexture()->getSize().y; +} + +//----------------------------------------------------------------------------- +bool checkAbove(MovingObject& player, int neededHeight) +{ + if (std::abs(player.getPos().y - neededHeight) < STATIC_GAP) + { + player.setGrounded(); + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +bool checkBeneath(MovingObject& player, MovingObject& staticObj) +{ + if (player.getPos().y - staticObj.getPos().y > (ICON_SIZE - GAP_BENEATH)) + { + Player& newPlayer = static_cast(player); + newPlayer.setBrickCond(true); + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +void checkSides(MovingObject& player, bool condition) +{ + Player& newPlayer = static_cast(player); + newPlayer.resetVelocity(condition); +} + +//----------------------------------------------------------------------------- +void InitializePoints(sf::Sprite rect,sf::Vector2f& bottomLeft, + sf::Vector2f& bottomRight, sf::Vector2f& middlePoint) +{ + sf::Vector2f topLeft = rect.getTransform().transformPoint(sf::Vector2f(0, 0)); + sf::Vector2f topRight = rect.getTransform().transformPoint(sf::Vector2f(rect.getTexture()->getSize().x, 0)); + bottomLeft = rect.getTransform().transformPoint(sf::Vector2f(0, rect.getTexture()->getSize().y)); + bottomRight = rect.getTransform().transformPoint(sf::Vector2f(rect.getTexture()->getSize().x, rect.getTexture()->getSize().y)); + middlePoint.x = (topRight.x + bottomRight.x) / 2; + middlePoint.y = (topRight.y + bottomRight.y) / 2; +} + +//----------------------------------------------------------------------------- +Collision::~Collision() +{ +} + + diff --git a/src/GameHandlers/Controller.cpp b/src/GameHandlers/Controller.cpp new file mode 100644 index 0000000..0123ad0 --- /dev/null +++ b/src/GameHandlers/Controller.cpp @@ -0,0 +1,199 @@ +#include "Controller.h" + +Controller::Controller() : m_startOver(true) +{ + TextureHolder::instance(); + AudioHolder::instance(); + + std::fstream leaderBoard("leaderboard.txt", std::ios::app); + if (!leaderBoard.is_open()) + throw std::exception("File couldn't open\n"); + leaderBoard.close(); +} + +//----------------------------------------------------------------------------- +void Controller::startMenu() +{ + m_startOver = true; + while(m_window.isWindowOpen()) + switch (m_window.openMenu()) + { + case START: startGame(); break; + case QUIT: exitGame(); break; + case LEADER_BOARD: openLeaderBoard(); break; + } +} + +//----------------------------------------------------------------------------- +void Controller :: startGame() +{ + sf::Clock clock; + sf::Time deltaTime; + float timeRemained; + bool playerDied = false, + finishedGame = false, + paused = false, + spacePressed = true; + + int world = 1, + score = 0, + coins = 0, + originalScore, + originalCoins, + life = START_LIFE, + condition = 0; + + while(m_window.isWindowOpen() && life > 0) // The game Loop + { + handleObjectCreation(condition, world, finishedGame, playerDied); + + if (finishedGame) + break; + + m_startOver = false; + timeRemained = STAGE_TIME; + originalScore = score; + originalCoins = coins; + m_board.createPlayer(life, coins, score, condition); + m_window.setBGStage(world); + playerDied = false; + + while (gameConditions(playerDied)) // The Stage Loop + { + deltaTime = clock.restart(); + if (!paused) + { + m_board.moveObject(deltaTime); + timeRemained -= deltaTime.asSeconds(); + } + + m_board.getGameData(score, coins, life); + m_window.buildMap(m_board, 0, m_board.WindowLeftBorder()); // Drawing all the objects + m_window.printText(m_board.WindowLeftBorder(), score, coins, world, (int)timeRemained, life); + pause(spacePressed, paused, clock); + + if (outOfTime(timeRemained, playerDied, life)) + break; + if (m_window.isExitPressed()) + return; + } + + if (!playerDied) // In case the user cleared the stage. + { + m_window.messageScreen("STAGE CLEARED",SLEEP); + score += (int)timeRemained; + world++; + } + else // In case the user lost the stage. + { + score = originalScore; + coins = originalCoins; + } + } + + handleEndGame(score, finishedGame); + startMenu(); +} + +//----------------------------------------------------------------------------- +void Controller::handleLeaderBoard(int score) +{ + std::fstream leaderBoard("leaderboard.txt", std::ios::app); + if (!leaderBoard.is_open()) + throw std::exception("File couldn't open\n"); + + leaderBoard << score << std::endl; + leaderBoard.close(); +} + +//----------------------------------------------------------------------------- +void Controller::handleEndGame(int score, bool finishedGame) +{ + AudioHolder::instance().stopBGSound(); + if (finishedGame) + { + AudioHolder::instance().playSound(AUDIO_WON); + m_window.messageScreen("YOU WON, YOUR SCORE IS: " + std::to_string(score), SLEEP); + } + + else + { + AudioHolder::instance().playSound(AUDIO_LOST); + m_window.messageScreen("YOU LOST, YOUR SCORE IS: " + std::to_string(score), SLEEP); + } + handleLeaderBoard(score); +} + +//----------------------------------------------------------------------------- +bool Controller::outOfTime(float timeRemained, bool& playerDied, int& life) +{ + if (timeRemained < 0) + { + playerDied = true; + life--; + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +// This function is used to pause the game +void Controller::pause(bool& spacePressed, bool& paused, sf::Clock& clock) +{ + if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space)) + spacePressed = false; + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space) && !spacePressed) + { + spacePressed = true; + paused = !paused; + AudioHolder::instance().playSound(AUDIO_PAUSE); + clock.restart(); + + if (paused) + AudioHolder::instance().stopBGSound(); + else + AudioHolder::instance().playSound(AUDIO_BACKGROUND); + } +} + +//----------------------------------------------------------------------------- +bool Controller::gameConditions(bool & playerDied) const +{ + return ((m_window.isWindowOpen() && + !(playerDied = m_board.isPlayerDead())) && + !m_board.isStageCleared()); +} + +//----------------------------------------------------------------------------- +void Controller::handleObjectCreation(int &condition,int world, + bool &finishedGame, bool playerDied) +{ + condition = m_board.restartStage(); + if (m_startOver) + condition = 0; + + if ((world == 1 && !playerDied) || m_board.isStageCleared()) + finishedGame = m_board.readMap(m_startOver); + else + m_board.createObjects(); + + AudioHolder::instance().playSound(AUDIO_BACKGROUND); +} + +//----------------------------------------------------------------------------- +void Controller :: exitGame() +{ + m_window.finishScreen(); +} + +//----------------------------------------------------------------------------- +void Controller ::openLeaderBoard() +{ + m_window.leaderBoard(); + startMenu(); +} + +//----------------------------------------------------------------------------- +Controller::~Controller() +{ +} diff --git a/src/GameHandlers/GameObject.cpp b/src/GameHandlers/GameObject.cpp new file mode 100644 index 0000000..9602b7b --- /dev/null +++ b/src/GameHandlers/GameObject.cpp @@ -0,0 +1,40 @@ +#include "GameObject.h" + +GameObject::GameObject(int row, int col): m_delete(false),m_firePole(false) +{ + m_sprite.setScale(SCALE, SCALE); + m_sprite.setPosition((float)(col * ICON_SIZE), (float)((row * ICON_SIZE))); +} + +//----------------------------------------------------------------------------- +const sf::Sprite& GameObject::draw() const +{ + return m_sprite; +} + +//----------------------------------------------------------------------------- +bool GameObject::isDelete() const +{ + return m_delete; +} + +//----------------------------------------------------------------------------- +void GameObject::setDelete() +{ + m_delete = true; +} + +//----------------------------------------------------------------------------- +sf::Vector2f GameObject::getPos() const +{ + return m_sprite.getPosition(); +} + +//----------------------------------------------------------------------------- +bool GameObject::isFirePole() const +{ + return m_firePole; +} + + + diff --git a/src/GameHandlers/GameWindow.cpp b/src/GameHandlers/GameWindow.cpp new file mode 100644 index 0000000..8995e6e --- /dev/null +++ b/src/GameHandlers/GameWindow.cpp @@ -0,0 +1,292 @@ +#include "GameWindow.h" + +GameWindow::GameWindow() : + m_window(sf::VideoMode(WIDTH,HEIGHT), "Super Mario Bros. 1",sf::Style::Close) +{ + sf::Vector2i windowPos ((sf::VideoMode::getDesktopMode().width / 2 - m_window.getSize().x / 2), + (sf::VideoMode::getDesktopMode().height / 2 - m_window.getSize().y / 2 - WINDOW_GAP)); + m_window.setPosition(windowPos); + initializeText(); + initializeScore(); +} + +//----------------------------------------------------------------------------- +int GameWindow::openMenu() +{ + m_window.setView(m_window.getDefaultView()); // getting the view back to normal + m_window.clear(); + m_background.setTexture(TextureHolder::instance().getScreen(I_MENU_SCREEN)); + m_window.draw(m_background); + + for (const auto text : m_menuText) + m_window.draw(text); + + m_window.display(); + + return runMenu(); +} + +//----------------------------------------------------------------------------- +void GameWindow::buildMap(const Board& board, int timeRemained, float leftBorder) +{ + int index_moving = 0, index_static = 0; + bool moving = true, statics = true, firePoles = true, firstTime = true; + sf::Sprite temp; + + m_window.clear(); + m_window.draw(m_background); + + // Printing the sprites until we have finished the moving and statics. + while (moving || statics || firePoles) + { + temp = board.drawToWindow(index_moving, index_static, moving, statics, firePoles); + m_window.draw(temp); + + if (!moving && firstTime) + { + index_moving = 0; + firstTime = false; + } + } + + // Fixing the view by the player direction + sf::View view = sf::View(sf::FloatRect(leftBorder, 0, VIEW_WIDTH, VIEW_HEIGHT)); + m_window.setView(view); +} + +//----------------------------------------------------------------------------- +void GameWindow::printText(float leftBorder, int score, int coins, int world, int time, int life) +{ + m_message[SCORE].setPosition(SCORES_X + leftBorder, GAME_Y); + m_message[SCORE].setString("SCORE: " + std::to_string(score)); + + m_message[COINS].setPosition(COINS_X + leftBorder, GAME_Y); + m_message[COINS].setString("COINS: " + std::to_string(coins)); + + m_message[WORLD].setPosition(WORLD_X + leftBorder, GAME_Y); + m_message[WORLD].setString("WORLD: " + std::to_string(world)); + + m_message[TIME].setPosition(TIME_X + leftBorder, GAME_Y); + m_message[TIME].setString("TIME: " + std::to_string(time)); + + m_message[LIFE].setPosition(LIFE_X + leftBorder, GAME_Y); + m_message[LIFE].setString("LIFE: " + std::to_string(life)); + + for (auto message : m_message) + m_window.draw(message); + + m_window.display(); +} + +//----------------------------------------------------------------------------- +// Setting the background image based on stage. +void GameWindow:: setBGStage(const int stage) +{ + m_background.setTexture(TextureHolder::instance().getLevel(stage-1)); + + sf::View view = sf::View(sf::FloatRect(0, 0, VIEW_WIDTH, VIEW_HEIGHT)); + m_window.setView(view); +} + +//----------------------------------------------------------------------------- +int GameWindow::runMenu() +{ + int action = NONE; + while (m_window.isOpen()) + { + sf::Event event; + while (m_window.pollEvent(event)) + { + switch (event.type) + { + case sf::Event::Closed: + m_window.close(); + break; + + case sf::Event::MouseButtonReleased: + action = buttonPressed(event); + + if (action != NONE) + return action; + } + } + } + return QUIT; +} + +//----------------------------------------------------------------------------- +int GameWindow::buttonPressed(sf::Event event) const +{ + auto location = m_window.mapPixelToCoords({ event.mouseButton.x,event.mouseButton.y }); + + if (m_menuText[START].getGlobalBounds().contains(location)) + return START; + + if (m_menuText[QUIT].getGlobalBounds().contains(location)) + return QUIT; + + if (m_menuText[LEADER_BOARD].getGlobalBounds().contains(location)) + return LEADER_BOARD; + + if (m_leaderText[LEADERS-1].getGlobalBounds().contains(location)) + return BACK; + + return NONE; +} + +//----------------------------------------------------------------------------- +void GameWindow::initializeText() +{ + m_font.loadFromFile("Fixedsys500c.ttf"); + + for (auto& message : m_menuText) + { + message.setFont(m_font); + message.setColor(sf::Color::White); + message.setOutlineColor(sf::Color::Black); + message.setOutlineThickness(THICKNESS); + message.setCharacterSize(FONT_SIZE); + } + + for (auto& message : m_message) + { + message.setFont(m_font); + message.setColor(sf::Color::White); + message.setCharacterSize(GAME_FONT_SIZE); + } + + initializeMenuText(); +} + +//----------------------------------------------------------------------------- +void GameWindow::initializeMenuText() +{ + m_menuText[START].setString("START GAME"); + m_menuText[START].setPosition(START_X, START_Y); + + m_menuText[LEADER_BOARD].setString("SCORE"); + m_menuText[LEADER_BOARD].setPosition(SCORE_X, SCORE_Y); + + m_menuText[QUIT].setString("EXIT"); + m_menuText[QUIT].setPosition(EXIT_X, EXIT_Y); + + m_finishText.setFont(m_font); + m_finishText.setColor(sf::Color::White); + m_finishText.setCharacterSize(FONT_SIZE); + m_finishText.setPosition(EXIT_X, EXIT_Y); +} + +//----------------------------------------------------------------------------- +void GameWindow::finishScreen() +{ + messageScreen("BYE BYE!",EXIT_SLEEP); + m_window.close(); +} + +//----------------------------------------------------------------------------- +bool GameWindow::isExitPressed() +{ + sf::Event event; + while (m_window.pollEvent(event)) + { + switch (event.type) + { + case sf::Event::Closed: + finishScreen(); + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- +void GameWindow::messageScreen(std::string message, int sleep) +{ + m_window.clear(); + m_window.setView(m_window.getDefaultView()); + m_background.setTexture(TextureHolder::instance().getScreen(I_QUIT_SCREEN)); + m_finishText.setString(message); + m_window.draw(m_background); + m_window.draw(m_finishText); + m_window.display(); + + std::this_thread::sleep_for(std::chrono::seconds(sleep)); // Freezing the screen + m_background.setScale(1, 1); +} + +//----------------------------------------------------------------------------- +// This function handles the leaderBoard +void GameWindow::leaderBoard() +{ + m_window.clear(); + readFromFile(); // Reading the scores from file + m_background.setTexture(TextureHolder::instance().getScreen(I_LEADERBOARD_SCREEN)); + m_background.setScale(1, 1); + m_window.draw(m_background); + + for (int i = 0; i < LEADERS -1 && i < m_leaderVec.size(); i++) + { + m_leaderText[i].setFont(m_font); + m_leaderText[i].setColor(sf::Color::White); + m_leaderText[i].setCharacterSize(FONT_SIZE); + m_leaderText[i].setString(std::to_string(i + 1) + ". " + std::to_string(m_leaderVec[i])); + m_window.draw(m_leaderText[i]); + } + + m_window.draw(m_leaderText[LEADERS - 1]); + m_window.display(); + runMenu(); +} + +//----------------------------------------------------------------------------- +void GameWindow::initializeScore() +{ + for (int i = 0; i < LEADERS; i++) + { + m_leaderText[i].setFont(m_font); + m_leaderText[i].setColor(sf::Color::White); + m_leaderText[i].setCharacterSize(FONT_SIZE); + m_leaderText[i].setPosition(LEADER_X, LEADER_Y + i * LEADER_GAP); + + if (i == LEADERS - 1) + { + m_leaderText[i].setString("BACK"); + m_leaderText[i].setPosition(10, 10); + } + } +} + +//----------------------------------------------------------------------------- +void GameWindow::readFromFile() +{ + std::fstream leaderBoard("leaderboard.txt"); + if (!leaderBoard.is_open()) + throw std::exception("File couldn't open\n"); + + m_leaderVec.clear(); + auto line = std::string(); + while (leaderBoard.peek() != NONE) + { + std::getline(leaderBoard, line); + m_leaderVec.push_back(std::stoi(line)); + } + leaderBoard.close(); + std::sort(m_leaderVec.begin(), m_leaderVec.end(), std::greater()); +} + +//----------------------------------------------------------------------------- +bool GameWindow::isWindowOpen() const +{ + return (m_window.isOpen()); +} + +//----------------------------------------------------------------------------- +void GameWindow::closeWindow() +{ + m_window.close(); +} + +//----------------------------------------------------------------------------- +GameWindow::~GameWindow() +{ +} diff --git a/src/MovingObjects/Animation.cpp b/src/MovingObjects/Animation.cpp new file mode 100644 index 0000000..d21b765 --- /dev/null +++ b/src/MovingObjects/Animation.cpp @@ -0,0 +1,162 @@ +#include "Animation.h" + +Animation::Animation(const sf::Texture& data, bool dir, sf::Sprite& sprite, int size) + : m_data(data), m_dir(dir), m_sprite(sprite),m_size(size), m_totalTime(0),m_current(0) +{ + initializeTexture(size); + m_sprite.setTexture(data); +} + +//----------------------------------------------------------------------------- +// This function is used to shift between the different sprites that +// an object have. +void Animation::staticShift(sf::Time deltaTime, float switchTime) +{ + m_totalTime += deltaTime.asSeconds(); // Counting the time passed into a member. + if (m_totalTime > switchTime) // Inc case the time is larger then SwitchTime + { // We change the sprite. + m_totalTime -= switchTime; + m_current++; + if (m_current >= m_size - 1) + m_current = 0; + + m_uvRect.left = m_uvRect.width * m_current; // Here we decide which sprite we will take. + m_sprite.setTextureRect(m_uvRect); + } +} + +//----------------------------------------------------------------------------- +// This function flips the sprite to change direction he posing to. +void Animation::setDirection(bool Direction) +{ + if (Direction) + { + m_uvRect.left = m_current * m_uvRect.width; + m_uvRect.width = std::abs(m_uvRect.width); + } + else + { + m_uvRect.left = (m_current+1) * std::abs(m_uvRect.width); + m_uvRect.width = -std::abs(m_uvRect.width); + } + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +void Animation::initializeTexture(int size) +{ + m_size = size; + m_uvRect.width = (m_data.getSize().x) / m_size; + m_uvRect.height = m_data.getSize().y; + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +void Animation::changeMarioTexture(const sf::Texture& data, int size) +{ + m_data = data; + m_sprite.setTexture(data); + initializeTexture(size); +} + +//----------------------------------------------------------------------------- +// This function only handles the player sprite. +void Animation::updatePlayer(bool direction,bool standing, bool fire, + bool inAir, bool duck, float velocity, sf::Time deltaTime) +{ + if (fire) // Player shoots + { + fireFunc(); + return; + } + if (duck) // Player Ducking + { + duckFunc(); + return; + } + if (standing && !inAir) // Player Standing + { + standFunc(); + return; + } + + m_totalTime += deltaTime.asSeconds(); + + if (inAir) // Player Jumping + m_current = PLAYER_JUMP; + + + // Player slipping + else if (direction == LEFT && velocity > 0 || + direction == RIGHT && velocity < 0) + m_current = PLAYER_SLIP; + + // Player Walking + else if (m_totalTime > SWITCH) + { + m_totalTime -= SWITCH; + m_current++; + + if (m_current > PLAYER_WALK_END) + m_current = PLAYER_WALK_FIRST; + } + + m_uvRect.left = m_uvRect.width * m_current; + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +void Animation::duckFunc() +{ + m_current = PLAYER_D; + m_uvRect.height /= 2; + m_uvRect.left = m_uvRect.width * m_current; + m_sprite.setTextureRect(m_uvRect); + m_uvRect.height *= 2; +} + +//----------------------------------------------------------------------------- +void Animation::fireFunc() +{ + m_current = PLAYER_FIRE; + m_uvRect.left = m_uvRect.width * m_current; + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +void Animation::standFunc() +{ + m_current = PLAYER_STAND; + m_uvRect.left = m_uvRect.width * m_current; + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +void Animation::setDeadSprite() +{ + setDirection(LEFT); + m_uvRect.left = std::abs(m_uvRect.width) * m_size; + m_sprite.setTextureRect(m_uvRect); +} + +//----------------------------------------------------------------------------- +// This function Handle the animation of a flag going down. +void Animation::pullingFlag(sf::Time deltaTime) +{ + m_totalTime += deltaTime.asSeconds(); + if (m_totalTime > SWITCH) + { + m_totalTime -= SWITCH; + m_current++; + if (m_current > PULLING_PIC+1) + m_current = PULLING_PIC; + + m_uvRect.left = m_uvRect.width * m_current; + m_sprite.setTextureRect(m_uvRect); + } +} + +//----------------------------------------------------------------------------- +Animation::~Animation() +{ +} \ No newline at end of file diff --git a/src/MovingObjects/Fireworks.cpp b/src/MovingObjects/Fireworks.cpp new file mode 100644 index 0000000..04a0187 --- /dev/null +++ b/src/MovingObjects/Fireworks.cpp @@ -0,0 +1,39 @@ +#include "Fireworks.h" + +Fireworks::Fireworks(sf::Vector2f playerPos, bool direction): + MovingObject(TextureHolder::instance().getTextures(FIREWORKS), direction, FIRE_SIZE,0,0) +{ + if (direction) + m_sprite.setPosition(playerPos.x + ICON_SIZE, playerPos.y + FIREWORK_Y_POS); + else + m_sprite.setPosition(playerPos.x, playerPos.y + FIREWORK_Y_POS); + + m_dir = direction; +} + +//----------------------------------------------------------------------------- +// Special move making the firework bump +void Fireworks::move(sf::Time deltaTime) +{ + if (m_dead) + { + m_deathTimePassed += deltaTime.asSeconds(); + + if (m_deathTimePassed > SWITCH) + m_delete = true; + return; + } + + m_velocity.x = FIREWORKS_SPEED * deltaTime.asSeconds(); + if (!m_dir) + m_velocity.x *= -1; + + fall(deltaTime); + m_sprite.move(m_velocity); +} + +//----------------------------------------------------------------------------- +Fireworks::~Fireworks() +{ +} + diff --git a/src/MovingObjects/MovingObject.cpp b/src/MovingObjects/MovingObject.cpp new file mode 100644 index 0000000..98dd0ce --- /dev/null +++ b/src/MovingObjects/MovingObject.cpp @@ -0,0 +1,266 @@ +#include "MovingObject.h" + +MovingObject::MovingObject(const sf::Texture& data, bool dir, int size, int row, int col): m_gatheredPoints(0), + GameObject(row, col), m_animation(data, dir, m_sprite, size), m_dir(dir), m_dead(false), m_deathTimePassed(0) + , m_directionChange(0), m_air(true), m_velocity(0,0), m_shouldMove(true), m_tortoiseKill(false) +{ +} + +//----------------------------------------------------------------------------- +// This function is being used for tortoise and BadMushroom +void MovingObject::sideMove(sf::Time deltaTime, float speed) +{ + if (m_sprite.getPosition().y > m_lastPos.y) + { + m_lastPos = m_sprite.getPosition(); + return; + } + + m_velocity = sf::Vector2f(0, 0); + m_directionChange += deltaTime.asSeconds(); + + switch (m_dir) + { + case RIGHT: + goRight(); + break; + + case LEFT: + goLeft(); + break; + } + + if (m_air) + m_velocity.y = TOP_FALL_SPEED * deltaTime.asSeconds(); + + m_velocity.x *= speed * deltaTime.asSeconds(); + m_sprite.move(m_velocity); + + m_lastPos = m_sprite.getPosition(); +} + +//----------------------------------------------------------------------------- +// This function is used by flying tortoise and playform. +void MovingObject::upDownMove(sf::Time deltaTime, float speed, int top, int bottom, float switchTime) +{ + switch (m_dir) + { + case UP: + goUp(); + break; + + case DOWN: + goDown(); + break; + } + + m_animation.staticShift(deltaTime, switchTime); + m_velocity.y *= speed * deltaTime.asSeconds(); + m_sprite.move(m_velocity); + + // Switching directions + if (m_sprite.getPosition().y > bottom) + m_dir = UP; + else if (m_sprite.getPosition().y < top) + m_dir = DOWN; +} + +//----------------------------------------------------------------------------- +void MovingObject::decideDirection() +{ + if (m_directionChange > CHANGE_DIR_TIME) + { + if (m_dir == RIGHT) + m_dir = LEFT; + else + m_dir = RIGHT; + + m_directionChange = 0; + } +} + +//----------------------------------------------------------------------------- +// This function is used when totrtoise kiil an enemy, +// there is a different way to die. +void MovingObject::handleDeathTortoise(sf::Time deltaTime) +{ + if (m_deathTimePassed == 0) + { + m_velocity.y = BUMP; + m_sprite.setRotation(FLIP); + } + + m_deathTimePassed += deltaTime.asSeconds(); + + if (m_deathTimePassed > SWITCH) + fall(deltaTime); + + m_sprite.move(m_velocity); +} +//----------------------------------------------------------------------------- +// This function helps collect points within indirect kill +void MovingObject::setUniqueKill() +{ + m_tortoiseKill = true; + m_dead = true; + m_gatheredPoints = KILL_POINTS; + AudioHolder::instance().playSound(AUDIO_KILL); +} + +//----------------------------------------------------------------------------- +// The function pull the bricks down when being bumped, so as the coins +// and question block +void MovingObject::squareMove(sf::Time deltaTime) +{ + m_animation.staticShift(deltaTime, SWITCH); + if (std::abs(getPos().y - m_lastPos.y) > BRICK_GAP) + { + m_velocity.y += deltaTime.asSeconds(); + if (m_velocity.y > TOP_FALL_SPEED * deltaTime.asSeconds()) + m_velocity.y = TOP_FALL_SPEED * deltaTime.asSeconds(); + + m_sprite.move(m_velocity); + } + else if (m_velocity.y != 0) + { + m_velocity.y = 0; + m_sprite.setPosition(m_lastPos); + m_shouldMove = false; + } +} + +//----------------------------------------------------------------------------- +void MovingObject::fall(sf::Time deltaTime) +{ + m_velocity.y += FALLING_VEL * deltaTime.asSeconds(); + if (m_velocity.y > TOP_FALL_SPEED * deltaTime.asSeconds()) + m_velocity.y = TOP_FALL_SPEED * deltaTime.asSeconds(); +} + +//----------------------------------------------------------------------------- +void MovingObject::handleDeath(sf::Time deltaTime) +{ + m_deathTimePassed += deltaTime.asSeconds(); // Couting time before we delete the object + if (m_deathTimePassed > DEATH_TIME) + setDelete(); +} + +//----------------------------------------------------------------------------- +void MovingObject::squareBump() +{ + m_velocity.y = SQUARE_BUMP; + m_sprite.move(m_velocity); + m_shouldMove = true; +} +//----------------------------------------------------------------------------- +void MovingObject::elevate(const MovingObject& platform) +{ + if (m_velocity.y > 0) + m_velocity.y = 0; + m_sprite.move(platform.getDirectionVec()); +} + +//----------------------------------------------------------------------------- +void MovingObject::addGatheredPoints(int points) +{ + m_gatheredPoints = points; +} + +//----------------------------------------------------------------------------- +void MovingObject::bump() +{ + m_velocity.y = BUMP; +} + +//----------------------------------------------------------------------------- +int MovingObject::getGatheredPoints() const +{ + return m_gatheredPoints; +} + +//----------------------------------------------------------------------------- +void MovingObject::setDirection(bool direction) +{ + m_dir = direction; +} + +//----------------------------------------------------------------------------- +void MovingObject::setPreviousPos() +{ + m_sprite.setPosition(m_lastPos); +} + +//----------------------------------------------------------------------------- +bool MovingObject::isShouldMove() const +{ + return m_shouldMove; +} + +//----------------------------------------------------------------------------- +void MovingObject::setToAir() +{ + m_air = true; +} + +//----------------------------------------------------------------------------- +void MovingObject::goDown() +{ + m_velocity.y++; +} + +//----------------------------------------------------------------------------- +void MovingObject::goUp() +{ + m_velocity.y--; +} + +//----------------------------------------------------------------------------- +void MovingObject::goRight() +{ + m_velocity.x++; +} + +//----------------------------------------------------------------------------- +void MovingObject::goLeft() +{ + m_velocity.x--; +} + +//----------------------------------------------------------------------------- +void MovingObject::kill() +{ + m_dead = true; + m_animation.setDeadSprite(); +} + +//----------------------------------------------------------------------------- +void MovingObject::setGrounded() +{ + m_air = false; +} + +//----------------------------------------------------------------------------- +bool MovingObject::isDead() const +{ + return m_dead; +} + +//----------------------------------------------------------------------------- +sf::Vector2f MovingObject::getDirectionVec() const +{ + return m_velocity; +} + +//----------------------------------------------------------------------------- +void MovingObject::move(sf::Time deltaTime) +{ +} +//----------------------------------------------------------------------------- +MovingObject::~MovingObject() +{ +} + + + + + diff --git a/src/MovingObjects/Pickable.cpp b/src/MovingObjects/Pickable.cpp new file mode 100644 index 0000000..76d374e --- /dev/null +++ b/src/MovingObjects/Pickable.cpp @@ -0,0 +1,11 @@ +#include "Pickable.h" + +Pickable::Pickable(const sf::Texture& data, bool dir, int size, int row, int col): + MovingObject(data, dir, size, row, col) +{ +} + +//----------------------------------------------------------------------------- +Pickable::~Pickable() +{ +} diff --git a/src/MovingObjects/Platforms.cpp b/src/MovingObjects/Platforms.cpp new file mode 100644 index 0000000..a9a0b9a --- /dev/null +++ b/src/MovingObjects/Platforms.cpp @@ -0,0 +1,18 @@ +#include "Platforms.h" + +Platforms::Platforms(int row, int col) + : MovingObject(TextureHolder::instance().getTextures(PLATFORM), LEFT, 1,row,col) +{ + m_sprite.setScale(PLAT_X_SCALE, PLAT_Y_SCALE); +} + +//----------------------------------------------------------------------------- +void Platforms::move(sf::Time deltaTime) +{ + upDownMove(deltaTime,ENEMY_SPEED,MAX_HEIGHT,MIN_HEIGHT,SWITCH); +} + +//----------------------------------------------------------------------------- +Platforms::~Platforms() +{ +} diff --git a/src/MovingObjects/Player.cpp b/src/MovingObjects/Player.cpp new file mode 100644 index 0000000..0e33ed5 --- /dev/null +++ b/src/MovingObjects/Player.cpp @@ -0,0 +1,464 @@ +#include "Player.h" + +Player::Player(int life, int score, int coins, int condition) : + MovingObject(TextureHolder::instance().getPlayer(I_MARIO), RIGHT, S_MARIO_SIZE, MARIO_LOCATION, 0), + m_stageFinished(false), m_changedDirection(false), m_reachedTop(false), m_startedJump(false), m_duck(false), + m_jumpPressed(false), m_hitBrick(false), m_leftBorder(0), m_fieryMario(false), m_keepDucking(false), m_poleDown(false), + m_life(life), m_hitSideObj(false), m_upKeyReleased(false), m_superMario(false), m_invincible(false), m_jumped(false), + m_startHeight(0), m_invincibleTime(0), m_points(score), m_coins(coins) +{ + if (condition == I_F_MARIO) + transformFieryMario(); + else if (condition == I_S_MARIO) + transformSuperMario(); +} + +//----------------------------------------------------------------------------- +void Player::move(sf::Time deltaTime) +{ + bool standing, falling; + if (getPos().y > VIEW_WIDTH && !m_dead) // The player fell from screen + { + kill(); + decLife(); + } + + if (m_poleDown) // Reached the end of current Stage + { + reachedFlagActions(deltaTime); + return; + } + if (m_dead) // The player have died + { + handleDeath(deltaTime); + return; + } + bool fire = false; + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift) && m_fieryMario) + fire = true; + + standing = (m_lastPos.x == m_sprite.getPosition().x); + m_duck = false || m_keepDucking; + + if (m_changedDirection) + directionChanged(deltaTime); + + moveToSides(deltaTime); + moveUpDown(deltaTime); + handleMovement(); + + falling = m_reachedTop || (!m_startedJump && m_air) || m_hitBrick; + playerCheckFalling(falling, deltaTime); + + m_animation.updatePlayer(m_dir,standing,fire,falling || m_jumpPressed,m_duck, m_velocity.x, deltaTime); + m_animation.setDirection(m_dir); + + varInitialize(); + handleInvincible(deltaTime); +} + +//----------------------------------------------------------------------------- +void Player::makeAMove(const float dir_x, sf::Time deltaTime) +{ + // Limiting the speed. + if (std::abs(m_velocity.x) > (VEL_MAX * deltaTime.asSeconds())) + m_velocity.x = dir_x * VEL_MAX * deltaTime.asSeconds(); + + if (m_velocity.x == 0) // Giving a boost at the start of movement + { + if (m_dir) + m_velocity.x = START_VEL; + else + m_velocity.x = -START_VEL; + } + + else + m_velocity.x += dir_x * ACCELERATION * deltaTime.asSeconds(); +} + +//----------------------------------------------------------------------------- +void Player::decVelocityX(sf::Time deltaTime) +{ + if (std::abs(m_velocity.x) < MIN_DEC) + m_velocity.x = 0; + + // Making the player slip with drag + else + { + if (m_velocity.x > 0) + m_velocity.x -= DRAG * deltaTime.asSeconds(); + else + m_velocity.x += DRAG * deltaTime.asSeconds(); + } + +} + +//----------------------------------------------------------------------------- +// This function is being used to make the player slip when he change directions. +void Player::directionChanged(sf::Time deltaTime) +{ + if (std::abs(m_velocity.x) > MIN_VELOCITY_X) + { + if (m_dir && m_velocity.x < 0) + m_velocity.x += DRAG * deltaTime.asSeconds(); + + else if (!m_dir && m_velocity.x > 0) + m_velocity.x -= DRAG * deltaTime.asSeconds(); + } + else + m_changedDirection = false; +} + +//----------------------------------------------------------------------------- +void Player::reachedFlagActions(sf::Time deltaTime) +{ + int endPos = (isFieryOrSuper() ? SUP_MARIO_END_POS : MARIO_END_POS); // Decide ending position + + if (endPos - getPos().y > ERROR_SPACE) // In case we are above ending position + m_velocity.y = ENEMY_SPEED * deltaTime.asSeconds(); + + else if (getPos().y - endPos > ERROR_SPACE) // In case we are under ending position + m_velocity.y -= ENEMY_SPEED * deltaTime.asSeconds(); + else + m_velocity.y = 0; + + m_sprite.move(m_velocity); + m_animation.pullingFlag(deltaTime); + + m_deathTimePassed += deltaTime.asSeconds(); // Counting the time since he started + if (m_deathTimePassed > PULING_TIME) // pulling the flag down + m_stageFinished = true; +} + +//----------------------------------------------------------------------------- +void Player::handleInvincible(sf::Time deltaTime) +{ + if (m_invincible) // Making the player to flicker if he is invincible + { + m_invincibleTime += deltaTime.asSeconds(); + if (m_sprite.getColor() != sf::Color(255, 255, 255, 100)) + m_sprite.setColor(sf::Color(255, 255, 255, 100)); + else + m_sprite.setColor(sf::Color(255, 255, 255, 255)); + + if (m_invincibleTime > INVINCIBLE_TIME) // If the time for being invincible is passed then stop + { + m_sprite.setColor(sf::Color(255, 255, 255, 255)); + m_invincible = false; + m_invincibleTime = 0; + } + } +} + +//----------------------------------------------------------------------------- +void Player::moveToSides(sf::Time deltaTime) +{ + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left)) //Left + goLeft(deltaTime); + else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right)) //Right + goRight(deltaTime); + else + decVelocityX(deltaTime); // decrease speed +} + +//----------------------------------------------------------------------------- +void Player::moveUpDown(sf::Time deltaTime) +{ + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up) //Jump + && !m_reachedTop && m_upKeyReleased && !m_duck) + { + jump(deltaTime); + + if (m_jumped) + { + AudioHolder::instance().playSound(AUDIO_JUMP); + m_jumped = false; + } + } + + else if (m_jumpPressed) // if we jumped, but stopped pressing the UP key. + m_reachedTop = true; + + else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down) // Duck + && isFieryOrSuper() && !m_air) + m_duck = true; + + if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) + m_upKeyReleased = true; + + if (m_hitBrick) // If we hit a brick reseting out velocity + { + m_velocity.x = 0; + if (m_air) + m_velocity.y = BRICK_BUMP * deltaTime.asSeconds(); + } +} + +//----------------------------------------------------------------------------- +void Player::varInitialize() +{ + m_startedJump = false; + m_hitBrick = false; + m_keepDucking = false; +} + +//----------------------------------------------------------------------------- +void Player::handleMovement() +{ + checkGoLeft(); // Check if player can go left + m_lastPos = m_sprite.getPosition(); // Save the last position + m_sprite.move(m_velocity); + updateLeftBorder(); // Relocating the screen + checkStatusJump(); // Checking if the jump need to be handled +} + +//----------------------------------------------------------------------------- +void Player::playerCheckFalling(bool falling, sf::Time deltaTime) +{ + if (falling) // Apply gravity + { + fall(deltaTime); + m_reachedTop = true; + } + if (!m_air && !m_startedJump) + m_velocity.y = 0; +} + +//----------------------------------------------------------------------------- +void Player::checkStatusJump() +{ + if (m_reachedTop && !m_air) // Finished the entire jump + { + m_reachedTop = false; + m_jumpPressed = false; + m_startedJump = false; + m_upKeyReleased = false; + m_jumped = true; + m_velocity.y = 0; + } + if (m_hitSideObj) + m_hitSideObj = false; + + else if (m_hitBrick && !m_reachedTop) + { + m_velocity.y = START_VEL; + m_reachedTop = true; + } +} + +//----------------------------------------------------------------------------- +void Player::jump(sf::Time deltaTime) +{ + if (!m_jumpPressed) + { + m_velocity.y = JUMP_START; + m_startHeight = m_sprite.getPosition().y; + m_jumpPressed = true; + } + + if (m_startHeight - m_sprite.getPosition().y > HEIGHT_MAX) + m_reachedTop = true; + + // Decreasing the velocity of the jump. + m_velocity.y += JUMP_DEC * deltaTime.asSeconds(); + m_startedJump = true; +} + +//----------------------------------------------------------------------------- +void Player::goRight(sf::Time deltaTime) +{ + if (m_dir == LEFT) + m_changedDirection = true; + + m_dir = RIGHT; + makeAMove(1, deltaTime); +} + +//----------------------------------------------------------------------------- +void Player::goLeft(sf::Time deltaTime) +{ + if (m_dir == RIGHT) + m_changedDirection = true; + + m_dir = LEFT; + makeAMove(-1, deltaTime); +} + +//----------------------------------------------------------------------------- +void Player::checkGoLeft() +{ + if ((m_sprite.getPosition().x <= 0 || + m_leftBorder >= m_sprite.getPosition().x) && + m_velocity.x < 0) + m_velocity.x = 0; +} + +//----------------------------------------------------------------------------- +void Player::handleDeath(sf::Time deltaTime) +{ + // Reseting the velocity + if (m_deathTimePassed == 0) + { + AudioHolder::instance().stopBGSound(); + m_velocity = sf::Vector2f(0, 0); + m_jumpPressed = false; + } + + // Counting the time + m_deathTimePassed += deltaTime.asSeconds(); + + // At start make him jump, if SWITCH time is passed make him fall + if (m_deathTimePassed > SWITCH) + fall(deltaTime); + else + jump(deltaTime); + + m_sprite.move(m_velocity); + + // His death is ended + if (m_deathTimePassed > PLAYER_DEATH_TIME) + setDelete(); +} + +//----------------------------------------------------------------------------- +void Player::updateLeftBorder() +{ + // Update left Border position + if (m_sprite.getPosition().x > VIEW_WIDTH / 2 && + m_sprite.getPosition().x > m_leftBorder + VIEW_WIDTH / 2) + m_leftBorder = m_sprite.getPosition().x - VIEW_WIDTH / 2; +} + +//----------------------------------------------------------------------------- +// This function is being used when the player hit an object from the side +void Player::resetVelocity(bool condition) +{ + if (!m_duck || condition) + { + m_sprite.setPosition(m_lastPos.x, m_sprite.getPosition().y); + m_velocity.x = 0; + m_hitSideObj = true; + } + else if (!condition) + m_keepDucking = true; +} + +//----------------------------------------------------------------------------- +void Player::decLife() +{ + m_fieryMario = false; + m_superMario = false; + m_life--; + AudioHolder::instance().playSound(AUDIO_DEATH); +} + +//----------------------------------------------------------------------------- +void Player::setPoleDown() +{ + m_poleDown = true; + m_velocity.x = 0; +} + +//----------------------------------------------------------------------------- +void Player::transformSuperMario() +{ + m_superMario = true; + m_sprite.setPosition(m_sprite.getPosition().x, m_sprite.getPosition().y - ICON_SIZE); + m_animation.changeMarioTexture(TextureHolder::instance().getPlayer(I_S_MARIO), S_MARIO_SIZE); +} + +//----------------------------------------------------------------------------- +void Player::transformFieryMario() +{ + m_superMario = false; + m_fieryMario = true; + m_sprite.setPosition(m_sprite.getPosition().x, m_sprite.getPosition().y - 3); + m_animation.changeMarioTexture(TextureHolder::instance().getPlayer(I_F_MARIO), F_MARIO_SIZE); +} + +//----------------------------------------------------------------------------- +void Player::transformMario() +{ + m_superMario = false; + m_fieryMario = false; + m_invincible = true; + m_animation.changeMarioTexture(TextureHolder::instance().getPlayer(I_MARIO), S_MARIO_SIZE); +} + +//----------------------------------------------------------------------------- +void Player::setBrickCond(bool condition) +{ + m_hitBrick = condition; +} + +//----------------------------------------------------------------------------- +bool Player::isStageCleared() const +{ + return m_stageFinished; +} + +//----------------------------------------------------------------------------- +bool Player::getDirection() const +{ + return m_dir; +} + +//----------------------------------------------------------------------------- +float Player::getLeftBorder() const +{ + return m_leftBorder; +} + +//----------------------------------------------------------------------------- +bool Player::isFieryOrSuper() const +{ + return m_superMario || m_fieryMario; +} + +//----------------------------------------------------------------------------- +bool Player::isInvincible() const +{ + return m_invincible; +} + +//----------------------------------------------------------------------------- +bool Player::isFiery() const +{ + return m_fieryMario; +} + +//----------------------------------------------------------------------------- +void Player::addPoints(int points) +{ + m_points += points; +} + +//----------------------------------------------------------------------------- +int Player::getPoints() const +{ + return m_points; +} + +//----------------------------------------------------------------------------- +void Player::addCoin() +{ + m_coins++; +} + +//----------------------------------------------------------------------------- +int Player::getCoins() const +{ + return m_coins; +} + +//----------------------------------------------------------------------------- +int Player::getLife() const +{ + return m_life; +} + +//----------------------------------------------------------------------------- +Player::~Player() +{ +} diff --git a/src/MovingObjects/SuperMushroom.cpp b/src/MovingObjects/SuperMushroom.cpp new file mode 100644 index 0000000..27865b3 --- /dev/null +++ b/src/MovingObjects/SuperMushroom.cpp @@ -0,0 +1,55 @@ +#include "SuperMushroom.h" + +SuperMushroom::SuperMushroom(int row, int col) : m_kind(false), m_rising(true), +Pickable(TextureHolder::instance().getTextures(SUPER_MUSH), RIGHT,1, row, col) +{ + m_sprite.setPosition((float)(col * ICON_SIZE), + (float)((row * ICON_SIZE + ICON_SIZE))); + m_lastPos = m_sprite.getPosition(); + m_shouldMove = false; +} + +//----------------------------------------------------------------------------- +void SuperMushroom::move(sf::Time deltaTime) +{ + m_dead = false; + if (std::abs(getPos().y - m_lastPos.y) < ICON_SIZE && m_rising) + { + m_velocity.y = -deltaTime.asSeconds() * ENEMY_SPEED; + m_sprite.move(m_velocity); + } + else if (!m_kind) // SuperMushroom + { + m_lastPos.y = getPos().y; + sideMove(deltaTime, ENEMY_SPEED * FALLING_VEL); + m_rising = false; + } +} + +//----------------------------------------------------------------------------- +void SuperMushroom::setKind(bool kind) +{ + m_kind = kind; + + if (kind) + m_sprite.setTexture(TextureHolder::instance().getTextures(FIRE_FLOWER)); +} + +//----------------------------------------------------------------------------- +bool SuperMushroom::getKind() const +{ + return m_kind; +} + +//----------------------------------------------------------------------------- +void SuperMushroom::setShouldMove() +{ + m_shouldMove = true; + m_velocity.y = -1; + m_sprite.move(m_velocity); +} +//----------------------------------------------------------------------------- +SuperMushroom::~SuperMushroom() +{ +} + diff --git a/src/Obstacles/FireBall.cpp b/src/Obstacles/FireBall.cpp new file mode 100644 index 0000000..65b9b66 --- /dev/null +++ b/src/Obstacles/FireBall.cpp @@ -0,0 +1,45 @@ +#include "FireBall.h" + +const float jumpDeceleration = 0.5f; +const float jumpStart = -0.55f; + +FireBall::FireBall(int row, int col) + : Obstacle(TextureHolder::instance().getTextures(FIRE_BALL), LEFT, 1,row,col) +{ + m_sprite.setOrigin(m_sprite.getTextureRect().width / 2, m_sprite.getTextureRect().height / 2); + m_sprite.setPosition((float)(col * ICON_SIZE), (float)((VIEW_HEIGHT + ICON_SIZE))); + m_sprite.setScale(m_sprite.getScale().x, m_sprite.getScale().y * -1); +} + +//----------------------------------------------------------------------------- +void FireBall::move(sf::Time deltaTime) +{ + + if (getPos().y >= VIEW_HEIGHT + ICON_SIZE) + m_sprite.setPosition(getPos().x, VIEW_HEIGHT + ICON_SIZE); + + if (getPos().y == VIEW_HEIGHT + ICON_SIZE) + m_velocity.y = jumpStart; + + else + m_velocity.y += jumpDeceleration * deltaTime.asSeconds(); + + m_sprite.move(m_velocity); + changeSpriteDirection(); +} + +//----------------------------------------------------------------------------- +void FireBall::changeSpriteDirection() +{ + if (m_velocity.y < 0 && !m_dir || + m_velocity.y > 0 && m_dir) + { + m_sprite.setScale(m_sprite.getScale().x, m_sprite.getScale().y * -1); + m_dir = !m_dir; + } +} + +//----------------------------------------------------------------------------- +FireBall::~FireBall() +{ +} \ No newline at end of file diff --git a/src/Obstacles/FirePole.cpp b/src/Obstacles/FirePole.cpp new file mode 100644 index 0000000..9eb914a --- /dev/null +++ b/src/Obstacles/FirePole.cpp @@ -0,0 +1,22 @@ +#include "FirePole.h" +#include +FirePole::FirePole(int row, int col) + : Obstacle(TextureHolder::instance().getTextures(FIRE_POLE), LEFT, 1,row,col),m_timePassed(0),m_angle(0) +{ + m_sprite.setPosition((float)(col * ICON_SIZE + 7), (float)((row * ICON_SIZE) - ICON_SIZE/1.8)); + m_sprite.setOrigin(m_sprite.getTextureRect().width / 2, m_sprite.getOrigin().y + ICON_SIZE); + m_firePole = true; +} + +//----------------------------------------------------------------------------- +void FirePole::move(sf::Time deltaTime) +{ + m_sprite.rotate(deltaTime.asSeconds() * FIREPOLE_SPEED); + + m_timePassed += deltaTime.asSeconds(); + if (m_timePassed > FIRE_POLE_SWITCH) + { + m_sprite.setScale(m_sprite.getScale().x * -1, m_sprite.getScale().y); + m_timePassed -= SWITCH; + } +} \ No newline at end of file diff --git a/src/Obstacles/Obstacle.cpp b/src/Obstacles/Obstacle.cpp new file mode 100644 index 0000000..9d8ffd8 --- /dev/null +++ b/src/Obstacles/Obstacle.cpp @@ -0,0 +1,11 @@ +#include "Obstacle.h" + +Obstacle::Obstacle(const sf::Texture& data, bool dir, int size, int row, int col) : + MovingObject(data, dir,size,row,col) +{ +} + +//----------------------------------------------------------------------------- +Obstacle::~Obstacle() +{ +} diff --git a/src/Sinlgeton/AudioHolder.cpp b/src/Sinlgeton/AudioHolder.cpp new file mode 100644 index 0000000..0c76606 --- /dev/null +++ b/src/Sinlgeton/AudioHolder.cpp @@ -0,0 +1,55 @@ +#include "AudioHolder.h" + +AudioHolder::AudioHolder() +{ + // Uploading the audio from resources. + m_tracks[AUDIO_KILL].loadFromFile("enemykill.wav"); + m_tracks[AUDIO_JUMP].loadFromFile("jump.wav"); + m_tracks[AUDIO_FIRE].loadFromFile("fireball.wav"); + m_tracks[AUDIO_COIN].loadFromFile("coin.wav"); + m_tracks[AUDIO_FINISH_STAGE].loadFromFile("poledown.wav"); + m_tracks[AUDIO_LOST].loadFromFile("youlost.wav"); + m_tracks[AUDIO_BUMP].loadFromFile("bump.wav"); + m_tracks[AUDIO_PAUSE].loadFromFile("pause.wav"); + m_tracks[AUDIO_DEATH].loadFromFile("death.wav"); + m_tracks[AUDIO_BACKGROUND].loadFromFile("background.ogg"); + m_tracks[AUDIO_SUPER].loadFromFile("supermushroom.wav"); + m_tracks[AUDIO_WON].loadFromFile("won.wav"); + + m_sound[AUDIO_KILL].setBuffer(m_tracks[AUDIO_KILL]); + m_sound[AUDIO_JUMP].setBuffer(m_tracks[AUDIO_JUMP]); + m_sound[AUDIO_FIRE].setBuffer(m_tracks[AUDIO_FIRE]); + m_sound[AUDIO_COIN].setBuffer(m_tracks[AUDIO_COIN]); + m_sound[AUDIO_FINISH_STAGE].setBuffer(m_tracks[AUDIO_FINISH_STAGE]); + m_sound[AUDIO_LOST].setBuffer(m_tracks[AUDIO_LOST]); + m_sound[AUDIO_BUMP].setBuffer(m_tracks[AUDIO_BUMP]); + m_sound[AUDIO_PAUSE].setBuffer(m_tracks[AUDIO_PAUSE]); + m_sound[AUDIO_DEATH].setBuffer(m_tracks[AUDIO_DEATH]); + m_sound[AUDIO_BACKGROUND].setBuffer(m_tracks[AUDIO_BACKGROUND]); + m_sound[AUDIO_SUPER].setBuffer(m_tracks[AUDIO_SUPER]); + m_sound[AUDIO_WON].setBuffer(m_tracks[AUDIO_WON]); + + m_sound[AUDIO_BACKGROUND].setLoop(true); +} + +//----------------------------------------------------------------------------- +void AudioHolder::playSound(int element) +{ + m_sound[element].play(); +} + +//----------------------------------------------------------------------------- +void AudioHolder::stopBGSound() +{ + m_sound[AUDIO_BACKGROUND].pause(); +} + +//----------------------------------------------------------------------------- +AudioHolder& AudioHolder::instance() +{ + static AudioHolder instance; + return instance; +} + +//----------------------------------------------------------------------------- +AudioHolder :: ~AudioHolder() {} \ No newline at end of file diff --git a/src/Sinlgeton/TextureHolder.cpp b/src/Sinlgeton/TextureHolder.cpp new file mode 100644 index 0000000..9658e52 --- /dev/null +++ b/src/Sinlgeton/TextureHolder.cpp @@ -0,0 +1,217 @@ +#include "TextureHolder.h" + +TextureHolder::TextureHolder() +{ + m_texture.push_back(std::vector()); + uploadFiles(); +} + +void TextureHolder::uploadFiles() +{ + sf::Texture temp; + + uploadPlayer(temp); + uploadEnemy(temp); + uploadWall(temp); + uploadCoin(temp); + uploadGoalFlag(temp); + uploadMenu(temp); + uploadLevels(temp); + uploadObstacles(temp); + uploadStatic(temp); + uploadGoodObj(temp); + uploadFireworks(temp); +} + +void TextureHolder::uploadPlayer(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Mario.png"); + m_texture[I_PLAYER].push_back(temp); + + temp.loadFromFile("SuperMario.png"); + m_texture[I_PLAYER].push_back(temp); + + temp.loadFromFile("FieryMario.png"); + m_texture[I_PLAYER].push_back(temp); +} + +void TextureHolder::uploadEnemy(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("BadMushroom.png"); + m_texture[I_ENEMY].push_back(temp); + + temp.loadFromFile("Tortoise.png"); + m_texture[I_ENEMY].push_back(temp); + + temp.loadFromFile("FlyingTortoise.png"); + m_texture[I_ENEMY].push_back(temp); + + temp.loadFromFile("PiranaPlant.png"); + m_texture[I_ENEMY].push_back(temp); +} + +void TextureHolder::uploadWall(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Floor.png"); + m_texture[I_WALL].push_back(temp); + + temp.loadFromFile("Bricks.png"); + m_texture[I_WALL].push_back(temp); + + temp.loadFromFile("Block.png"); + m_texture[I_WALL].push_back(temp); + + temp.loadFromFile("QuestionBlock.png"); + m_texture[I_WALL].push_back(temp); +} + +void TextureHolder::uploadCoin(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Coin.png"); + m_texture[I_COIN].push_back(temp); +} + +void TextureHolder::uploadGoalFlag(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("GoalPole.png"); + m_texture[I_GOAL_FLAG].push_back(temp); + + temp.loadFromFile("Flag.png"); + m_texture[I_GOAL_FLAG].push_back(temp); +} + +void TextureHolder::uploadMenu(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Menu.jpg"); + m_texture[I_MENU].push_back(temp); + + temp.loadFromFile("quitScreen.jpg"); + m_texture[I_MENU].push_back(temp); + + temp.loadFromFile("leaderBoard.jpg"); + m_texture[I_MENU].push_back(temp); + +} + +void TextureHolder::uploadLevels(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("level_1.png"); + m_texture[I_LEVELS].push_back(temp); + + temp.loadFromFile("level_2.png"); + m_texture[I_LEVELS].push_back(temp); + + temp.loadFromFile("level_3.png"); + m_texture[I_LEVELS].push_back(temp); + + temp.loadFromFile("level_4.png"); + m_texture[I_LEVELS].push_back(temp); +} + +void TextureHolder::uploadObstacles(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("FireBall.png"); + m_texture[I_OBSTACLES].push_back(temp); + + temp.loadFromFile("FirePole.png"); + m_texture[I_OBSTACLES].push_back(temp); +} + +void TextureHolder::uploadStatic(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Pipe.png"); + m_texture[I_STATIC].push_back(temp); + + temp.loadFromFile("Platform.png"); + m_texture[I_STATIC].push_back(temp); +} + +void TextureHolder::uploadGoodObj(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("SuperMushroom.png"); + m_texture[I_GOOD_OBJ].push_back(temp); + + temp.loadFromFile("FireFlower.png"); + m_texture[I_GOOD_OBJ].push_back(temp); +} + +void TextureHolder::uploadFireworks(sf::Texture temp) +{ + m_texture.push_back(std::vector()); + temp.loadFromFile("Fireworks.png"); + m_texture[I_FIREWORKS].push_back(temp); +} + +//----------------------------------------------------------------------------- +// This function is used to return the correct texture by the element given as input. +const sf::Texture& TextureHolder::getTextures(char element) const +{ + switch (element) + { + case QUESTION: return m_texture[I_WALL][I_QUESTION]; + case BLOCK: return m_texture[I_WALL][I_BLOCK]; + case BRICK: return m_texture[I_WALL][I_BRICK]; + case FLOOR: return m_texture[I_WALL][I_FLOOR]; + case COIN: return m_texture[I_COIN][0]; + case PLATFORM: return m_texture[I_STATIC][I_PLATFORM]; + case PIPE: return m_texture[I_STATIC][I_PIPE]; + case FIRE_BALL: return m_texture[I_OBSTACLES][I_FIREBALL]; + case FIRE_POLE: return m_texture[I_OBSTACLES][I_FIREPOLE]; + case SUPER_MUSH: return m_texture[I_GOOD_OBJ][I_SUPER_MUSH]; + case FIRE_FLOWER: return m_texture[I_GOOD_OBJ][I_FIRE_FLOWER]; + case FIREWORKS: return m_texture[I_FIREWORKS][0]; + } + return sf::Texture(); +} + +//----------------------------------------------------------------------------- +const sf::Texture& TextureHolder::getLevel(int level) const +{ + return m_texture[I_LEVELS][level]; +} + +//----------------------------------------------------------------------------- +const sf::Texture& TextureHolder::getScreen(int screen) const +{ + return m_texture[I_MENU][screen]; +} + +//----------------------------------------------------------------------------- +const sf::Texture& TextureHolder::getPlayer(int mode) const +{ + return m_texture[I_PLAYER][mode]; +} + +//----------------------------------------------------------------------------- +const sf::Texture& TextureHolder::getFlag(int kind) const +{ + return m_texture[I_GOAL_FLAG][kind]; +} +//----------------------------------------------------------------------------- +const sf::Texture& TextureHolder::getEnemy(int kind) const +{ + return m_texture[I_ENEMY][kind]; +} +//----------------------------------------------------------------------------- +TextureHolder& TextureHolder::instance() +{ + static TextureHolder instance; + return instance; +} + +//----------------------------------------------------------------------------- +TextureHolder::~TextureHolder() +{ +} + + diff --git a/src/StaticObjects/Block.cpp b/src/StaticObjects/Block.cpp new file mode 100644 index 0000000..d7b309a --- /dev/null +++ b/src/StaticObjects/Block.cpp @@ -0,0 +1,12 @@ +#include "Block.h" + +Block::Block(int row, int col) : UnPickable(row,col) +{ + m_sprite.setTexture(TextureHolder::instance().getTextures(BLOCK)); + m_sprite.setScale(BLOCK_SCALE, BLOCK_SCALE); +} + +//----------------------------------------------------------------------------- +Block::~Block() +{ +} diff --git a/src/StaticObjects/Brick.cpp b/src/StaticObjects/Brick.cpp new file mode 100644 index 0000000..c2c857c --- /dev/null +++ b/src/StaticObjects/Brick.cpp @@ -0,0 +1,21 @@ +#include "Brick.h" + +Brick::Brick(int row, int col) : + MovingObject(TextureHolder::instance().getTextures(BRICK), RIGHT, 1, row, col) +{ + m_sprite.setScale(BRICK_SCALE, BRICK_SCALE); + m_lastPos = getPos(); + m_shouldMove = false; +} + +//----------------------------------------------------------------------------- +void Brick::move(sf::Time deltaTime) +{ + if (m_shouldMove) + squareMove(deltaTime); +} + +//----------------------------------------------------------------------------- +Brick::~Brick() +{ +} diff --git a/src/StaticObjects/Coin.cpp b/src/StaticObjects/Coin.cpp new file mode 100644 index 0000000..fe40d11 --- /dev/null +++ b/src/StaticObjects/Coin.cpp @@ -0,0 +1,41 @@ +#include "Coin.h" + +Coin::Coin(int row, int col) :m_taken(false), +Pickable(TextureHolder::instance().getTextures(COIN), LEFT, COIN_SIZE, row, col) +{ + m_sprite.setPosition((float)(col * ICON_SIZE + COIN_X_POS), + (float)(((row+1) * ICON_SIZE + COIN_Y_POS))); + m_lastPos = getPos(); +} + +//----------------------------------------------------------------------------- +void Coin::move(sf::Time deltaTime) +{ + m_animation.staticShift(deltaTime, COIN_SWITCH); + if (m_taken) + { + squareMove(deltaTime); + if (getPos().y >= m_lastPos.y) + m_delete = true; + } +} + +//----------------------------------------------------------------------------- +// This function let us know when the coin has been collected +void Coin::setTaken() +{ + m_taken = true; + m_velocity.y = BUMP; + m_sprite.move(m_velocity); +} + +//----------------------------------------------------------------------------- +bool Coin::getTaken() const +{ + return m_taken; +} + +//----------------------------------------------------------------------------- +Coin::~Coin() +{ +} diff --git a/src/StaticObjects/Floor.cpp b/src/StaticObjects/Floor.cpp new file mode 100644 index 0000000..0e6f6c0 --- /dev/null +++ b/src/StaticObjects/Floor.cpp @@ -0,0 +1,12 @@ +#include "Floor.h" + +Floor::Floor(int row, int col): UnPickable(row,col) +{ + m_sprite.setTexture(TextureHolder::instance().getTextures(FLOOR)); + m_sprite.setScale(FLOOR_SCALE, FLOOR_SCALE); +} + +//----------------------------------------------------------------------------- +Floor::~Floor() +{ +} diff --git a/src/StaticObjects/GoalFlag.cpp b/src/StaticObjects/GoalFlag.cpp new file mode 100644 index 0000000..a9281af --- /dev/null +++ b/src/StaticObjects/GoalFlag.cpp @@ -0,0 +1,42 @@ +#include "GoalFlag.h" + +GoalFlag::GoalFlag(int row, int col) : + MovingObject(TextureHolder::instance().getFlag(I_FLAG), LEFT, 1, row, col) +{ + m_sprite.setPosition((float)(col * ICON_SIZE + FLAG_X_POS), (float)(((row+ FLAG_Y_POS) * ICON_SIZE))); + m_sprite.setScale(1, 1); + m_lastPos = getPos(); + m_shouldMove = false; +} + +//----------------------------------------------------------------------------- +void GoalFlag::move(sf::Time deltaTime) +{ + if (m_shouldMove) + { + if (getPos().y - m_lastPos.y < FLAG_DISTANCE * ICON_SIZE) + { + m_velocity.y = ENEMY_SPEED * deltaTime.asSeconds(); + m_sprite.move(m_velocity); + } + else + m_velocity.y = 0; + } +} + +//----------------------------------------------------------------------------- +void GoalFlag::setShouldMove() +{ + m_shouldMove = true; +} + +//----------------------------------------------------------------------------- +bool GoalFlag::isShouldMove() const +{ + return true; +} + +//----------------------------------------------------------------------------- +GoalFlag::~GoalFlag() +{ +} diff --git a/src/StaticObjects/GoalPole.cpp b/src/StaticObjects/GoalPole.cpp new file mode 100644 index 0000000..3db64e6 --- /dev/null +++ b/src/StaticObjects/GoalPole.cpp @@ -0,0 +1,31 @@ +#include "GoalPole.h" + +GoalPole::GoalPole(int row, int col) : UnPickable(row, col), m_playerReached(false) +{ + m_sprite.setTexture(TextureHolder::instance().getFlag(I_POLE)); + m_sprite.setPosition((float)(col * ICON_SIZE), (float)((row * ICON_SIZE + POLE_Y_POS * ICON_SIZE))); + m_sprite.setScale(POLE_SCALE, POLE_SCALE); +} + +//----------------------------------------------------------------------------- +void GoalPole::setPlayerReached() +{ + if (!m_playerReached) + { + AudioHolder::instance().playSound(AUDIO_FINISH_STAGE); + AudioHolder::instance().stopBGSound(); + } + + m_playerReached = true; +} + +//----------------------------------------------------------------------------- +bool GoalPole::isPlayerReached() const +{ + return m_playerReached; +} + +//----------------------------------------------------------------------------- +GoalPole::~GoalPole() +{ +} diff --git a/src/StaticObjects/Pipe.cpp b/src/StaticObjects/Pipe.cpp new file mode 100644 index 0000000..09f3e4c --- /dev/null +++ b/src/StaticObjects/Pipe.cpp @@ -0,0 +1,12 @@ +#include "Pipe.h" + +Pipe::Pipe(int row, int col):UnPickable(row,col) +{ + m_sprite.setTexture(TextureHolder::instance().getTextures(PIPE)); + m_sprite.setScale(PIPE_SCALE, PIPE_SCALE); +} + +//----------------------------------------------------------------------------- +Pipe::~Pipe() +{ +} diff --git a/src/StaticObjects/QuestionBlock.cpp b/src/StaticObjects/QuestionBlock.cpp new file mode 100644 index 0000000..5029b7c --- /dev/null +++ b/src/StaticObjects/QuestionBlock.cpp @@ -0,0 +1,63 @@ +#include "QuestionBlock.h" + +QuestionBlock::QuestionBlock(int row, int col) :m_open(false),m_finished(false),m_kind(true), + MovingObject(TextureHolder::instance().getTextures(QUESTION), RIGHT, QUESTION_SIZE, row, col) +{ + m_sprite.setScale(QUESTION_SCALE, QUESTION_SCALE); + m_lastPos = getPos(); + m_shouldMove = false; +} + +//----------------------------------------------------------------------------- +void QuestionBlock::move(sf::Time deltaTime) +{ + if (m_open && !m_finished) + { + if (m_velocity.y == 0) + m_finished = true; + + if (m_shouldMove) + squareMove(deltaTime); + m_animation.setDeadSprite(); + } + + if (!m_open && !m_finished) + { + m_animation.staticShift(deltaTime, SWITCH); + m_animation.setDirection(m_dir); + } +} + +//----------------------------------------------------------------------------- +bool QuestionBlock::isShouldMove() const +{ + return true; +} + +//----------------------------------------------------------------------------- +bool QuestionBlock::getKind() const +{ + return m_kind; +} + +//----------------------------------------------------------------------------- +void QuestionBlock::setOpen(bool kind) +{ + m_open = true; + m_kind = kind; +} + +//----------------------------------------------------------------------------- +bool QuestionBlock::isOpen() const +{ + return m_open; +} + +//----------------------------------------------------------------------------- +QuestionBlock::~QuestionBlock() +{ +} + + + + diff --git a/src/StaticObjects/StaticObject.cpp b/src/StaticObjects/StaticObject.cpp new file mode 100644 index 0000000..e78031f --- /dev/null +++ b/src/StaticObjects/StaticObject.cpp @@ -0,0 +1,15 @@ +#include "StaticObject.h" + +StaticObject::StaticObject(int row, int col) : GameObject(row,col) +{ +} + +//----------------------------------------------------------------------------- +void StaticObject::shift(sf::Time deltaTime) +{ +} + +//----------------------------------------------------------------------------- +StaticObject::~StaticObject() +{ +} diff --git a/src/StaticObjects/UnPickable.cpp b/src/StaticObjects/UnPickable.cpp new file mode 100644 index 0000000..d3ab95d --- /dev/null +++ b/src/StaticObjects/UnPickable.cpp @@ -0,0 +1,10 @@ +#include "UnPickable.h" + +UnPickable::UnPickable(int row, int col) : StaticObject(row,col) +{ +} + +//----------------------------------------------------------------------------- +UnPickable::~UnPickable() +{ +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..783ab32 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,20 @@ +#include "Controller.h" + +int main() +{ + std::fstream excp; + try + { + excp.open("log.txt", std::ios::app); + if (!excp.is_open()) + throw std::exception("log file couldn't be open.\n"); + + Controller game; + game.startMenu(); + } + catch (std::exception& e) + { + excp << e.what(); + } + return EXIT_SUCCESS; +}