diff --git a/src/include/Activities/FightActivity.hpp b/src/include/Activities/FightActivity.hpp index 1b795bf..970b074 100644 --- a/src/include/Activities/FightActivity.hpp +++ b/src/include/Activities/FightActivity.hpp @@ -40,6 +40,9 @@ class FightActivity: public Activity { void runCurrentState(Game &game); private: + /* + * fightEnv is a personal current view state of FightActivity. Therefore, can not be included in Game.hpp or a derived class + */ FightEnv fightEnv; FightStateEnum currentFightStateEnum = FightStateEnum::TURN_CHANGE; std::shared_ptr enemy; diff --git a/src/include/Game.hpp b/src/include/Game.hpp index 4be9f14..82bdfcf 100644 --- a/src/include/Game.hpp +++ b/src/include/Game.hpp @@ -21,7 +21,7 @@ class Game { GameStatus gameStatus; sf::RenderWindow& gameWindow; - Player player = Player("Ipagaxi", 100, 12, {100, 100, 100}, "default_actor_quer.png"); + std::shared_ptr player = std::make_shared(Player("Ipagaxi", 100, 12, {100, 100, 100}, "default_actor_quer.png")); static Game& getInstance(); diff --git a/src/include/GameStatus.hpp b/src/include/GameStatus.hpp index d707b34..b777365 100644 --- a/src/include/GameStatus.hpp +++ b/src/include/GameStatus.hpp @@ -3,6 +3,7 @@ #include + class GameStatus { public: sf::Time elapsedTime; diff --git a/src/include/ObserverPattern/Observer.hpp b/src/include/ObserverPattern/Observer.hpp index 125739a..db05a8b 100644 --- a/src/include/ObserverPattern/Observer.hpp +++ b/src/include/ObserverPattern/Observer.hpp @@ -12,20 +12,25 @@ class Observer { //Observer(Actor& subject); virtual ~Observer(); virtual void onNotify(int newValue); + void invalidateSubject(); + private: - Subject* subject; + Subject* subject; }; class Subject { public: - void attachObserver(Observer& observer); - void detachObserver(Observer& observer); + ~Subject(); + using RefObserver = std::reference_wrapper; + void attachObserver(Observer& observer); + void detachObserver(Observer& observer); + bool valid = true; private: - std::list observers; + std::list observers; protected: - virtual void notify(int newValue); + virtual void notify(int newValue); }; #endif \ No newline at end of file diff --git a/src/include/UIElements/UIStats.hpp b/src/include/UIElements/UIStats.hpp index 0cc893d..324b011 100644 --- a/src/include/UIElements/UIStats.hpp +++ b/src/include/UIElements/UIStats.hpp @@ -12,7 +12,7 @@ class UIStats: public UIElement, Observer { public: ~UIStats(); - UIStats(Actor& actor); + UIStats(std::shared_ptr actor); void init(Actor actor); void draw() override; sf::Vector2f getPosition() override; diff --git a/src/include/UIObjects/UIEnemyOverview.hpp b/src/include/UIObjects/UIEnemyOverview.hpp index 3c745c6..3f1eb13 100644 --- a/src/include/UIObjects/UIEnemyOverview.hpp +++ b/src/include/UIObjects/UIEnemyOverview.hpp @@ -13,7 +13,7 @@ class UIEnemyOverview { public: - UIEnemyOverview(Enemy& enemy); + UIEnemyOverview(std::shared_ptr enemy); Enemy enemy; UIColorPicker colorPicker = UIColorPicker("colorPIC_default.png", "color_picker_border.png"); sf::Text pickedColorText; diff --git a/src/main/Activities/FightActivity.cpp b/src/main/Activities/FightActivity.cpp index fc72638..e10b386 100644 --- a/src/main/Activities/FightActivity.cpp +++ b/src/main/Activities/FightActivity.cpp @@ -4,7 +4,7 @@ FightActivity::FightActivity() : Activity(), fightEnv(), currentFightState(std::make_unique(fightEnv)) { Game& game = Game::getInstance(); this->enemy = std::make_shared(this->initEnemy()); - this->fightEnv.enemyOverview = std::make_unique(*this->enemy); + this->fightEnv.enemyOverview = std::make_unique(this->enemy); this->fightEnv.playerOverview.init(); this->fightEnv.backgroundTX.loadFromFile(RESOURCE_PATH "backgrounds/background_fight.png"); @@ -42,7 +42,6 @@ FightActivity::FightActivity() : Activity(), fightEnv(), currentFightState(std:: } FightActivity::~FightActivity() { - //delete this->fightEnv.enemyOverview; this->fightEnv.backgroundMusic.stop(); } diff --git a/src/main/FightStates/PlayersTurn.cpp b/src/main/FightStates/PlayersTurn.cpp index 71ba6a6..a514892 100644 --- a/src/main/FightStates/PlayersTurn.cpp +++ b/src/main/FightStates/PlayersTurn.cpp @@ -20,7 +20,7 @@ FightStateEnum PlayersTurn::run(FightEnv &fightEnv) { fightEnv.pickedColor = fightEnv.enemyOverview->colorPicker.getPixelColor(clickedPos); fightEnv.enemyOverview->updatePickedColorText("(" + std::to_string(fightEnv.pickedColor.r) + ", " + std::to_string(fightEnv.pickedColor.g) + ", " + std::to_string(fightEnv.pickedColor.b) + ")", fightEnv.pickedColor); float attackMultiplier = this->calculateAttackMult(fightEnv); - int damage = game.player.attackStrength * attackMultiplier; + int damage = game.player->attackStrength * attackMultiplier; int millSecToLive = 600; fightEnv.textFadingManager.startAnimation(std::to_string(damage), clickedPos, sf::Color::Yellow, game.gameWindow.getSize().y * 0.05, AnimationPath::Parabel, millSecToLive); fightEnv.enemyOverview->changeHealth(damage); diff --git a/src/main/ObserverPattern/Observer.cpp b/src/main/ObserverPattern/Observer.cpp index 134555b..2c6bc9d 100644 --- a/src/main/ObserverPattern/Observer.cpp +++ b/src/main/ObserverPattern/Observer.cpp @@ -8,11 +8,25 @@ Observer::Observer() { Observer::~Observer() { std::cout << "~Observer" << std::endl; - this->subject->detachObserver(*this); + if (subject && subject->valid) { + subject->detachObserver(*this); + } } void Observer::onNotify(int newValue) {} +void Observer::invalidateSubject() { + this->subject = nullptr; +} + +Subject::~Subject() { + this->valid = false; + for (RefObserver& obs : observers) { + obs.get().invalidateSubject(); + } +} + + void Subject::notify(int newValue) { for (Observer obs: observers) { obs.onNotify(newValue); @@ -20,13 +34,13 @@ void Subject::notify(int newValue) { } void Subject::attachObserver(Observer &observer) { - std::cout << "Observer attached" << std::endl; this->observers.push_front(observer); } void Subject::detachObserver(Observer &observer) { std::cout << "Size: " << this->observers.size() << std::endl; - this->observers.remove_if([&observer] (const Observer obs) { - return &obs == &observer; + this->observers.remove_if([&observer] (const RefObserver& obs) { + + return &obs.get() == &observer; }); } \ No newline at end of file diff --git a/src/main/UIElements/UIStats.cpp b/src/main/UIElements/UIStats.cpp index 4a8a688..78c886f 100644 --- a/src/main/UIElements/UIStats.cpp +++ b/src/main/UIElements/UIStats.cpp @@ -4,9 +4,9 @@ UIStats::~UIStats() { std::cout << "~UIStats" << std::endl; } -UIStats::UIStats(Actor& actor) { +UIStats::UIStats(std::shared_ptr actor) { std::cout << "UIStats(actor)" << std::endl; - actor.attachObserver(*this); + actor->attachObserver(*this); Game& game = Game::getInstance(); sf::Vector2u windowSize = game.gameWindow.getSize(); sf::Color statsValueFontColor = sf::Color::Yellow; @@ -20,7 +20,7 @@ UIStats::UIStats(Actor& actor) { this->actorStatsBox.setBackgroundMargin(actorStatsBoxSize.width * 0.1, actorStatsBoxSize.height * 0.04); this->actorName.setFont(game.mainFont); - this->actorName.setString(actor.name); + this->actorName.setString(actor->name); this->actorName.setCharacterSize(windowSize.y*0.02); this->actorName.setFillColor(sf::Color::White); @@ -30,7 +30,7 @@ UIStats::UIStats(Actor& actor) { this->actorHealthLabel.setFillColor(statsLabelFontColor); this->actorHealthValue.setFont(game.mainFont); - this->actorHealthValue.setString(std::to_string(actor.health)); + this->actorHealthValue.setString(std::to_string(actor->health)); this->actorHealthValue.setCharacterSize(statsTextHeight); this->actorHealthValue.setFillColor(statsValueFontColor); @@ -40,7 +40,7 @@ UIStats::UIStats(Actor& actor) { this->actorAttackStrengthLabel.setFillColor(statsLabelFontColor); this->actorAttackStrengthValue.setFont(game.mainFont); - this->actorAttackStrengthValue.setString(std::to_string(actor.attackStrength)); + this->actorAttackStrengthValue.setString(std::to_string(actor->attackStrength)); this->actorAttackStrengthValue.setCharacterSize(statsTextHeight); this->actorAttackStrengthValue.setFillColor(statsValueFontColor); @@ -50,7 +50,7 @@ UIStats::UIStats(Actor& actor) { this->actorRGBDefenseLabel.setFillColor(statsLabelFontColor); this->actorRGBDefenseValues.setFont(game.mainFont); - this->actorRGBDefenseValues.setString("(" + std::to_string(actor.defense.red) + ", " + std::to_string(actor.defense.green) + ", " + std::to_string(actor.defense.blue) + ")"); + this->actorRGBDefenseValues.setString("(" + std::to_string(actor->defense.red) + ", " + std::to_string(actor->defense.green) + ", " + std::to_string(actor->defense.blue) + ")"); this->actorRGBDefenseValues.setCharacterSize(statsTextHeight); this->actorRGBDefenseValues.setFillColor(statsValueFontColor); diff --git a/src/main/UIObjects/UIEnemyOverview.cpp b/src/main/UIObjects/UIEnemyOverview.cpp index f86a6b3..6be6f72 100644 --- a/src/main/UIObjects/UIEnemyOverview.cpp +++ b/src/main/UIObjects/UIEnemyOverview.cpp @@ -1,10 +1,8 @@ #include "UIObjects/UIEnemyOverview.hpp" -UIEnemyOverview::UIEnemyOverview(Enemy &_enemy): enemyBorderedImage("monster_landscape_cut/" + _enemy.picPath, "actor_borders/fight_border.png"), enemyStats(_enemy) { +UIEnemyOverview::UIEnemyOverview(std::shared_ptr _enemy): enemyBorderedImage("monster_landscape_cut/" + (*_enemy).picPath, "actor_borders/fight_border.png"), enemyStats(_enemy) { Game& game = Game::getInstance(); - this->enemy = _enemy; - //this->enemyBorderedImage.init("monster_landscape_cut/" + enemy.picPath, "actor_borders/fight_border.png"); - //this->enemyStats.init(_enemy); + this->enemy = *_enemy; sf::Vector2u windowSize = game.gameWindow.getSize(); sf::FloatRect boxRect = this->box.getSize(); diff --git a/src/main/UIObjects/UIPlayerOverview.cpp b/src/main/UIObjects/UIPlayerOverview.cpp index 9ebdc5a..c0f11fd 100644 --- a/src/main/UIObjects/UIPlayerOverview.cpp +++ b/src/main/UIObjects/UIPlayerOverview.cpp @@ -1,6 +1,6 @@ #include "UIObjects/UIPlayerOverview.hpp" -UIPlayerOverview::UIPlayerOverview(): uiPlayerStats(Game::getInstance().player), playerFrame("monster_landscape_cut/" + Game::getInstance().player.picPath, "actor_borders/fight_border.png") { +UIPlayerOverview::UIPlayerOverview(): uiPlayerStats(Game::getInstance().player), playerFrame("monster_landscape_cut/" + Game::getInstance().player->picPath, "actor_borders/fight_border.png") { }