From 9dbb1d6d6da213843701a5f8e93b7717f0b345de Mon Sep 17 00:00:00 2001 From: Askou Date: Sun, 6 Jun 2021 10:10:53 +0200 Subject: [PATCH 01/40] basic music component --- sources/Component/Music/MusicComponent.cpp | 56 ++++++++++++++++++++++ sources/Component/Music/MusicComponent.hpp | 55 +++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 sources/Component/Music/MusicComponent.cpp create mode 100644 sources/Component/Music/MusicComponent.hpp diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp new file mode 100644 index 00000000..f31bfe16 --- /dev/null +++ b/sources/Component/Music/MusicComponent.cpp @@ -0,0 +1,56 @@ +/* +** EPITECH PROJECT, 2021 +** Bomberman +** File description: +** MusicComponent +*/ + +#include "MusicComponent.hpp" + + +namespace BBM +{ + MusicComponent::MusicComponent(WAL::Entity &entity, std::string &path) + : WAL::Component(entity), + _musicPath(path) + {} + + WAL::Component *MusicComponent::clone(WAL::Entity &entity) const + { + return new MusicComponent(entity); + } + + + void MusicComponent::loadMusic(void) + { + this->_music = RAY::Audio::Music(this->_musicPath); + this->_music.play(); + } + + void MusicComponent::unloadMusic(void) + { + this->_music.stop(); + } + + void MusicComponent::pauseMusic(void) + { + this->_music.pause(); + } + + void MusicComponent::setVolume(float &volume) + { + this->_music.setVolume(volume); + } + + void MusicComponent::setPitch(float &pitch) + { + this->_music.setPitch(pitch); + } + + bool MusicComponent::isPlaying(void) + { + return (this->_music.isPlaying()); + } + + +} // namespace WAL diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp new file mode 100644 index 00000000..c15335ec --- /dev/null +++ b/sources/Component/Music/MusicComponent.hpp @@ -0,0 +1,55 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#pragma once + +#include "Models/Vector3.hpp" +#include "Component/Component.hpp" +#include "Music.hpp" + +namespace BBM +{ + //! @brief A basic Music component + class MusicComponent : public WAL::Component + { + private: + //! @brief music of this entity + RAY::Audio::Music _music; + //! @brief path to the music + std::string _musicPath; + //! @brief Create a new MusicComponent linked to a specific entity + explicit MusicComponent(WAL::Entity &entity); + + public: + + //! @brief load music + void loadMusic(); + + //! @brief unload music + void unloadMusic(); + + //! @brief put music on hold + void pauseMusic(); + + //! @brief set music volume + void setVolume(float &); + + //! @brief set pitch volume + void setPitch(float &); + + //! @brief is music playing + bool isPlaying(void); + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + //! @brief Create a new MusicComponent at a certain Music + MusicComponent(WAL::Entity &entity, std::string &musicPath); + //! @brief A Music component is copy constructable + MusicComponent(const MusicComponent &) = default; + //! @brief A default destructor + ~MusicComponent() override = default; + //! @brief A Music component is not assignable + MusicComponent &operator=(const MusicComponent &) = delete; + }; +} // namespace WAL \ No newline at end of file From e04c8d0bd4e44c9ea403ca82d08b3f1c5c5f21b7 Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 11:22:45 +0200 Subject: [PATCH 02/40] add basic music manager --- CMakeLists.txt | 4 + assets/sounds/bomb_drop.ogg | Bin 0 -> 11489 bytes assets/sounds/death.ogg | Bin 0 -> 8715 bytes assets/sounds/new_death.ogg | Bin 0 -> 9601 bytes sources/Component/Music/MusicComponent.cpp | 75 +++++++++++++----- sources/Component/Music/MusicComponent.hpp | 45 ++++++++--- sources/Runner/Runner.cpp | 13 ++- .../System/Music/PlayerMusicManagerSystem.cpp | 26 ++++++ .../System/Music/PlayerMusicManagerSystem.hpp | 31 ++++++++ 9 files changed, 161 insertions(+), 33 deletions(-) create mode 100644 assets/sounds/bomb_drop.ogg create mode 100644 assets/sounds/death.ogg create mode 100644 assets/sounds/new_death.ogg create mode 100644 sources/System/Music/PlayerMusicManagerSystem.cpp create mode 100644 sources/System/Music/PlayerMusicManagerSystem.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 71343bba..19a5e613 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,10 @@ set(SOURCES sources/Component/Collision/CollisionComponent.hpp sources/System/Collision/CollisionSystem.hpp sources/System/Collision/CollisionSystem.cpp + sources/Component/Music/MusicComponent.cpp + sources/Component/Music/MusicComponent.hpp + sources/System/Music/PlayerMusicManagerSystem.cpp + sources/System/Music/PlayerMusicManagerSystem.hpp ) add_executable(bomberman sources/main.cpp diff --git a/assets/sounds/bomb_drop.ogg b/assets/sounds/bomb_drop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..40288f0e3f734ea1d28d6ee72209ca0f17b7c2ed GIT binary patch literal 11489 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 I?7tTOALZ>wHvj+t literal 0 HcmV?d00001 diff --git a/assets/sounds/death.ogg b/assets/sounds/death.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b582260411308e548dab9598241f29bcd27c87c1 GIT binary patch literal 8715 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 VU~0oJ8HOJmApSM|fb*~Ee*pk@LG1tl literal 0 HcmV?d00001 diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index f31bfe16..48daf6c3 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -1,56 +1,93 @@ -/* -** EPITECH PROJECT, 2021 -** Bomberman -** File description: -** MusicComponent -*/ +// +// Created by Tom Augier on 05/06/2021 +// +#include #include "MusicComponent.hpp" - namespace BBM { - MusicComponent::MusicComponent(WAL::Entity &entity, std::string &path) + MusicComponent::MusicComponent(WAL::Entity &entity, \ +std::map &musicPath) : WAL::Component(entity), - _musicPath(path) - {} + _musicIndex(IDLE) + { + for (int i = 0; i < DEATH + 1; i++) { + if (musicPath.at(static_cast(i)).empty()) { + this->_isLoad[static_cast(i)] = false; + } else { + this->_isLoad[static_cast(i)] = true; + this->_musicList[static_cast(i)] = RAY::Audio::Music(musicPath.at(static_cast(i))); + } + } + } + + MusicComponent::MusicComponent(WAL::Entity &entity) + : Component(entity), + _musicList(), + _musicIndex() + {} WAL::Component *MusicComponent::clone(WAL::Entity &entity) const { return new MusicComponent(entity); } - void MusicComponent::loadMusic(void) - { - this->_music = RAY::Audio::Music(this->_musicPath); - this->_music.play(); + { + if (!this->_isLoad.at(this->_musicIndex)) + return; + if (!this->_musicList[this->_musicIndex].isPlaying()) { + std::cout << this->_musicIndex << std::endl; + this->_musicList[this->_musicIndex].play(); + } } void MusicComponent::unloadMusic(void) { - this->_music.stop(); + if (!this->_isLoad.at(this->_musicIndex)) + return; + if (!this->_musicList[this->_musicIndex].isPlaying()) + this->_musicList[this->_musicIndex].stop(); } void MusicComponent::pauseMusic(void) { - this->_music.pause(); + if (!this->_isLoad.at(this->_musicIndex)) + return; + this->_musicList[this->_musicIndex].pause(); } void MusicComponent::setVolume(float &volume) { - this->_music.setVolume(volume); + if (!this->_isLoad.at(this->_musicIndex)) + return; + if (volume >= 0) + this->_musicList[this->_musicIndex].setVolume(volume); } void MusicComponent::setPitch(float &pitch) { - this->_music.setPitch(pitch); + if (!this->_isLoad.at(this->_musicIndex)) + return; + this->_musicList[this->_musicIndex].setPitch(pitch); } bool MusicComponent::isPlaying(void) { - return (this->_music.isPlaying()); + if (!this->_isLoad.at(this->_musicIndex)) + return (false); + return (this->_musicList[this->_musicIndex].isPlaying()); } + void MusicComponent::setIndex(musicIndex index) + { + this->_musicIndex = index; + } + + MusicComponent::musicIndex MusicComponent::getIndex(void) + { + return (this->_musicIndex); + } } // namespace WAL diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index c15335ec..7cb48fed 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -1,28 +1,34 @@ // -// Created by Zoe Roux on 5/17/21. +// Created by Tom Augier on 05/06/2021 // #pragma once -#include "Models/Vector3.hpp" #include "Component/Component.hpp" -#include "Music.hpp" +#include +#include "Audio/Music.hpp" namespace BBM { //! @brief A basic Music component class MusicComponent : public WAL::Component { - private: - //! @brief music of this entity - RAY::Audio::Music _music; - //! @brief path to the music - std::string _musicPath; - //! @brief Create a new MusicComponent linked to a specific entity - explicit MusicComponent(WAL::Entity &entity); - public: + enum musicIndex { + IDLE, + JUMP, + BOMB, + MOVE, + HURT, + THROW, + DEATH, + }; + + void setIndex(musicIndex index); + + musicIndex getIndex(); + //! @brief load music void loadMusic(); @@ -41,15 +47,28 @@ namespace BBM //! @brief is music playing bool isPlaying(void); + //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new MusicComponent at a certain Music - MusicComponent(WAL::Entity &entity, std::string &musicPath); + MusicComponent(WAL::Entity &entity, std::map &musicPath); //! @brief A Music component is copy constructable MusicComponent(const MusicComponent &) = default; //! @brief A default destructor ~MusicComponent() override = default; //! @brief A Music component is not assignable MusicComponent &operator=(const MusicComponent &) = delete; + private: + //! @brief music of this entity + std::map _musicList; + + std::map _isLoad; + //! musicIndex + musicIndex _musicIndex; + //! @brief Create a new MusicComponent linked to a specific entity + explicit MusicComponent(WAL::Entity &entity); + + }; -} // namespace WAL \ No newline at end of file + +} // namespace BBM \ No newline at end of file diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index cd5b30e1..74b807e1 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -29,6 +29,7 @@ #include "Component/Animation/AnimationsComponent.hpp" #include "System/Animation/AnimationsSystem.hpp" #include "Map/Map.hpp" +#include "Component/Music/MusicComponent.hpp" namespace RAY2D = RAY::Drawables::Drawables2D; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -64,6 +65,15 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); + std::map musicPath= { + {MusicComponent::IDLE, ""}, + {MusicComponent::JUMP, ""}, + {MusicComponent::BOMB, ""}, + {MusicComponent::MOVE, "assets/sounds/new_death.ogg"}, + {MusicComponent::HURT, ""}, + {MusicComponent::THROW, ""}, + {MusicComponent::DEATH, ""} + }; scene->addEntity("player") .addComponent() .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) @@ -71,7 +81,8 @@ namespace BBM .addComponent() .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 1) .addComponent(2) - .addComponent(); + .addComponent() + .addComponent(musicPath); scene->addEntity("cube") .addComponent(-5, 0, -5) .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) diff --git a/sources/System/Music/PlayerMusicManagerSystem.cpp b/sources/System/Music/PlayerMusicManagerSystem.cpp new file mode 100644 index 00000000..2d46b5ff --- /dev/null +++ b/sources/System/Music/PlayerMusicManagerSystem.cpp @@ -0,0 +1,26 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include "PlayerMusicManagerSystem.hpp" + +namespace BBM { + + void MusicManagerSystem::onFixedUpdate(WAL::Entity &entity) + { + if (!entity.hasComponent()) + return; + const auto &controllable = entity.getComponent(); + auto &music = entity.getComponent(); + auto &health = entity.getComponent(); + + music.setIndex(MusicComponent::BOMB); + controllable.bomb ? music.loadMusic() : music.unloadMusic(); + music.setIndex(MusicComponent::JUMP); + controllable.jump ? music.loadMusic() : music.unloadMusic(); + music.setIndex(MusicComponent::MOVE); + (controllable.move.x != 0 || controllable.move.y != 0) ? music.loadMusic() : music.unloadMusic(); + music.setIndex(MusicComponent::DEATH); + health.getHealthPoint() == 0 ? music.loadMusic() : music.unloadMusic(); + } +} \ No newline at end of file diff --git a/sources/System/Music/PlayerMusicManagerSystem.hpp b/sources/System/Music/PlayerMusicManagerSystem.hpp new file mode 100644 index 00000000..7038549a --- /dev/null +++ b/sources/System/Music/PlayerMusicManagerSystem.hpp @@ -0,0 +1,31 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#pragma once + +#include "System/System.hpp" +#include "Window.hpp" +#include "Component/Music/MusicComponent.hpp" +#include "Component/Health/HealthComponent.hpp" +#include +#include "Wal.hpp" + +namespace BBM +{ + class MusicManagerSystem : public WAL::System + { + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief ctor + MusicManagerSystem(WAL::Wal &wal, RAY::Window &window); + //! @brief Default copy ctor + MusicManagerSystem(const MusicManagerSystem &) = default; + //! @brief Default dtor + ~MusicManagerSystem() override = default; + //! @brief A MusicManager screen system can't be assigned. + MusicManagerSystem &operator=(const MusicManagerSystem &) = delete; + }; +} From 8e93e840064b521ee2e114b300c55b626e053543 Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 11:43:06 +0200 Subject: [PATCH 03/40] add sound/music component --- sources/Component/Music/MusicComponent.cpp | 56 +++---------- sources/Component/Music/MusicComponent.hpp | 24 +----- sources/Component/Sound/SoundComponent.cpp | 93 ++++++++++++++++++++++ sources/Component/Sound/SoundComponent.hpp | 74 +++++++++++++++++ sources/Runner/Runner.cpp | 19 ++--- 5 files changed, 190 insertions(+), 76 deletions(-) create mode 100644 sources/Component/Sound/SoundComponent.cpp create mode 100644 sources/Component/Sound/SoundComponent.hpp diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index 48daf6c3..e1aaca5e 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -7,25 +7,15 @@ namespace BBM { - MusicComponent::MusicComponent(WAL::Entity &entity, \ -std::map &musicPath) + MusicComponent::MusicComponent(WAL::Entity &entity, std::string &musicPath) : WAL::Component(entity), - _musicIndex(IDLE) + _music(RAY::Audio::Music(musicPath)) { - for (int i = 0; i < DEATH + 1; i++) { - if (musicPath.at(static_cast(i)).empty()) { - this->_isLoad[static_cast(i)] = false; - } else { - this->_isLoad[static_cast(i)] = true; - this->_musicList[static_cast(i)] = RAY::Audio::Music(musicPath.at(static_cast(i))); - } - } } MusicComponent::MusicComponent(WAL::Entity &entity) : Component(entity), - _musicList(), - _musicIndex() + _music() {} WAL::Component *MusicComponent::clone(WAL::Entity &entity) const @@ -35,59 +25,35 @@ std::map &musicPath) void MusicComponent::loadMusic(void) { - if (!this->_isLoad.at(this->_musicIndex)) - return; - if (!this->_musicList[this->_musicIndex].isPlaying()) { - std::cout << this->_musicIndex << std::endl; - this->_musicList[this->_musicIndex].play(); - } + if (!this->_music.isPlaying()) + this->_music.play(); } void MusicComponent::unloadMusic(void) { - if (!this->_isLoad.at(this->_musicIndex)) - return; - if (!this->_musicList[this->_musicIndex].isPlaying()) - this->_musicList[this->_musicIndex].stop(); + if (!this->_music.isPlaying()) + this->_music.stop(); } void MusicComponent::pauseMusic(void) { - if (!this->_isLoad.at(this->_musicIndex)) - return; - this->_musicList[this->_musicIndex].pause(); + this->_music.pause(); } void MusicComponent::setVolume(float &volume) { - if (!this->_isLoad.at(this->_musicIndex)) - return; if (volume >= 0) - this->_musicList[this->_musicIndex].setVolume(volume); + this->_music.setVolume(volume); } void MusicComponent::setPitch(float &pitch) { - if (!this->_isLoad.at(this->_musicIndex)) - return; - this->_musicList[this->_musicIndex].setPitch(pitch); + this->_music.setPitch(pitch); } bool MusicComponent::isPlaying(void) { - if (!this->_isLoad.at(this->_musicIndex)) - return (false); - return (this->_musicList[this->_musicIndex].isPlaying()); - } - - void MusicComponent::setIndex(musicIndex index) - { - this->_musicIndex = index; - } - - MusicComponent::musicIndex MusicComponent::getIndex(void) - { - return (this->_musicIndex); + return (this->_music.isPlaying()); } } // namespace WAL diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index 7cb48fed..132179f2 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -14,21 +14,6 @@ namespace BBM class MusicComponent : public WAL::Component { public: - - enum musicIndex { - IDLE, - JUMP, - BOMB, - MOVE, - HURT, - THROW, - DEATH, - }; - - void setIndex(musicIndex index); - - musicIndex getIndex(); - //! @brief load music void loadMusic(); @@ -47,11 +32,10 @@ namespace BBM //! @brief is music playing bool isPlaying(void); - //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new MusicComponent at a certain Music - MusicComponent(WAL::Entity &entity, std::map &musicPath); + MusicComponent(WAL::Entity &entity, std::string &musicPath); //! @brief A Music component is copy constructable MusicComponent(const MusicComponent &) = default; //! @brief A default destructor @@ -60,11 +44,7 @@ namespace BBM MusicComponent &operator=(const MusicComponent &) = delete; private: //! @brief music of this entity - std::map _musicList; - - std::map _isLoad; - //! musicIndex - musicIndex _musicIndex; + RAY::Audio::Music _music; //! @brief Create a new MusicComponent linked to a specific entity explicit MusicComponent(WAL::Entity &entity); diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp new file mode 100644 index 00000000..eb7b8ad8 --- /dev/null +++ b/sources/Component/Sound/SoundComponent.cpp @@ -0,0 +1,93 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include +#include "SoundComponent.hpp" + +namespace BBM +{ + SoundComponent::SoundComponent(WAL::Entity &entity, \ +std::map &soundPath) + : WAL::Component(entity), + _soundIndex(IDLE) + { + for (int i = 0; i < DEATH + 1; i++) { + if (soundPath.at(static_cast(i)).empty()) { + this->_isLoad[static_cast(i)] = false; + } else { + this->_isLoad[static_cast(i)] = true; + this->_soundList[static_cast(i)] = RAY::Audio::Sound(soundPath.at(static_cast(i))); + } + } + } + + SoundComponent::SoundComponent(WAL::Entity &entity) + : Component(entity), + _soundList(), + _soundIndex() + {} + + WAL::Component *SoundComponent::clone(WAL::Entity &entity) const + { + return new SoundComponent(entity); + } + + void SoundComponent::loadSound(void) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (!this->_soundList[this->_soundIndex].isPlaying()) { + std::cout << this->_soundIndex << std::endl; + this->_soundList[this->_soundIndex].play(); + } + } + + void SoundComponent::unloadSound(void) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (!this->_soundList[this->_soundIndex].isPlaying()) + this->_soundList[this->_soundIndex].stop(); + } + + void SoundComponent::pauseSound(void) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + this->_soundList[this->_soundIndex].pause(); + } + + void SoundComponent::setVolume(float &volume) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (volume >= 0) + this->_soundList[this->_soundIndex].setVolume(volume); + } + + void SoundComponent::setPitch(float &pitch) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + this->_soundList[this->_soundIndex].setPitch(pitch); + } + + bool SoundComponent::isPlaying(void) + { + if (!this->_isLoad.at(this->_soundIndex)) + return (false); + return (this->_soundList[this->_soundIndex].isPlaying()); + } + + void SoundComponent::setIndex(soundIndex index) + { + this->_soundIndex = index; + } + + SoundComponent::soundIndex SoundComponent::getIndex(void) + { + return (this->_soundIndex); + } + +} // namespace WAL diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp new file mode 100644 index 00000000..1feaa261 --- /dev/null +++ b/sources/Component/Sound/SoundComponent.hpp @@ -0,0 +1,74 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#pragma once + +#include "Component/Component.hpp" +#include +#include "Audio/Sound.hpp" + +namespace BBM +{ + //! @brief A basic Sound component + class SoundComponent : public WAL::Component + { + public: + + enum soundIndex { + IDLE, + JUMP, + BOMB, + MOVE, + HURT, + THROW, + DEATH, + }; + + void setIndex(soundIndex index); + + soundIndex getIndex(); + + //! @brief load Sound + void loadSound(); + + //! @brief unload Sound + void unloadSound(); + + //! @brief put Sound on hold + void pauseSound(); + + //! @brief set Sound volume + void setVolume(float &); + + //! @brief set pitch volume + void setPitch(float &); + + //! @brief is Sound playing + bool isPlaying(void); + + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + //! @brief Create a new SoundComponent at a certain Sound + SoundComponent(WAL::Entity &entity, std::map &SoundPath); + //! @brief A Sound component is copy constructable + SoundComponent(const SoundComponent &) = default; + //! @brief A default destructor + ~SoundComponent() override = default; + //! @brief A Sound component is not assignable + SoundComponent &operator=(const SoundComponent &) = delete; + private: + //! @brief Sound of this entity + std::map _soundList; + + std::map _isLoad; + //! SoundIndex + soundIndex _soundIndex; + //! @brief Create a new SoundComponent linked to a specific entity + explicit SoundComponent(WAL::Entity &entity); + + + }; + +} // namespace BBM \ No newline at end of file diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 74b807e1..3670a151 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -30,6 +30,7 @@ #include "System/Animation/AnimationsSystem.hpp" #include "Map/Map.hpp" #include "Component/Music/MusicComponent.hpp" +#include "Component/Sound/SoundComponent.hpp" namespace RAY2D = RAY::Drawables::Drawables2D; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -65,14 +66,14 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); - std::map musicPath= { - {MusicComponent::IDLE, ""}, - {MusicComponent::JUMP, ""}, - {MusicComponent::BOMB, ""}, - {MusicComponent::MOVE, "assets/sounds/new_death.ogg"}, - {MusicComponent::HURT, ""}, - {MusicComponent::THROW, ""}, - {MusicComponent::DEATH, ""} + std::map musicPath= { + {SoundComponent::IDLE, ""}, + {SoundComponent::JUMP, ""}, + {SoundComponent::BOMB, ""}, + {SoundComponent::MOVE, "assets/sounds/new_death.ogg"}, + {SoundComponent::HURT, ""}, + {SoundComponent::THROW, ""}, + {SoundComponent::DEATH, ""} }; scene->addEntity("player") .addComponent() @@ -82,7 +83,7 @@ namespace BBM .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 1) .addComponent(2) .addComponent() - .addComponent(musicPath); + .addComponent(musicPath); scene->addEntity("cube") .addComponent(-5, 0, -5) .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) From fb9e5710b15729eaf172bd104aa88aeaedf3f2c2 Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 11:46:27 +0200 Subject: [PATCH 04/40] replace music system by sound system --- .../System/Music/PlayerMusicManagerSystem.cpp | 26 ------------------- .../System/Sound/PlayerSoundManagerSystem.cpp | 26 +++++++++++++++++++ .../PlayerSoundManagerSystem.hpp} | 14 +++++----- 3 files changed, 33 insertions(+), 33 deletions(-) delete mode 100644 sources/System/Music/PlayerMusicManagerSystem.cpp create mode 100644 sources/System/Sound/PlayerSoundManagerSystem.cpp rename sources/System/{Music/PlayerMusicManagerSystem.hpp => Sound/PlayerSoundManagerSystem.hpp} (53%) diff --git a/sources/System/Music/PlayerMusicManagerSystem.cpp b/sources/System/Music/PlayerMusicManagerSystem.cpp deleted file mode 100644 index 2d46b5ff..00000000 --- a/sources/System/Music/PlayerMusicManagerSystem.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Created by Tom Augier on 05/06/2021 -// - -#include "PlayerMusicManagerSystem.hpp" - -namespace BBM { - - void MusicManagerSystem::onFixedUpdate(WAL::Entity &entity) - { - if (!entity.hasComponent()) - return; - const auto &controllable = entity.getComponent(); - auto &music = entity.getComponent(); - auto &health = entity.getComponent(); - - music.setIndex(MusicComponent::BOMB); - controllable.bomb ? music.loadMusic() : music.unloadMusic(); - music.setIndex(MusicComponent::JUMP); - controllable.jump ? music.loadMusic() : music.unloadMusic(); - music.setIndex(MusicComponent::MOVE); - (controllable.move.x != 0 || controllable.move.y != 0) ? music.loadMusic() : music.unloadMusic(); - music.setIndex(MusicComponent::DEATH); - health.getHealthPoint() == 0 ? music.loadMusic() : music.unloadMusic(); - } -} \ No newline at end of file diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp new file mode 100644 index 00000000..512a5603 --- /dev/null +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -0,0 +1,26 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include "PlayerSoundManagerSystem.hpp" + +namespace BBM { + + void SoundManagerSystem::onFixedUpdate(WAL::Entity &entity) + { + if (!entity.hasComponent()) + return; + const auto &controllable = entity.getComponent(); + auto &sound = entity.getComponent(); + auto &health = entity.getComponent(); + + sound.setIndex(SoundComponent::BOMB); + controllable.bomb ? sound.loadSound() : sound.unloadSound(); + sound.setIndex(SoundComponent::JUMP); + controllable.jump ? sound.loadSound() : sound.unloadSound(); + sound.setIndex(SoundComponent::MOVE); + (controllable.move.x != 0 || controllable.move.y != 0) ? sound.loadSound() : sound.unloadSound(); + sound.setIndex(SoundComponent::DEATH); + health.getHealthPoint() == 0 ? sound.loadSound() : sound.unloadSound(); + } +} \ No newline at end of file diff --git a/sources/System/Music/PlayerMusicManagerSystem.hpp b/sources/System/Sound/PlayerSoundManagerSystem.hpp similarity index 53% rename from sources/System/Music/PlayerMusicManagerSystem.hpp rename to sources/System/Sound/PlayerSoundManagerSystem.hpp index 7038549a..aff694c2 100644 --- a/sources/System/Music/PlayerMusicManagerSystem.hpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.hpp @@ -6,26 +6,26 @@ #include "System/System.hpp" #include "Window.hpp" -#include "Component/Music/MusicComponent.hpp" +#include "Component/Sound/SoundComponent.hpp" #include "Component/Health/HealthComponent.hpp" #include #include "Wal.hpp" namespace BBM { - class MusicManagerSystem : public WAL::System + class SoundManagerSystem : public WAL::System { public: //! @inherit void onFixedUpdate(WAL::Entity &entity) override; //! @brief ctor - MusicManagerSystem(WAL::Wal &wal, RAY::Window &window); + SoundManagerSystem(WAL::Wal &wal, RAY::Window &window); //! @brief Default copy ctor - MusicManagerSystem(const MusicManagerSystem &) = default; + SoundManagerSystem(const SoundManagerSystem &) = default; //! @brief Default dtor - ~MusicManagerSystem() override = default; - //! @brief A MusicManager screen system can't be assigned. - MusicManagerSystem &operator=(const MusicManagerSystem &) = delete; + ~SoundManagerSystem() override = default; + //! @brief A SoundManager screen system can't be assigned. + SoundManagerSystem &operator=(const SoundManagerSystem &) = delete; }; } From a0ea2576a5c5b16af051c4c0e0433c78dbb35437 Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 12:33:18 +0200 Subject: [PATCH 05/40] add Sound component --- CMakeLists.txt | 6 ++++-- assets/sounds/death_wav.wav | Bin 0 -> 259406 bytes assets/sounds/weird.wav | Bin 0 -> 6246 bytes sources/Component/Sound/SoundComponent.cpp | 4 ++++ sources/Runner/Runner.cpp | 6 +++--- 5 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 assets/sounds/death_wav.wav create mode 100644 assets/sounds/weird.wav diff --git a/CMakeLists.txt b/CMakeLists.txt index 19a5e613..19eabf68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,8 +69,10 @@ set(SOURCES sources/System/Collision/CollisionSystem.cpp sources/Component/Music/MusicComponent.cpp sources/Component/Music/MusicComponent.hpp - sources/System/Music/PlayerMusicManagerSystem.cpp - sources/System/Music/PlayerMusicManagerSystem.hpp + sources/Component/Sound/SoundComponent.hpp + sources/Component/Sound/SoundComponent.cpp + sources/System/Sound/PlayerSoundManagerSystem.cpp + sources/System/Sound/PlayerSoundManagerSystem.hpp ) add_executable(bomberman sources/main.cpp diff --git a/assets/sounds/death_wav.wav b/assets/sounds/death_wav.wav new file mode 100644 index 0000000000000000000000000000000000000000..53f4bb258a29805df9703bc1ca502cce53f2f078 GIT binary patch literal 259406 zcmeF(cbpW}`XKzyIrsGRq)szKlpr}H2#5s92q>T=k)$9XAQ{P$gMgrtlOz$5oFqyR z5P_LaGt-kgP4{%pv(Gd4*8BF(qQ86Z?z{W$=Tr6lqpGV8CnU2LZMPY?3WFk{^zJcmPzKEJ(dVtcJqErtNCeZpM}7WL zi`I==wQSVn_17t5N6i>TfwhnW838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!g zi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O! z02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a} z838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec z0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{ zG6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)? z0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^ zWCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz) z1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6JuT z0G09&ul|;t`~SBHRQ+@KclYZ*UGCrA&i{_|#Ie*I|0mlf&i|U@zgt)GcKCh_^N(!Xl{f4c2gt&5n4 z>m;WC)A4_DEX20{XO<<_@qc>!zv6fKU-3KqD{=Tw<4qi6^7vob-v8}sl8-le`v3Oh z`cL%?*LzT;%#BW5yu@d7~rTbrXOn-M=#P*3Xu^%;$iTM1g zeM+83tOv(5Kzt_F`>HXqJf=+^lDAoNIyv3{m(#>{U$u>z`%Qd)Roed@^N3j2jAQb) zlhgcH)5*)>G!cvcWL$GyuiD4I+n<`t|2vO^QvwAtMiC;;276S3^k{TZ4%?ZN=M9p)tFc|dEKu{mpm_dnO7}`$C;cSr(czh zNJGR0KPOKU-zSg%tM8N3CQm2tGv3z-$@4LN&Gpy(oScUEE_s}&`iJCsIGwyNHK*}= zTq=3MG|Bt+SJO4u^{UUrdSCTj^1OdFUGg%?(>3>z_>P!Qd?v=k_Fi@DL>e3?FHbC! z{5_Ede^WZZF)l;QPhOr_j+jTJBj&$qOlBRgm;bAECvO|qNi6$U>1%G6*ak75 z_>5y>eaZ7)HI3*$*6KQKs<92Eef3AiGf~_0m8pr?Xfct~-#hft;a71WV*R+EH3wq9lGlf6i2Wv}lRx7;V!7mP;ynB= zdBEieIG@-KP80KSObocM#BWI)FR=`ciFvqPA|0_0_+9dPiQk~+^2BFiT{uo&NAfhL zCH9S2ck+6PWr=m+vN(;$M4S`E`GB8^WpQ1&ZelrNJ;~>9^7lBMybQ4&Vm`5N#CCCv z-w`oN-VRO^1F;;Aalqw>WpNwC{t)SLjNcRII-c){ScX_Pt_zQ~=JkN{alrIMJZg^d zI~;IZxIUc5?L|Ns;24*|?{OcAoPgL@V!!b-u{^E=r-``XXJVg;c{pbN6Ha3q+z#>k z;b+_?4!Evl_#Ls|I86+=JjNgd{J;lr8q?yoctG$^d&I=$ff8f_EyxA6|EU(GR`tAeN_ur#+)q5t z#sK%HC+G`$gU+A{&;UGEj0FxD1LFL^->@9yfrsEaI0KIU)A_3NRWAW9Qx9|pBfuwM zK3EOD27AE|;55KvzXP6tKLL(!fTLgyz-8YBxGs!i9e{B*R2izyf^WcbFbhlplfdU- z9XJVo2PL2q;BQ8p&v-51dGtCM0u}?@r$0a(WK*-Ltw9Tr0-jNxQN93pj^pw60+B={ zaTV+ad%(}&H}DiZ2KT^Ca2;F$zXCnrSMjTQfYsnGzD`O0`T`Z0Py&yf&QQcr~{gT_rXSh+r@JqV~gkFb6^8@-~d4& zpbDrtpd?3^W2tzy_g2DB%Z!DnV5%@FBq8 z4bNBHr&9pWA3XQ)xBe2CK{skQ>i56|s5B}~2%^*|^(Gh(yc92G2Ecm;UL)3oH8Bh1 z0&CnFzX-O2rC>SO0gi*80e<%Y*g<+CJuwno0QIZtR~-a+zU>E@)J*D^;0`c=U%_(F z6yQGY26Ms3;62a{;IeoucuZe|_TWY0MfJWlOEgPlfF@u%_!Ho@j^`}?zEiuPvRGMcDQE_wFzCSp@ECYN`&j$fA&?u-jUNIH6Ai1cozYdJ ztMHzW_srqc;nWh)ht`L-2J8pl0gS~&&=X_>JJn9z4eD!2?hpl_mY;ts%T2=5PgZ)!zt zMcob_f|uX|z~7`1D5sQDeg?}ydw}=7-r!o|TJ<@$GrluU1=C{FVoY#1dN+Ck90lh= z0mzDF#XbTTLG5_$_*pO^F(Hvzm05j<$9vyca2QyCj;f>107YOpZ8+^ZhyWg)M-S7& zv@4(=xJ%lzm z5ts!o08WBa{ku;}OiJtncrK(@rB~l8-3d2brOy*ZfKkPOGq7RR41oKzm9mwhrmCs$ zgZ`imz&xrk5Cc39iU5PkfU~6)btL!%%mS+b-WR?Ccn`;UUxQ2F33v?fo_Y&B1$dt; z00B^oR*NS6K zK}k?n0W1??nW{6;f!1ImzVXu{8sPjgAc;z% zjlq1tim_t5Kzckq{xxWmXaiTSH-Y7u0)XXAEYDzh=?cJo>O<{AJqHvt1+4>U2=Kf* z0J;D?f0hC)Ltwn|Sn+qld>4Vt-$E^yIZ^hJOVF48X2HiLO!8dwSNTvgB&bS-#EdrA8kxTvn`d&oS>Jj$0< zUsfGV987S*SMjgnfmk5c1$-C%E}988L^ebU!Uf^iz_HM=&}ZNSFbb>({4hWKE0__P z5%Gc%(Gk`8;F#E$*h|np-adXB^iT9p(5vWGdja03uzYb3L;w_nsD6r{;sH!5lUf^e z1p`5EfO!JuSLeYT&=24}bS0<&SbqBr=x93HB9I5@Ft9)-!24$eEN3idl!3a;y37e+ z2lxW8z*5H2>Uiqu`s(z4nxA$6>;`!6zX}e4Gaw2&(L2#Q0-XK@VB9|f7+bs^@mXY9 z)v~I~iOUIN+*o~%@?-p1pJ<=xp2(gEUhlq;FBAv{f^sk+Fd-24$Nj$p2N)9=6Q~`m z9h8UUA!?W!{v9lgER1NQ+UP0pTI{vh4*<{q0f_+#d|sGEnMLVN?G8DFg*ucrl(rpU zxvCprfl6v6H3*#GJeUkH)_9M_=NT;L;BPY=JOEf8TmbF@HBC($17?CL;A^0yE9sBH z2F3=)TgI*@FVp{Y9*zzI*)t3>h&rt=U}<_NbE@U^=^$=Bk5pJcu@G;(6=E+&=G6`J`8*q z*yP{jrvrn};8XY&@M)8ONMK0d^Wf*f-$K8Iu)^edqOev<^0$5Hs0SW--ad@A= z``{b&H|U1|-b3-4o(0YT7ih<9$NU+LWsPNN*;@8tPzs8`H-HPeu)45jGiNhP8KsOX zzz5!DzRg??4uJjOQ{ZR#8E=6N^bPbXT2=Ku!B6!=$>Vh@mhCrGZK(Pw@l#@3d|UjT z*gLV5Xi8KQ(L_E9e-!>X^mE7+bOoD%HGwsO3;qlKuYF(p=6L6LtsbjK>XmvggVVm# zK8xSt9~K-Iw1%vqj7Uc08*mnQz_jQztZIp_kFAgOi}#CTIpJ#6)hc{G+fUt(r#BVz z(G-CB1KtZUpZ^qKp1cT*0quYi;JwrZ@OkYDSV&t)>p<^7&j&pjJsE2O#_~D9^Q=AC z4jQl;u%ZCtc!+a|Bjd`r9I&6WpCbk1+2h$~SZ7!|kjKnpnm`6CgY_Bs1zZGkfE?^( z?qouC%}4>2v`QN8#~#Wa%C@R)RbM2&NZ@@h5luv$5od%2v|(+yeyDz^U9es7gTM!Y z#s04EMvOHOyZr*O*Yrbo~0f7O5%fZXRXQ5}I4dD%8 zZA2Tn48Dkd5$zW17E{C(aV+;YuWDX}_eOlK!}84%@H?Q=sdNL)Q2m^R_oi}y`4%1E z^91HaSSKI@833P8pMe{+8?veU-!#_;c<-$U8pgWw0jIe|HWW&UOU zdA@nRHr_VgCzVesFS;+f$ATB&Y30+(G;f-BgKvYcPM}U;YjA6DZfI`k55Nwy!!v*~ zqKw=HTccZ}KgE8EHBB^4;Ik%&%Avjhcz?%drH25^f%xpy7)%D3H{kOTJ~v_o9iG#8 ztrr14jZZrU@VMGB+A&suZ^0ALl-ZQI80-c{@D=MT)_V4O_G->*&LHj}E)RwuK@_Y3 z%el+Bi#dxqL3WV+0=xtjpe3gz=R5El7z-A%7qaKE=CRf?*D}{J)-ig~d(nTV{!YdE zAw`v<3W|b>;#hI)K=eSgPoz&I914fd1A*j z{Jpp+CW@6tN+Umne+YLAbqoC-_&u<|zra7sH_La>d(ivD^Tbn8Sy8D1-QC@*nu-%zP6}rQHgn$+OPIM3Oov&3Z4pFwzw!0Q0>oZHlYm_wUG%cbX5pU30q6(d z6IAdk_;#M1rv$%nf8iE_NxVrsClK<5{Ik5XyeK!yE#wq(-ebSV9?u-l#QGZzRYS%4 zOMDhx7+o0UNB9v&m=RWnlp%k>A2{nj>)-C%?%U$s;vME0=DF#<>2Bj{gej&Xy0hh2MwJKowf>F#bWnjx6-5Z8-sj#WAtEj8! zJh%rQf^UIMXcJ0z7KvMd^hlJKa0~1W?G2p@ zp9*h`Y>a#z{W@AFUMHSYl~YB90ppcUPp_`Gn@OKZ$Md!w!1|CFz`W`#C;+YLt*h(% z8Z#O*x`I*QHRfx~$E?S!p{hXis#PfPAxd^IPd5L zhTDhRJJ>qdmRgru&w_`xhqe)p5srox4J#J87rBRfhkGmh75<^Yp}~{j4(Jl<5~?2t zk@}Gq(H7BLv0E{0+ra1fU9?@*vHF4j13eC&0(_?KNb5*r0<5ncMjr;HrEjY1>!vZL zF~%^*Fv|g!YZ^egvopIhTgVl15AY7~hVX~*r-GxPfuMolYj6`lHIHDIaF=kOXrJh$ z_@sEaWVqx6cmeK$0br?ksrU!c4;@A%a6lD!$YostGc{o^cuZf57#rwJ<6?cDO?_>$BFmME%q&TjN3R6 zum-I4K&SFf<@Pdr+1&EEE0{u*Gpaw=~sZ=_(P;Ca-}tza`45B7uE;@RSTl6{gJ(i_t4vhA{LdA58acn`dky_7|y5ox8QQsNPN#Pz|? zqMt>J!5d(|F7O(z0Ew$ zJYTxMbYHEwTG7VY#wl?~9CSO~{=)jgdaC?X`IE9IWevgP(#fS$N~V+?Ek0U&2^=mt zT=H7kYh|BVKeOI&+;Dv7{?7f-`_S9l-`hU~^aDA8oIrzMgWxv63b8_G!)L=-uY&cB zSE*O2WwbI{h#sP2ozVg?jxmmrpe1M*0JfKW#`uh(WGa~!kju_x58({q>;p}}$DjeP z0q-ZlPXfHAzZ8Edz5!xjjAV@D0{8>q^(~YNrPqKQh96UYOmQe2iqBF%OWh8xgY)2; z;+kTie4)HhQYdL5ZXsSLS|=(J776DI<_i|`7V_G0+Hr0(Z!@tjuomHiL7e~d> znW34Xh5m*9N1jKXGIyDKwrjS_;dD5&9odeBwuQEF)^XMy?bA z4?w6mRD2Me2RS7;aF$kHUtSA%^XxPpY0&-G}yHZ11~Azej%r8UQZ12-Y*!Gs?jr<{;*`tZ!Lw zaNgjganrbO0~U`}T_&0=0+Pv+jna+M4`m<9`pWyt=_&LS5x6P8DL)Hv`Z)MR@rj~U zYOB-$SfX5_JPY=NjzE?wOLfUz@=4N3(yrpJ;va-R2;UXFD+urcys6x&+^g)X>{HBB z%xro#{bOhceH4Eb&yD6rJA^ufzVLtHf5-cd_fX}bN{L(IZdTE(VyR=P^cAA6b8P{_Mo^ zf!rha)Cb=Im)GS@^{4vZ2KPaaP>&F{GoDMFOJIXgCe$ZeXcpQ_#!JRU=0!L|>oTV> zrZ5UY3>wD1V12<_4Z5r>aK?o#ejPE4DaRyVzF`ZG`rZl~Q&TavmY^%was@>bGT z(w^d;;xC0?3Ne3c$!p1L!)?R8#lFQ(VWu##4FTI|v2OXj(0id4{ucfhl`ksmxaznj zJ10ABcALG4t%>be`LXg}%6=)M0(vRE^ic7k;-QwImPJL2ib92t$U`YHH}jha zn+WlK7?Osh;uLYp0mT7DQEE}@J>@-R{j~aNVP#mk0*nXpGP-B;bKD^^$ZarSY}bIfxzvp2K%u=cQiT=sEU>(bVx z^GoKJEGu4CJk>JQ5-Exl2`xg)qoPMe3h+bW4~4H6y4Q8ESpI~3%T;a^%&EV06bm36(Q1LOzG09x%TC>l*tS`wz|^oHA}1w?4l< z|El1sV2EglXp?x8c%5XO#3VIIopPsqV(P@yb!qF;Z0WZ2RT--?)&T)%n%*>hPTHKb zC179rzVz*x+cQlnlZvC|XxHl2>Ry5?+AG=x>ILeLGC#_Es(h+!pVB@hO`0aXF1jun zBpf6hCKx8*!vM{{oW`uiEUW|jGVx_X6;Va7KDfE3xd-cu{&4)^m|>e?gYFV#r%O(k zlvqkETZ^_9Z7$qgc&Fe_K{vn$H_bQALZCP5je87x3=w@q-^S3!@Rso{BiGC|A1ORi zm|2opa-;l4`3w6CyRt%Aam{tj#jE61{tobgWDcv&6H+FC{M}i)4#r4N@AUoKT!l3{ehIE=gaKUX)ps`J?Jb)l~IV^(?R! z_&^Iy3yls80)w@KwO4glbqBK#X3qyxbW?P0ja$Q3v(2P^F>?X9e>tS?Gml^ z2hcwF9{s)QM#>B93v8^r?auAa?Z@lKd(MB(e^2AJ2H1<-c;RGP1j7Y=*B#Ss(`^UK50<}Q_I_FK(%z+YOX`+jJcbkvDY{;8y7H3qJptM}#k^3wCu^M~t)>wh==Zpby|npzdKD%fh-YI(Qp-7=+3 zX`61JZg1;o>-fa^iBsuPx@Nd%xHndAtlaM1?&SyhL3hL*>6Pe}r~`ew#K9YST^Q3rET&b>9?40r-?Lk_%jBXiYv&LpM zR5w&BGz!g5Fi<;CTUS?CcLJOR3&BKy_r;@N328jR zRjw+JmBdQ!7vC=)2QFAHSTJ99m>uT!ruL>!jh`BA2AkoW{+zxvuQcz@%R4XY<<-k; zncp)1PtZ@_PyfL1z;MNU#XQn7(lV}eTxp;3KIQm~bk}~@e${!^$#St=QE;I0K;<~! zIN#0S&0w8qohY`=&!*0%V*4vz&kMKaG-<7&6b%K0?yp5!dL@tyI|KR??UB+6* z8V~(PFrVHN-xJ>!*%lcS920EiYvt=!*{yPG#nuXuL*&?M-D<60R=*4$i;Fv2I$9!y zk-|p>j|xVbN1Cr1uNo&ACKk#Pm%3Ywdmn|d31 zS6{zP@|)x@$y<`g1&)`FmtFI^=4It)HTijLJReDx-R`y298!1OqkEV7?@01?M2xQ>>>^;?cs&6#k zXi~FNv-jrg&542R-0a+2piiwnwW@Nfa#KLxoW41c>`3+x;JWU*E?b+e?Wpdk?vm9d z>vsC>^tq{XQ_soH$)GqdF5(yQrCceuCkxPf(sdLaMHCmsv0qU^pdj$J_igW8*IieA zXMN{l`(isZVb}s?fwJi((@S2ryly#Jc(U-Tg0BklOnIg)hAoDC7(M`>03K+U*DkN@ zW!cLUc_;E(=v(M9%>m;9<6!e(bAzG=MT1HPm7FL$QP#-X$hyO}!#3A3*RiK!Pj%h9 z&ZF~;^o{i04c-l6-$(2tbqD(O>KHl(mT}f{)^f1CTbEy#KS?l2Fi28HvQA<`!HdQoLq~&Y*gE)gYkC=~` z_38EL%_+?(!B{Z1KD<7R{a&!WtF)rDg6rTqu3N8LFPB{|J6UqFIE#(0|hoBOfNVqJ7yG&7NzI72x@ z!FHTOtV1jbSHiu(yTI!s=p(@TukDiUl3ZD?teL!-e0j?9l#!_;QwO9CNP}jz?1V0%gVQei9e@XLU3*-?(iB#;dKew(N2Fa1?h55-M;UeKy@mBFN=`!hg*?HM! z`DXd^l;VYAvzUEp zeQ9vZPhh*0Ib;q&wNJp{F?iOw*15iOeCOz9>t<_F-l9BS5-&MxIcq5{EG|4-aJKpx zHWyX(Y^O@?I>Zs1@Z-Qx`Zylb{qy5uo$eS^rrOo&^J3Lo)d2rX%tx;TpWaMMgCcyS)QL< zKe_HY?mDnRen;7kvQZ_YO8Qv(SauffESyp>rC^15g?XuIsi~u}qtU1L=`rtp7aYht zkmr2qe0c$2{!&X{OW(rS!Z_bN-wf3tMFqtL#hc1Dl^wGlvnuUMdlyF+$93m*=kKoH zUGI3_@nrZj{8&G?Ke|84tYTK_pg*9UVP{NXPhlVA9^|g$uj4~FgiA$BMRu`W{HgR) zsbA)oO-`AdVpUib^Of_Jt+30@0#YA=4fecX&q5IqBOfWyLdp+ zfTHgUzAs2Mr<$?CwE_6V@QLAb{pb2V`F--=$$Ka7-phM0Zvj=F3QCBjd4u$W^rMZV zjaSWA&DtVu(d^>c#ebImS((B3V=Q|t`!M$~_aXlwAKRSX7QZbXFBvbvvhG&dRvFf#j#P|PI8&Xe zchl~su`*ei3sehK&os|8`21EYr&dlBbjj_Kn*;K5@^iiei@|u14mM?P%J%BKy4v7( z&F`91s#7X^hCKu89d@PcO6e}`F1;hXBkaNJ!NdM<*s~hsqC?_bKgD8n%QjcM9(m7MY98{Z0K%G$XD0yz8Xzq%Y1d&fg8% zf=79e@(zN0@Lv9V`5p8f^w$m74GB}ibhYqm;kx2=#p*J3**xn!>mB zTG?9Jtdvk}HN8>qk5ey!b{y*V4NRb#F(cSNlbwKjp(;9Y>_m>J+e z&Vigm*@v=s>2~RsYnN-=YuanptJbS#WzNc!q)XB#q)tekDxWIPkYq?U2{s9^9CLzs zf{A@Nd&4^wJz_m#W5Z*^djfj`_@d(Y%JG#qD{fX`gL!vrck7nYEv2$zS@HA2=Y{3w za`SN0a8oy9H{(}^uMBwY_5nNccjSBWJbCj$e=rqStNcvZiKC z&FH4=raUD-C5Ng^Nf$vE0rn4aGMo(T`B9OmNYszjk97-o3%?O~Bhb{_)GKfc+~*wU z980WAtc9h8rEq!`r&-c09~XXHSYR$NpD>*;-7wxT-ZtDeY}aqsZ_D47&jrWwj^*_O z7{BcN?0kIA+il!!Twq>co?SS*5Idcg!qCv#&^pyN)wapL$-dsX-r3pR+5OD(%v0g3 z@If_J@L~927~glncOv)0yF}PO6rbtF^2YM!3g!x)3ZDvjVxAbwFkNL`WozVX1tXu!kgA`ipEz<%iX zPA9hac|xAhZ2xTkbkB6pY1e7jbH{TB-^RE7UiN!gZfS1m^5W&ihl&mrJuP@zu-LrV ze9Cmnbjx_l__5(*Lp^;x{iFOx`Iz5!2iAOR{x<-chV^e6-ZWe@UNg2gw>S4K>{~d$ zcz!W<_?cpxVtZZ;+Nw7lKzry;HdPdbi91L+?HZXk)%pe4=N8T85xX>)mf{vcBpr# z8)_SBx9PU&@HqpoV@<9mcUjJ|>bzq|_Kxhn;Fj)|P7O9`H))k%v}Uv>Rh_C%%Sy|_ zdT(q;!29b($wf(TVQ=9j?j>#~Rwou#sIw?6iaailGoh~?C&&p-^-cBF^VIX4aGh{r z8~$zUZR?P-A!UG_S%0$nar<%gd_A8h;)xcD7m9~ThDqv4>q+~``pNdo_sdxdmf~{ig3kRh2lnao^c}kL^izEnvL~ZY_LJQL2K5S zHCUhUMD;|qIBRj%PZ>XDU>m~wiuV;`Wn*Q%#J$8=x2E7IIFlHY82GMFUwAidW^`tB zZD?%>ipBns-jUv&?w#%_&MD5pw!zis;GL2?B@ZkQELi`1*?if&-n8C?o%P_>V>IXu zdUw7%e;4=&6y_D?jRxmHLw!TN$S5-IHSIO^D(F@4r07YJqr_3NrhH9#FIz9$Bl{zJ zfwRE5(!J81@FYCti>zX+ z7@EMV+wD5aJIcGKbWiE1=%|>HIwMt_CQkFG`>U^Eqspk-quHZrqHCg?kv$_D>tC?k zEC>Cv`(^LZ?a|c&=e6gxjlp8gVojbpPu&#^Qw>w?&)lEcExlX%$<&jn74nMe_Ncdn zZwY_o{>UA|8dCi%{2ufnpAerA|3314gd5_9uzhWgXO3sSYrbojW0#}YT5KItHm0m? zN!yYcmKhdLp{Hkwt}*ttURSWg_Fujh30%E<|TD9>ts$-O;bVFL`@%U zAMKyIKXv_c`savq#kr4j9_QGz?b+qJa;R

)L4BXtBJwTfJM|5+qa!)jBXGYf9F{ zjENa{m3Nf|DFrDfr6;BM@_hlffQ$WoufV${-%&u~yM!{Pj7<$s4P$+X+%NYJ@eHYc zCZ1xSV!v5_vz%4Ns=k(2SXNZm`(x+7@de`xW|?Q12bl($CK@LiEe4BWJosAwwH^yH zV!c@3!qCDn&N$9E(lpYPXU;RfQ}j+zuaaIR@Y;15-e>)GzkO82s0yf3bz}LnkFSp} z=8yTuhQ@}PMw><}df0$YKtb9v|TdnNZuu3N5K>J`;1x>9hZV61tp zd7x>a>6!7FF&|jK0`S!E)X)!b!6W@6{S`3OFw{_KtTYZP7*r4~iWcoH*;_Kbe0uo; z`vQCWiuM($?o>DSGacm_^>qrZLYt+@(qO$-TUA@t%gmRV@LFd2 z1?2^0J4HJMw)vkEpA(M|j1WBFJm5@ZPGpXyjinu{I##8MtK#29zKdYp!V~`!|7h=M z?+y12H>-kGfpzm8tR1XV%chojOS~oD7k^*e*V5O5FKgZ{xLa`8eAv9fw86B_xX$>< z@W?O_IP?zvJdh1Aul^M{3=TtUQ)|-?<{!)jg$0GsrMjeLdCT&3wsp4Jj@pi=&Zo}T z-LJdZUbYw8Wj_sm8oU_3815eL9>@3h@m+*R>_=?u>uDC41tY{G#Ocy>sT+JN`&L#Y zFOqLiY)}Z5Lgo8u@26SQt?B17&t>*g^;3;jk5=bsax@aHMB78xLx*)Rn9sBT=XK|G z?}2h{xwZjlt7)qls~)S?tMsZdV0qT^EPPQ4^QvR1$5Qe6Q6Lk@+KbzZu?_JH&KH~y zm>*PM+aFOrqNFF%6KA4lqG{o@ur{C#JoP;FeCqnt)z8t-@tyTMYqzp)W!SD++fv)I zu5evp*MhDE_(JGP<4R*wLsP@s`nUCW^Y7+=3K(Er-n#0tBGzG#$sd#djs6=w-^e%K zH{Ca76=oG`iZ#Wn%2t&7UGGx=Qh!!3D<}y|!iS@Wqx%#4 z6Zjs;62=n7a`tle9o`+@IpI0sYVqp-Cy$;hn=AWO{;Pat%E}ZxZ#JiHPCcD=It{w2 zWz5K$ku_B{RrRO(Pc>9I>gwjy%^8t9BKHjV72E|Y0G^w7vhQRU>xy+50J_&{52+8S zH7bp2ZRXm{v*~BkM=3`sx1|8-Ht8(UEKw>yl|Pd`la1{=C*U0_e7C)0v||*nrx*Sg zewWAP$#7>>U)yc%ZSAeCt*vjBy;U}>WLU{j%TY_;qP|5KkC-`TR)CqNnWl1Mxv@6D zcICDDwfZ-~^Ze)ek-SLWD1d(m@=X6s&oyyP5p%?hFK}Q#s4L}H%8hoTeUfvMb9BY% zid=WD8~dL3^7r!Z2<`~>iu8(L2bvkQ88j}7%NoTQ#le2F*w-ynk}1Js8YvqoTQ6TP z-=f%}z`jV-bZYuR@G#?H#*M5SSu@o$)g3e)G`|7A*004fB2>ZU)X%M-dphTIjv8#w z-d{x*J@N9H+KajxQq{f2$4b*!~+S>3W5#W#wV z7A-A$S@5#pl=+l-hiQkYud%NY%hqx*2Ye1L>MvsPPR|BY!3l5%XboBe_JzQ5J3fQ= zDehB@ZH32d$81}jTbhu0H>*xwiHvf&Z83g1H#v&1YBSHz9M z3zXPzTP;;f^JICl!6}1NiWS9*;mYC4HEC*#=olNlVFN;bS587YMKe>|YtbGVt9~>?{01?1R{i@QrZCV8eaC%=$!4;#tSsvvrGJ!8DV|b1p=d&pufSJu(0tI`)zsCbHENAm&e;aAom2<# z{Ok=zgJ}TEMtC2^a_7&cpG|uT_7ud5Vnv)%PU&9jUaQinbpGM`!-c=&Sl?LR{lNVI zK3fGN!3g&I&xQXL>O${Af1C9-OT|@jr2?s-j<}BawDh#Jg}jBlPD-7WW{PHtVX4DX zTPRy7?|_YI8`H!Y;tWa_C2Of_sp@U@+v)(QrLCo1pos*TwN=!wj zB3>b{u+m&<9taMZ4w=px&l-yj#fE+03it(V0N;Rofb|k%z)OJT^PkK=nN0TBxzIPh^`aAw+1S?BTG(0$#UaTi*(TZLl*=jDcXM&t;xu=ZJvj87S#@<8@Lc1ChWq7tb@ZTW5agE@maTbWy#PMVW85dN3x_xSJeF3~R0 zPeY%Eu+O%}qw!?BvRxw`Bdgn9`jz!7>rm36WSwQ5#aZYq6cz{znwXlHo*AAQV)~fA zJ?Nj`KmUuoFY=m$FTquS^*&gwv+Yu{_50MHOFg?`_B7LY=g%BPFQa-(Lb^JU54i2=HVTY9T9w$ zR*5!BHcFbyn#&Hz56EjNYAL=<{W5i^a;S0}xB}`!zs9e@0k8>N0oa!WKaW$6Q+}rS zOfgzMTE17hR|?gTlKGgOtak8MzNQ1npv zP`Fp9R|v~`*?Z~1Qd>IdovS_WGN z9bipp4R$xizu5>a0?wc__#?o&iT3)X)!hu&Upd|TG z^?UHsDbp#qUi@#Qd9-=7o%Egb0n7o+>i6#17WO30Bo5}6ivae${haeTCk5;RH@G*r z*Lc@>Sf2$&M*a=K4Z%X;Lg5Bb4^+PgCHPgK2M@t2&jgSz-xhZp>?6@ zk?9d^d%=7L|A+20^)wY@iO2C8=QR$#r_)8$MKnkOB5vveTqIMDvwt8sXih8Vh_vpD-*43#Rj@^DlERb8T!J8~b@fvod`HWdmhb zVpjs|dizEDMQ?|0hwxqTwZ65!N>8N+`vTXks9TZi$aM_054HCI(6!p81{bUstW+D- z)(~8?Ub8j;5`c9o*w2M)?+t*FxWiUycNbkO^|{bHo@(}+l8!WVI8r~sdLuz)brf*-}D!uH_%-417l59 zj50>aS{{quqAwd!Heze^*611WGvc+ywZ#XO98_{msWqjRm0nhQYMH5J4g%x#QNUcb z&oBfImpELae6jMy?!@1TUlqG57F)FFH4$qf-WcDY0;rVHZEzcMAPb5aiy`Z{FaEcf zk+o`T^=nb_GC-(z$=B!W`MxvHwT-cju{E?av@>+pb=EP*aff1uVx@GY^e@q0qA2uE zVvRG}3A$&Z##e1sTko3hnwi61HLGgYw6tky*N+@6Fz37--_B~C0hvDkVT4Seov z0O<+o3B410CkCKev1-K%5(^UN!0!paC&b3b#xu91cU14FViCn6nj4!Nd+B@WSt~qV zJzo7;`B{mQ4#hI*GHDXJ41ElI3{>=1^iFe5b5^odvhlf~Rbi__gmcaL_bK)QpuEFWt)499zb_+56-_5_94_Xdd@Uj$*w~n`N1lC?=z#Q~i$brX> z$BuYcyo*hFn2UGPb<#B#HURrv)CJsHoZq>=bG-xRzs`X{ofL0zpL(RqxFe9pxS6 zO=L}Eth+B17m81cPKsKFTZZ2T-v(JP*#hDr-=FUv1G{~@g*te?ZUbEdU2ePEF1Cqn zQmfSZpy)x-cF@2A%L2=4cnRD)9WWm--_O6FzbJ1}-hh!*n8CR!(2cQ|%9`ndbJKX^ZQZw77#qR?}%wY0UAHJQ^? z(^QSLjkMe&uQ07J1tWqHyCZi;N~5Gv=V5j9>S%<|Vt#-ba0jZyR*9Vr^PvXpjoBMx zjkZSj1GFxQj)BXN5|a{BFRor(*Z8jS#sp)+Hi$}$N}LM|0I9DD&*GoOXT@dVDX2r- zzSw=S+hVrGG>C2xeLnJhBx}KJ2AhE~))ZBWiv3(zpI-+(kL^# z)_H~V3U&Fq{LVR@bDCu}%c_x4BO^C8Hj@WuTdOHTW2D$WJy*DBd5%8n=$yf1Lv0AQ{^SXSjeXQMU*lYM=`eI`4 zJJ`vdEz9M5q#-+?lLS15NPHN7TyeoNK3c3^^b;8^ZcplWq(#XR9&m>^s zYky$QE_)Z8fOEk7-G;7)u9lvb9-jHO^|$pm4K@w3zZUz7mXei{@r=fzvZ#`@Nm`UM z=qDK_8S0qom>NemjtoQvqL#%hi|G~DD~{)kdByUI4J|RWgayWw98s8s4gz?Gl zitdW->h0?5y6d{rhSLV4$!L;A$|Apy{yv&@o4QzCY<5g`4D&Ir#9fIy7Jn?Bb##t6 zN8C^GKgBOdSddU6u|#57V4V}=BzHlKB0oNtb}!z&czntDl6OkoDRs2;Q6Z;4u1s8+ z5|CFqukeLouMlF>+?x;g5BJv()DO%F&It|;4-KzE&&L7ivhk1X zAK663M8!$fNfp9An%273x;$8^U#VYjSa0}Z{9<&N9H#vd`y*OJwusb3X;3x0AgU$& z9r<_UY$yxN$ugJ>rcZ`X{Kn8t-%Wp0dsEB%@n^+n1^bhYk&cmaU&Y#&MZrbEu8;)m zXTydKBi$q2JRdpbIOX6OZhBF=(9?x=c>O^ItZOU}4*;!S3LjY>S(+C$FGAZW>vG$2 z+h)gR2kXZ@_^Rcv;HFT@EtF5A| zqLTsR5-|`3wSf2X%CHM~|NmG2uYRFnpC&5$Plg-T@3P~@}i9JTf}b>mvLrvQGZcbM^C6u2r)a>bq0cgAbV3? za9?nLbbNGFwNwc~KmAUrj&*snH!mCfOknwW) z(_3KPK{I#)fiHnCFTTF`ievTEgXss;YiHKZ#3Ni*>DX!XDDZQZ+vh3A>xOKzasyN z>>b@Zx<_n}*k19y;%y1G1m^BNEB>tbhLRgf)-PSZG;=A(Lp9)e`VAOXb{H}P&y~Fe z*}z=bTk?$~EF))(uGbVa&mS!Y?1Hc-I4y%||EvN~jR$Uyi$6-Vb^ zk0l>V9t$mD!8TOv5$RJhrewU%e4W`R zyH9p*PHxVWyeYyt@J{nib3IEv%jBZTMM>5q>sZ@Z8}B!ay)<(*a}9M575a}f^)>ae zPvqv%=FnU8No75JJy|{3SoBq#qL`v+qimz}gHz>H?a=Jd_;r5WZ^qw@iy{_9tcqME zCp2eQS?!)dxK+8qf2j~ieor9fA z9ZMa};SkJq&UOCc`o*=xy~MrKv(t0cd(}I^H^Em161)js=I5@0b>4N}6km!jIuISu z1U11FSQlCs`WKixc^J@cPw0!@2>nCHqTkhz(jTQ;!5IA*J$r@pfC41x^@G)#)tXD{OKLxQRWDU(2nlU$RZrabOKc_B*#%YbyN~M=dubfdi zV`1jP%*NS`vzed9-VCb>Ru!lV)rD+g%>5yITHg2G_aZet$Q~b^0L=A}=5HTPk&yZ(ejW=^gewY3(eHnTgD)bh5n>w31^U!lD+8k|W zy+R->ko73zQ3jiDc1`V?%DTX9U$%WI`MKoh5uZkUN`hN3?enzHtVLp-R%BXaTKkOl z8GW+)WG&BGo`aO+{Cnnm<~HcF*4@_K#+*p@ZMf*VC|r+td~#R!RLAKO(e&q$ED@v z<>f0BD-;`*8RVth(bf5;im4U&Ze7juSh*>Bn7ZSgkN zi5e^h%P4pbtRH1ujkyqvwatd4yrjI>Ij?iZ!in4y!t>bp{PCzdT9kjj;CunkZ&|}T z6BYx{AWcq_lf4#}`j+}o9v>JM8Wv*j*UqxevLr>4LZ*_bH2B)5+oxl_6Z?^%1yjVw z$d8fC9li+XU=CCROQa?8EpRWj7uLWDxDTxLO-9jdJE#ae_ih^5G;$X(V8eC1SWGdt zt&Fh&^D`E~MOX)?qfbW}hqs4+ z5Bwf@<9*}xxqL46AlX>7v1qb+vUzjf=Dg(WWFZe=QaYqfN~;8Qf#W+*Y77+#6q#q2M` zJXrRQ+alW{TcTK^V6O9h^?fzk9%}pR`s?sGt{-h2ZCqtqW#any64-BNU(~*+bv#a!EZ%6iIvf=2R2a@OIpx9b!66S)fN!xpFqtd(P~IoilbM*wS0*+Y$e zepvrp4-$cOiR|mwTHadj0i8mpXb;ns)0M5%t<)$R*WmF==Yf0rd-|b0Q!|GW|y;2Gc<4l&*s?*ZWXUj9PZN0Ne&${aw}Cxqxfbx} z8MD3uLqH3RgF2iJ=UvBL#~Aw<`)J!}yy_;Q9}U_#*%nzBSq;z`P)2P_ftmK1cB8|{ z-{xrIYT{b%Uhd|ZTPJTP?@-@RpELj=X^1_laO5D~D%~pWk3O&LwL4ioS)HxP)*R6u z(cb|PJD#l_z z$v(*y#|ne17=B|AU`<;q#&Mp*^BKBA&OF zla-TgkZ+KuDbf_ZRJ~M;#hlTe(KgpN*E2>}!Bj!W=d?%JqnPi-Tu!8H#Py5s7vC$P z7b-h|fOkcqUvYx=u9jE3YD6MdX|E zO?(g8=im?hA8e1OZ>Vdid#ZV=5vfJ$amsPZ{)+yJ74j8w=BG85HkQ5>zZH+b+>Te6 zOT-#n{+}`CSi@bzea3ml$sG8K_KNm%)^paXMOBMV7oIL;UGCug!TIHK%jM#jF>6oe zp3Ep9emw8`zVQ3PTb5fw9}?bg*}Hk3bDlHTo$J>6w7!9XfdS4gVxLf#%q5$pn5DR= zyr^V9RHxRdWsX<@@U7LK&T$Yoc1L7H5UBLT>|a10Q`KeNwN~8{v*{KXN>B z@EMUkLwG*LUN0Z=KIHMjOvz5k*5qi=3F}JEf4~?ue-5b~ISYYb?8ET_BJv~hj};s% zK>43}PT`zFv}mxrf(}I;gnlGripJnn_)F1Y>tX8;wjXRK0I5y3)ArML){yT79h|qH zw-0m-bf9e2ImkW8-3T?Qk01pz3^w^U`O5^$1X-IU4vWJ-i+&a{UyprfdA71ixk>q4 z^;}g$Q$xcTG3$NKfl{y3kAS;S)lk)N1Zo;<3hPF)F&R%TPmLEL1!&2x9 zXVqub8emN~Z(@y=jg_oPKP5jU-vlFIwQRMFXKMVcEP-CYellyqYr>_2rGxYQ^Ze_4 z>wG)CJH5j^!#q9RJ>478uknrZjZ+De9g~q^QPIIgW&(_|jk3jAUv_c0lXWL+JFJF@&;UvRpC2>ePWGMb!koe!-b-+7SkTAZ$K0#1 zSK(O8Sc}f8v$8&Nn`4`U&#u2fOIJ%5dw}p65-o%M>VO(Mjdy{+gMSD4cl;akrN)cK zHJ%)Jbbo>3*=6{pNYb(dk8 zewqHb;ke;nJN07t9yX(R;Ufe&PJW2bKqx9Ys5e{sp8l74hEWusLk; zj(EodnCYD9JmNayYU^q1LHi;fO3VE>Fgxo|_)wU05ZDttEDcLf$xg{ca*@0(Sb=B1 zJyktbI<-#SA5OtQ%|Olf+V7Etp0CYrb{%w(ZvK*0iFuqOri& z3oRrpymwE9j=IWR zBN%KQjBbPPttD+GZLMG~@IG?Je#Xwf3reTZaqF@3wd=L3wWqb`viGu=GlP77pZ~ky zcfq@%yP*c61|sgy8INGEbRPyhTvlCH{j2_0eO7Z;^FsSVYtz|uC(u(;XVBqQIw{nf zcZul2&}+mh;B(qnV4XrAP(&yqUKw8*|AN(~)u!l(=!ib1J|^a%oY9}rpM-4SUSXPU znr@+Xq1FWKt5Fvi*ZxEOhkB}Ns%oBcp7I)IRoLZrwkMX`q&A_qc1_GGxFEhD%z_lo z7BKUvE@t=D2-XNr3QP(d_8%6`?1y`Yd%yL3>lx!7AH%!9}$iS2mAiju-34C zM8O+t)ImgK_Z!W?ssxh?Siy*Gbvev7;oc~x_(=Kh)UXU++D1aY}>xkrG{*e{`R zeq&T%zRG`G@VJ1ziAolhER+M^+Yy!#7OsU~Y+r2L0J(t=oBc3fB*&BEVLUd^pXXH;U&?(UH-@ zv-n)oToa!^*r4=`?u@RDwvBeHdaHW7a=UVse3krw^nmmw=9Pu`*9MuT{y)Jy>W+;jDF zbwCwRO@LNV30^2)pyPa!vMeM*Rp348SKzO`g8{Hnu~GQsabhUJ~j4K>h_}u*5Tmmflmi%RT%ku8#-pyqm+IRWi<>MH*U_G=lw=y>@ zY*?5M`LGA>19NYX%3|FE>?896Sa+4<$Z=%3vRrRHZ#}H5`#bP=fO8r8VCExx49`QS ze(o{z(Px7>N;JI%+ zaQIONmW>ndhNt_rLQFm}i_P6jQ!Exgk`(>=T0yWO{3 zx3D8nxTc~H&U?puM_E{AUuN$F%-!1qe74?X+hp@vz1F?JSQPgSM*(TZMJd)4>jyNW zm|~w|XK&h0j!r^siu<_cIOFSK?_qBMeq;sURsjDfbE1Y(%aj$Vt#|)r!%&OTP z+#M`~=1dL22d^9kOL;v8vGPD_5kw&E9dd2m~iCJuBxmk|m5*g26T8CSQuLrLO*P$0b z&mlT`J9?+Or@C2BH_b84kzh}-->}}WGB-~J2u&6lfqUFaz+B!Xz&(}{cn>-T%(cD> z{5({Ge+vFVX3pw@eZUz3vw@!-et$^8kb@tvm;Nt3&+s;3E(Q0ojZBS9Z-9Bh%=s%FSsE2c10(;1Fz_s6U&OwMkEV~N zOCZ7kW9H)}nUYK`j4g~m8-6zQg#|DKm{-BGZ9en(wSFO=a*1|{_M+yZW)*U7$6+=W z*B$0+UcyYbrkMY9LvllMM0`Zd*@as8IrMX=SD;s5pl_g$`y1v@%yZ3iwR5&}7IzeP z@Y%4yT3|){;i7CywuL>TTxOSfHg46GGj4j+JddShV(?1X0KX4o|snYo|t z1cM+27-xA=^rC2rb&9Y*xM#g5?2m8TZrj$`*V%hHdO4ng6*wfQ8~g(n*aeKq&jHpt zH*`0|w6YuSuTb1m+>-~@eARr+QRi8C3dD!vLtDaI!Y+|ZB$LR5d7=lU2c`RD`(&II z$k|OiZ=J24tyXK*+I6~hx{vyg`saq{2A+j41;&CIb9oGBU@#N|v_BAHE)|RwjLgGA z8H^CSk)kmppGOA)@BMr>!m*F`Ds%@vw=aW6fYvnX)9@>B-WKC7Y|j*-i4bBiFH|p7 z`<45ZGqDzI#d$t!9{Bg?EblFtY0JG2dx~cSGlHW7qXRsj{nq=fH`$%+9)bB7eCF$B z?`B7ui47_6MZ8zk0PgGfp4>FwG`}x+FTA%I`5F0*3mO+pfXeVW|8qW$(DRoREGbAd zCn76tmH8|1_px4rXNZN+&)U!0AId;VQA*Ky;GTUwY=S2+!aBm5WJ|J5vrn^+b&PfN zboO+1c6D}*caL{p^IY?^@U;-?BUs-wH#}Fk@9>$2GhIu{OA39I8>$+r#%acBCg~>W zg8HC-5NfbZ5vGU=Q5B+iHpSexr@*|TgxG}G39#;e4#pmgeFxdF7Z_*W8nYD<=cX~Q zqhCjNfPbU@jamWBVPk&o%!rv0Eln*=Lybd?JXdj`MuK0xbiHt=m+KgVxeSGxLd^}- zOsqjo;Y{UBWm!d81?Mp_2Fo*FERiCl&xV-GHOfEA&%Ex7?u%~bgjgIF$5{JVyTxj; z-YvRY^u_XpN1m1rg&lG^ErElU(8=FQCOm|2aJV7P|{Ko zQ&K)!I9G{#0p`Cgv@f(X*2elJ=Ak?Vy-SZPWQ41XyNtV(r<5lJ+I!o3ufs~;O5arf zRN>t1KmUK|RJhLn5?)}gk|v}Hu?7`K#^E#+;$IVA6Zeqxkfg#D=@ntm9h3*<&lS%V zo0XfDd|pMVp{671u?m5&Un(5ZAJVr&t;2Ho75JC=7$z zkSEKNodnK@L2DfuXPj_m#CpkkNv1dxUA_B>!=f;{HD2V?hOp1z=k9snIi{mE4zLFZ zXId8X74tRpHuRqLob^nBSm4~ieXf13iSQ9PV~A&Gr-5fjmothlYlRSU1-bbDlZ3ZGdcm zY#ZjfWGFHe9aJ4ubJTOxjAQSE0hnVoPd86D7xP@KU^EyJ#ja|o4;Iwh41xm0pMB6A zXFy?HSXUjEYnN;H0KdNmIKPRtU_;OS(rWk zJ9_#tkH3qji^qkpgU*A_c8+$As`je(jkb-5OtiOgzup!yi!zH;R+V)oJO;*?8`&D! zR48hw>8R<5a7H*M!V#$Ms_wGF3HJ#%&qNOZ&%Rkm5e+7g!B_N%{yAad(<_q;8 zPu)-5r9Gw5A)^*s@_R%u7+6!-+S}SY7=DM@zS+Jv{x|+_F;ks;%Ez!Yyfl0nv*k)i zN=TSX@;ho?`573g9I0HcTCU<}=OXmi^w%^(ok9`x)b&IM+?_f%G|@NF7l&QCUBZ6+ zE^E81WyNKcrIn?1By}XLeS8>x7@iTD z5n?=cd|-UwkpGaMxpT~?Xy9$&We$67%> z^K14Z-vrUHodY&At2CSd6<>=1(@Ry2|kHW!W?wwG!(!`_#NKBK*d13`>z$u$6{P%Hk4A8 z!nC}jsywKsuBN^KeKdVAHSDnF7l;S;_{oBrnwrATt<|j6)CcC0@R_eE%u&u!E>|p9 zw3oM+r$|$z+}D-{-h0>!yN{@k=w|pPI%CfkX3Vb+tqyfX{&cQCS6DB@zOXPa{1^W( z{t~dvw+z`QCAbXvszY&o9oyH?&=!y5KJ@7W1H7=kuyp`A^oKm)GbZbbD>y1RxVPQr z+UB~CxqEj#fLZ5%`~LQw_Mi6O3)~Cvn!>neQIa@G%pxGJTaBcRq{n5)WqO4km4Z7I zd%*^rfpY|Nhgo~_0mf*?@JL3(e7h7)ie?w^x#2CW0F+^>=K}Y^*ML2v*qa|IN$N?O zNjM#JYr1K>X;;7*xCDD)C9H*`a2!Se^YZv-8ezJ6y85l^t*RZcH{eOdNyQ?}pym9( z)za0{SJ;ss6(1F9cilmEkolu$F>@R(QhaZaZ^gO0(Xhw8$6X3mxKYR`GL>=v*0qM0lyx=DEJomKGbp7 zaW4SYdLMQjM#sqUt`krMtkv5Ir=WzpgnK`5UG58i0rO)X!W7>WUp3TkB*V18v;gm? z%R|dUyk2v~x#F#uZN43t+jl{BL3U4ZPm!Wb!KB^)*xp3RIz4_)c4~KO_XFdK%)kE! zvrl<%{T|ln*XYx9X*#3cD4g}O=O;0@h4<3e+Sgj8PKl138`0HrgYZ1UShYvv(Nw?` zO6K))ZSvz7(sXYqN0eVSsR1u%DfK5T~fP~KYJ+8nAw6W9!; zZKW~QWR>jz{0?sc=_YJFX^(||@CK?ms^M?Y&2bi(ue=>IhHH3h;FIt44)6`|wf496 zzYn|*a9$3dyLO@n*hle4p$;}A3(0u?x>mVX$Tb?Q9jxVRtw9|U-yh~zvybv5(?F> z=V}VPJ{AME>DrP|SyNfV`1CH-F5&&Ej~;bASKT26$qvb8@n-QF(Hdb!`>fEcP)YQ1 zIN?9xALSe6B3nWYia*Ptup6qayBgMe0M`HUoRhfKCH)FcwI;r;>^A3=##+n z0`7?z4=AB1q2N7>vG-HJwTt;db#!%fd`)@2#yuwcv%Uom+&yMGX6gVnfO%oe5kqQ% zF%vjXhVh3DHIhO#JktP!j z*7rggn5dd4ypLxUXB8>(6g(l9lvkEjmT?YyM{!3n`#Ss=`Y*(D(E6xrVmzJu!%LX$ zd>OO18S|;)tRkHEgl%CSmDq||i&@7PjW5EZsAUOg;ZEV5!dzhQ=2^ga^OM3Sg_i-_ z)50W6lJKm_daEdFlyxmIR?7YG0=Nsga2r+ue+~a6+t08U*w-o=4UbmCRoD$1!2;({ zuf_e?4$KKZ?&tfWk7}kOQ!!sP zU+6c&m-5h-8&ez89$-$=65!0g=`atv0%y&(glC3l$fDV37zd3( z39t39F%4)j!!dfsC33VmI4xbMZ2$pHK=Ti<7JfeT10}Ey@hN)X*_1XVH}h_}n<+MO z=58?7o+L?sBl!6n_@m=j`NT6b1gcEz95U;i`^q#BVA>kWu5FZfl$1C z2WDJ!1NIMModtV+mIo6UfbZ)Icml~#2n?*rieyEVpeOMCp9P1Zw6!!_U|LVwPTHE< zn<6^54ihc^wZ}SQacVKxu?U6%$_gDgPO!Ikw0Gpe&(5Eb8F*RvOtx{g;UlN(v-`9A zF={~$dk=f(Vjf6;e}8`))bw-=b_{L`Z3;z-B1MzMlf|PYqa`(@HKc81ZDgF^&`a4% zIA6srL50z=>RH-Z!g=>?{cV;H>v8mtsPugU(n5`AO=nHZ0O_Bm_o%l*nhYYajo5b2 z^aXW#M_>o6f%fp!@D!N{Kj5@9+7Q-<^%<}hP~xns35T_Zwew*$41!CVOPV+8H+X_9 zsXm0cn~mV6@}{x@a9_hS!gca>@|T!I#}8Cc5|miQR`DazBN6L_+K1YQ+?YeL$G^wl z#n;7G)mv3K`{oSG)~?nrv>A8u^<{37-|Dyi2rr9X7EJ*59Q|PVAbc+CTIyONpgK$f z&Ku`i`xN-_whr1`+gtgPF?X%Ly}tb);NFyr<^bma=N`BZnZS7jjbSQq?Nqvzn0PbX z{Rpahs(NO^31IzZe{X*;!YID$(8u4$?*aasehB>#x)Qz;zJosLKZ$=5SCUkc@LA)K z?2wFSHSFcdJv={?A$3U2+Q;_Dzhw>xKUX!3HBjky+4z&`Ct*G*bNXuo`#DsG7El8+ zOc|zGfUuv5pIzp>F;>JJ-pBgKLX3d3iC5@W=w51HYRkeV%_dDP;3nfASPFa=`Jnos z`U9BbHVGI9{zdtVl4rl{TlTm7Z@CoQQn&PhcW#n7pG8oH6)vc=eA5XD<)_W)z4Jj)9}WoKpQK-dkbkcdP~=37mG z`_SFp-JJ#Ojc^zk_aERL;AQ^Ld8py9;okve&|LcgEDSCT4hRhhO%6{M`T-$*QCw15 zQd&Y*Le@dvLC$Az?&l||C#mab>S#W|G3_xe^L$3@N9%chcL+wKmLSFyBdn*)P2gwq zFJS&vFJQe-EF3o-#|qrWl#imM^^gdQ4T}x$F@K^Jd_<#?CBU=5#oEQ%Qoz^)=X~&e z9j6|rKCC*-@r|l`sC8q%3!Z<=pq9Lr{5RQe$U-hBoPjgPp6ly$@pSQT=xcK;d@Gz6 z$_ufcR0iyeTMKouEqyJ0Jg;Kj;(GLI;_Fy|x-$049f^8)v)zm-m@|aWD$fTy1M{tT z=)s;741V!`*cf-$O%ZLv$veZ>Bqi#LN4tRNQc-*F9mH_daMZ8_4g&io^8U*CKg=UyZOB+)t}p9;M8I{GbAp)5wGx_w z8uHco>bo!&c#qV>4CM@EE#S?QxfvMsA>1!}$a=_Fzpwy4NIpnDi$4o%ZEiRhokCiM z4}=bcQiG{Men|NI#oSKDOFwu%c*+6$b@X!ea`Cx)sAH((k^PaqKX5inGhiQtj!+3I zKtteJ#|&5vzr#OZhsx-M&ivKW!2QfVsPCwc9n3ig(yr0@u8VUeaLv`ZbgrRr8?c2( z2j=>ivfbW23H|~;N3uuQS_r}u?-OqxW+Hn1UO(%QP--CbS!164>+tI^dpf(J5wfiq zr{?|hw(PbHqcMb@E$l&FUtM240)6?%X~$`~pM3yr^lkJvppl^wR?vMy?E}i)gj{02 zzdeEPF?*RazM5&sG(3Sz@Dt?dbMzhHzV5zIBl-Y6yBJ?!9x-!Z_QPorLlxK@t!`blJuruTgiNGGP2SmVn zoc+H2zJNF2Z3T?AGfwc{_1;wx7CIL?zdF7;TEHRuA$ua6x1G05fbXH@|FlAG9%H(U z$t(u0wPL&2UK@JAEI0>V=;G)i)b4VhQ{7qJxdM=8k7(g~p-yPDdo)&y^}>wrgYJXw zJK%)&p7x%r(8$}!dkDDpZiRvVf&On%%M=%k3%-U$p+%uK;WpulqKYD(9r2p}1G53< zOXo{@rc^>+0+G*Ld9or|;ZypQQR*l@I;(k)W8UQ-&`Q@z_XO(d>*^Q5KOi=U4V9q| z@C@IqH|wv%CYT1i7R)-cZXuKhKMolJz})bMFdi5KVk`owvKoFy*@I#T@bJD997b=T z`oJDO4`2XXlwXv)Wp3HGutB;(%6yn_fzO+-M6W~{;f!!jD2HhYp&`K`!2^K2&Wj7+flLZ7~WkT?4ySe;hqAmHbVxf}QF_w38z2WSF}Bk;4#`|gjx zZ;t@;+gd??m<$IX4I(j|hwJYQcnorv9Nm*kySl+8sOPSSZV@Yl+_Zh}eSGwB^PGh_ zQ$v9L`4AfQje!hU<6qr68QMzPN_0}4l&{TN`C9ox z#X<$^NpHh@)q52`LpL-xG{w=FjGx=Lz_b4gz`Cy*`WpHq;CsyXaTojw-GOU%vMyPO z-y@|!|5W!B9e&E_mT8yagl2$tHcSG>e3;KU4@N>y;5}6V@6_+qD?ka;(8H)eSswgfBzq@w$q!$sdkUwPm@ zWDe?aZ@F)|n*i^#jK3Yl`4pc|-#Felw!jeJ`_}A#>N@H=YC&6=3de!>P|k(oY>m~x zwKfNgXzKYrEQPbcINulG+S?m=#xe`oZ(szh1m;C>|N90ICPSBpy`I^q9p=7(_Ysu8 z`xio2)IoQ{j8*pY$pzMIAstZk37(6ei*HG8NsdX6N%zS1$hOP3%NHpYDLN}VDJF-OV=3q#o{^UTmJ=&G4cIF_y|$F3R)vD z|Ew%LQa{3z${RKF3>$(DE~_uAr@=rN0sQRNg)B7n-3W|(uovolkOOPAaa5+5E1xTW zC3__^Ks#wWAzq}D=p?_0e-S?rJrHGvGll(d`B3=~&pVzVH?u16Gk{cP-*RBAo#%=? zqcj0~nWVeYU6Uc#nTscq0YZ(Y*Wq=vLoUj8xC#FPV>&fmHHFW8TUT3`7QSG924lcq z;UhePr(lNSuHwkFYKs4|Ehgo(K&4<4;m2KEU0e&`A&AlY*#x`>SkJ|oVtMeL=R40P z2*57yE^m@A$yXNrR#V_y;9Ou6dj5|MjSagPsQUd2S=QYEjGYo-Y z&<1!e!Z^Yj*bR&;@V}`Ie4oDszW?d!bYy7%A$)$9puTVld;`Z+$5a)8Jy8!pC)ldk zsyHe?Do>UrBU5y+%q4Y62f;$gLdkmZdhv77b5R>O5k3)qA9^49h~DU_fmAL}fh2#D z|BLU7Z!%ze;++MBo-HU_DC*-QH0;mcmvR8eqI+GrWh| zp4y&ez<5Lq>RGve?(XaEYvym}FBK?-e_3i^d2qRqmv;+u4~K<^g@eH71=iXtB}$14 zo?*uKSlL)vE-o?C-^MUu~w~z$`R0D8|m8~kSF0N*etUuu*q(cN|WW|F7*i(aj zV=90O-s0TkF7Wr3QkPOUg7Ux|;ji!-xJTxnwFUSYX08SQ+)uC$*sJdfYJC^OkKk2! z(LJiW5T|g+9H`)0%{I@nxzf4P1Cj%hE2w$O73GQ=!fNEavBwA=*F*h-{e`}J4FU}U zyZyWU9-qh84|qnyGqK9RI#AXK^KAOD`?32ba6h{n=E58}3Vasz0nfCVZ=3{NcX{5* zxI5m+z5dKz9UycT#U!S(z&YzKaO9sUOXp4RTx!e{%8=Zq)G zo8&D5p8s+G7=s4S%xUQx>>GRlJwrW1#;`G*28{3XJoO?lF2%KvuNC`m*Ok}BC+4V} zv*=F&bH$mP-5ZVp&pm&FDbNO(%gyzb{c*R#Vqm^Xd*Hs9YcS(V%q8c2fw_ERfIXO= zK>^6o;EwC{L|6=r=T`>y-{r%TN99r70p6=C0}~+k0&`$mDOxE8%LmJM%67^^(vWll z+{8Q>u3K@yI@k1YdU!0{zc($m3+Mk8dE`n=RCW_d#tk zu@ej@@WByA8_y)K)9|r6PGX|JrgfXtjdQf?BZ0h+BjsR<=Dg!q+yoORxSAGO| zU37zX&BGH@o05!?8*|0ZfEZYci0yunpC6R#kvAUgw<yPV-}4(h7G`Lg87<^WlsXm(p17n_eWvPU=D6y_y+j-=KIU_ zpR)rQ_wEC{m#|i0F)RU|&2mlPed8{$uILLa^)3}+mZN>6(beFEa1O-28iN9Z0-s?< za7M67s7mNH^bhyvsG{&6qCZ5lG53Wz2D}g6hT_uV$h@f>H1%M4=B;4@iPxz%}48@Uz?y`om`U01}OaDTJDA zb+-ByFot;^)&Td9ynpasu^mRhH^B3M_RC&|dFC1N4540^brS>Omh=`fW-3d!NVZ7w z&?liR3=$0z-3#9f{|E?8h9<$+;Md@Ir~up$-GQHgYr#MMfBeg!C-8h5?SK8Be4l)$ zVIlkg>;YwhJa3-&Htc~FFdt^ZNMP<#X@~$Lcs*Xvbr=JcfM@@S5C!?}eBqvQ)_oQe zs2{q`z_p@0w1APY4PF56>*IlE@QJ=eWIGSUB=>Fj8-DUJzPA(D6KErp!2F?0&^gpO z^Z^Ej2Zo;kbNpt)IYABrA2gCRl5K+w;ODFs^oMcDH`DX`XLE%FCx;h6Gf=|Q(9_Tw=mxB1c@caOoB$%=IywQkKj4|bDHsC9fcrznX+{9o z2Ie}Q23`Z*f%l4%Ac1sGy5}LBg7v_)p&K*tEyXRx+W;R`$vTioC8$d2AzcI)fx+k*z^C7$5x=mH?l{`Tdjd8kkJR+%M*H zuumy-a8?5MB8;sz0zQXc0Imhhq2!+A1+eev-@xC)eG6+O`$1z+!e{wsq2B8$ayc)+ zIAAPq7Vz)LJV4IETMIlN+9cT|DG9H|uf;o|8x)8NL@S^M@ETbG)!|dT#u~*Yv5lv4ohG#G>3A4$DcqBW+^a_lKZ$Luo^}{dtjbUcVKL_FLZ#W zP!sqp9}Os@@tc6(=RPJKvwv>DA=nGNk39kYd?9e3QvgUo@&!TT*Z3oV`{BC4wT^kA zAAx5t!{G|BZw%u@vw^i<&mjRb+NQzZ;D-2ce7Gra?|l?Pz+MRdK@D*Y@ih1o6cPop zRR&1*0N3m@Z~@)|`@%JciLe>|f{!4QiLhg>AZrgJU@36_`UyP18amuku!AWl{{eVy z9fIR<3$j70&?<^U87TKZQ7BqwUxdrB3--VX;B~nX20%2tkiC%YhM%D|Sfm!|uh0xw zOzD=mC0C#iq+tNsFHjA>ioPNnX^p5IB!CYIoNr(+41j20T#@U{80ZM~p%}P>?%*@n z54=A$0wuf&ya{ZBF2M7H`~Lf=LO<;P4Msva;QnAA%m6;$a@{Bcu}~bCBg*xo67a{| z-$Vh|BHr8h>&!I{;eeQXUan7EcRE9F7z3Mt`8Z;~*k2i#m&A4N4rD+O$_L5^M#5Rh z0;KZ>6X1LJ4cG&;a;S1>6zqm~z}KWN90SHH8jBi>h5(;q7>}$kt}p%-UV%wsl5_>` z0n>o7Tju)S1g=5f$i9({g5&TXqypnZOi*twZ!Vt!b07)$UjG8e;41Js*bArNAGi(N zd#nKFelqWV6tsXyFw4xyn0P5XS6`G}M5J_&YywmVl!;59z)4sPZ2^y4(sz<~m^l4A zI-T^D_{2W(A21v$L8>TKv;lZuiUB5^{S91uz6173y%V|+1~5-MBxj$Z^yFaT>e_+!RTczrtdXQrIt5@mE0?kru*r!TS#Le)!DAHSQ?zy5;i=uaj>A-w10X_b#mCeh&G- z`%-sU1($()d2L7=Y6r`J=fTN<^gv9J=pDWewMDftd3CesJ;=p!aV;1ED_{rkzJCU| z2f*bht{|x(X#+!ndmiRU;F6b=m6nyZhZ%4Qm_JcNRzubm1^{D>Lt!M020o9@1K#g= z9dKRZnuHLvoL>e=fCwl+od9bIc#W)w#lY*d32^iKN%~289$5d+Tq>T0Dj`FXA?#ze zNw%R2;uv&rX^7QSA^9Z!Bt8W*p$YJd>+UT$3EN>YOok+A4<#WloF`mUXAmnm0E?k3 zAdM*e3jJ)30AJ^UP!&SKknkQn4n7WEfDOR4i8<=5)u;_okb;`UGr;$ACCr9?Pz(6H zf|N4sK#Yi5#Rz#P+`G1ivA}+aYhXK^1m=vt1YQ%5;Nk!9`%nMp0rEZg-_d>e2l#XR z^^btj1c5}%8)*RSNzwyG!3sD5_uwTkUgQOy0Wf!D2mIff)IHo?`0QQAyeYnJWkh8# z$+Pir7*j6;b)X}# zM;-S^tcBqj>2%PFa-Z#{eyJ~Q z1> zqw;>r>rI5Ovd{s30^VOQzzZmZ2sC?Z1VdppaG#$7j3d;A!NB*C&x*%^`+oLt$p<|S z`B|UZ4Y+qZ3txeIeqK8!(1RS<8WpJuQk1|8&-gsYU`||F;P>N!zlXohJr~!s7jPZ8 zw(W)0Fb?>fp@EN*kCOAi=e~I`30U_r9C|}DC=M>MOZ)&C3E~Q#r^Xxd(e;4)li>Py;GJ2{3>o=s?u! zMeq#pd5pc2c`xJh8Slre(dHV%wT87itlg^&=6Tuqt*xh*+qdfQ4M~{piA3Y;F zDSCNi-t=7Zoap(Hb-riaS4S_6*xU1>XGij}o_kQ_+4vsO%_I8|ej|7J=!#K3YrEK2 z4*5z}dmlaIwCIl`Yucwp4~gy`-8#BnbVRfjc@OG2^yAToqPIsci=G%gB(jFNS9ElQ zW&V7}&bsi_?NfK=Y;*O~BJ;I9qvU7e*&U){mZT zkBNRHvY&RD=o>ja033SY&{)Oc2fqG|ukWnEto4moPmI{p@zH}KcFlcY^ni%%nMcKW zRP^vjn7s-*F7h1Ydk$l@`SvN%Q==0jea5rW??rzey(==-vsHUJ)`Mq9)*SZ#J{g@E zd2aoD55xd%x>(> zx9%QUr#~ioR`iPKFQUJRj5B9Mo)7KW=99Rc_P$g8551p?*!YRj^P-nTCr9k$jgjA( zzA3Uk@Q&Ob*EvzPPyF=bVwa8B*;S%zMc3KW_40oR+%URvbp7auBJtSeRij%*cZocU zd#7+zbo=PekvaS5NLuNRh^&hp`r3P=w?yjns)#*5J8}>Ds`ZRD^?f4!_{iw;(V@|Q zZT;8IJB>5*edR}@4@91Mem{Cf^ytVQ)GtR|Oz#=pF|syb?|!rK+3nBfuVB7&`!$hq z#=FD2N5-F9Mb-+}j?9st%-YNt{o2TSL7V&iGP}NhWLz8D{`Y({cY5^t$T)33p3Skr zCq%|a->E-6Vw3h@+4^ed-s#^bx?jZB&F9ieC%==UH%6yL=7h5%$K?)OZf8&O$OA_n zI3oIi=$g^ZBlfD!KN~$d@>|Za*}u-WBEFaSSoDSHJMxD#FB4rUx?yzJ$R3~f2fq`& zHZr$;I{L1>_`iB|o5+}g_rs&dN1hFSGx9yct0Hrywqny7sdHZs>&!7*vOk{2IJ<$~+2fzIvoTUp4X$THTG|`L7puZ2J<2Tw=%0**fX};&8?L>eg3x)^lfX zoxL;n&3OO5{LPbhM{ke3pL%8Vq6p8YML0h$vL?sI~8Dm*9I!@oylp16K=wdl&xWut7B9XLBWBYJQ2o;|%Q|NDu4 zVXxyYk>5X@61_NjPV~&^>Cw|7&j9*_Z+e~>Jt^W^Q;i;%zlG*I2hXis*R7}RoxCLS zEb)rSzKXT=`y+kSJZ8_u+9ccj2Rwi1&%Oy|^VWCl{zlO)Bes8+=qDokHV=rb2Ok)D zo_=6M|X>6&7{vzWDYbdy?0sBKhmH*NF7tn?<*d*t@+qb^5W${CD5TceIa))SY}Q&-Q;c zvZnXE^xKg>;CBOm8NDa+8>fGXJ{)~A@^{C+9v!-M=+>npdwSk4-#)r)Wc`HweWUwD z?3}&-Or&kh?Y|JQbz$0SZ2w_f58G)&?P&d_FB~69=Utk(@*C+l`j9e5`j>EJTE{8R z-j8pIo)kSf`nAZ~?y-^QZ?fjL-c|?V_uk=`B6YD2=a=6DBlqS$J;P5u>>(c&dG~kQ zi0xs5h5JyRxltR{-M8kk8e-l3z7YL?#TH$kv?ZHQ6BoV z{`;qq`S|2WA5x}gXyb@}WL(jQ%sJS2ZgY?Bf7)r-Yb*C`9bg>0!=7%pb-S%wM8-OO z%lOAGE*9lym-(voQ#!jo*DET{l#8_In=i$`jBhl*b}q1vgUkJWSsbo=mn9v*Zq1|_2$SPkad>6 z^o7VAVjMCaT`sz6j?OA}W5kCpP!Je>l?zgr#isUhQPkzFsW3Rq%_`Zm1&Yt<( z+V@hCeNb(~o{f9|9hon_7->K2uT{d%iCq6mWPTy(^atw(&+W!h=i9KCvhBIpO2oC+4KRyjQ^$Pr?>=hqfmBwB|Yc1BXZK zz4Whn;zR`@9cHv67%aZ zk@sh0TySoVp<^TA`jkFS{NlMTy}8N$k@cuPG5x{Xi1fATZ~DlMBjNg_=WyxNM?S`X zd7JY_%2$sm&m1U?^zxCP`y&0+Js%leDbnwZfB4{yzwc<+y*{Gdv>~y3;`e)V-}z}{ zZSDDo4UoNok3`lk)^+Sd-(V}&Huf;}2^zn>1bs!Ek#ja?{mI{MKg^?tJ{N zONTjmo)pF=XDk$#*r>6Ron9kir^Z)fE<0f}V@uqz70*1z_oMg3&nAdHPB?oKmu=2m zF!{-w{Wv!dD39$JztzXS5KSM_e_S7_=d~jHdsmCN7R314qvk`oDQ&<_>+{_+T%^*kUXSHRw^KRm~>NBv~&EBXwvU2A_X=||(&zvQ9cjo30f);EFesNf6xBLjO|?I3Rk9hBk_gFL%zzvMjIH@rw?f#V>; z<(=~QmF>6eBlUMrb1zdj^|D7KANP-gx+!~@suy9&9%kI+&R9CO!4=MC#MK7w$r!Bu zY;BeHq`5EtS^v1_8N2aOK6{#RlKrv0e~#vP+;kA3BUD?2b)L+iQPz$v&+;tTEWKafzS(&iFLzTJ|sgtW%_y53RN}{>^L7 z)nc1OK)cKmFHt*m_;C%o9pj6u`K#1ntg7zZZ) z*x5Q>vHcl8*rRmAUtPwY`PFe9bKQgfHSM9lIh;G(D_1*Vg70Y9<3Adfb4@!LbI91F zEzLEfbPbia8#d>^QnjH>Nu`&*XNLC#%cHG`WzE?`V$t$PdwN#o5pD6 zhNHIGo$0^%FZR=B_|H1u+KTkY>5Jk{zmqpfJL%-=`dm{7by@os|7Mu`aKG+vcwjif zl*|dlzxG4yY5L^aF4KP6jhq{wW?bje^ck+Pe>7v6bS%R8%niaOU#{|ZpUig02zD}B zlrx$* zbIrMHlLvS5U&Ge)(##=T8I#}mr(feUZ1!`-8%-YExd-_vYx3PCzx%IvYuzUvcfb11 z{jB#l@y4C|*Jk_^&Yf!$uADj6c&lIBHQgG2!lyo)?&KqU{FC3D<1$R}pgEK!zOjZT zAK~K6^(j|e`Hnkftnnv|JLPbdJN4i?WW3AJKul3;H@7N6A zOfz*+pSApnH(~O2f9!YDp2v2_9R_p0wg>+RANg{HNyim7<*En2!?iiYmH&k8MA-Xh z>OSsfUhdVk$&241uQfmEHZ|?ZUA2}man`V@%Uqi_U(Yw~VeDothhM&vZoM}5_9aERxvv2;p84sU{Ke0B`&N+9#`<*(BJMrZ={3q{mC(h(2-q_UIKAUAu`f;V3 zHXV1(i(eiNe#h#UW^8iz>No9l`oY-vxKqx!!e@TupZl2f)0bSEG-KP7=bTG3VXJ@g zm^|m&nogX}w5}`D!ClWMZ0dx|v)t&U*v55&2k6-z#giV|^{|O&=(ofteSDMwoo}XLzlyh$Gw830o z>#*iI@mB8BW^+v*{A>6cwx*qUlXhG-xsL13C!PAN^^^D1aSfk%Tyds8+{ueO=MyHb zV?E~|ZN{InC;pT-d93L+>)_g&-^5+royu(dvzD=z!$0*|ldNImUs>&!ZsLtQaip6= zn7Xdl)_ldAbM8*Wy?@qgliwP5KmTSw+RVds{ctm$yo601ro3^dUUR;>b8o^n{gZBW zr|s6TNxO!Pf8r0vHGKT5JMq>!j^F*wvHB-$+{sUz^U|bQ-OV)Xwbei6jO*I!pSZ%t zzs8xkcR}->_-mQxH*ab8V>tCaSiPp))m`In`qgPO?s`7{ z&2$&^d@~>C7bK6(^wLh)>JGOFTg%uCoAcG3_`=4&x)XOZZ1eow(y#G0{bL`($Im^l zW9oD;ck-Ax&R73jKfmtOZ{n}@Jg-@HfX7v-^E`D@tutqb03+{t4N+s{Ao#@#Q@8m64J zU#!o(Q_&hmZPt)`@y+Wha>NJW*qbQ0Z zD{@DcWm#P<%d%9dQ4~chgb+eBP1BgLf7kvQ_o|)D%)T?^GSCYG4{ob!S z)2|N?#b4gK_07Mt|DnE^-Tvg(ty{l2eV_ zabR30{MZ6qjis>xadoDQwH*3FpU4EBUs_W!rTuKm$Iw?E%Y`+(U%;_G?IVG4>H8)k zW0%llg)s~0i8j@;sw^{Os$l3#m*WxbBayX>vM7npsMJw7oETOx5sI8c9a!UZQWix% z}s0*Sl}jv`e#W9zVaIi`+45mWLFPXBnAEY6N{As?v=7Y$A(3PPnq{XV6kh(kL{GG|5Wo zjIYQp?TI66h#HA08wqSYHXr@!&ZDuKG_h?bbzP^*&aduHoO0P$$c>sV)tHB$KhnF+ zYSm*uEE1iaOePkl6P@+&-Vk4}*Q+)X4kk*vUbjg|Vwn-c8pnCR&Qx|RpmMcdtx9Qk zS85&HSwtpW!!&l|X_Ns6mP;{-b; zxNMp_kf#%!v=G?j+Gr?6TMGxu7G9B*RI$d3c0vfiD_@#UjSRqbL$vW&i5f6-9O@#k zhE1JeT;?{|0U;S|NM;KY&M6yuO0YVaC{YauC&Qs33R+ZG1n?Q)HNfX^Fo-Qo1-Go} zVMx{KRE;3=1744+67WUt$b#ZxlEFDB0)=I@1R`O8B!)K=I8OkJOi9!bwQ!zWU;h0k z55u1RWtDvAAMZ#t>{8!_qr0CD{R%Q*MU>(0z(o0ay{Qa_;cd^yt6pcE)%!LzzPzVx z-f!MlGGm0kPq56z@2@v2`-{)yYIA*!1%b4&@2g{_{QYLL3HBdpQMTG3UaukC8}EqS z`^~0zSkXrTsU6-~Zq|Kxc#p{eUK>JCB|h>bF<5O@>qguid8FBNj$pN`JaUDOrJP# zFfMx}>-n-TW9?wz(i|);$%?`t!k%mt%dV^K!+niF!WE|E)ma$$GH(@-bZx|qv@j{U z+*JIgD`JlwCInWefw zv5_xNW$>ne$hOy>lLq)FK?ON$#! z{Ti~guhqRrVg?D@0h=Z#b)$U0=bU&T(qm z1DoJFQ902`F|NC=oN>dcTLZRj-0=bHH+|dXX`sS^C%`62R);bx0Xl>I%Pnrmcr|Q& z(**3{)XFKZq{&R;CD^_!#ZZ()PH|J5Z}*TLax?*8*L-%!+Buj7z-3PIsv1sXRX8F~ zk8c4GVlpEEQE*jy?1;Ca3fFm>dMYqZM%kpOBCw5!WEJdUNGSnw15BuR6T!})nr`ue zWM`C3@-hUx33$54NSQKP3TW7Fho3?%f(K=EeLOemQFbKAIpdYBbH#RG~ zIoJ^3Yocsp$|hMEkAL~McjN{>hq?_O{nNiZj+U@FeXi`>+0~)6EaBiW2m7)YL1Oei z&+vxlhUFSDa`}E$_=CHH;`f{DrNby8azkQs_VRkYAuu2Ho9ou#ygmJ)2 zNV`N*$ht|9d@zA^ma9x=Ge(vT3aM&%85gaYOpTd)bxQD{nbO_bV< z`z-X8p+sQ5Pvwb*LfmG$5<(IZcf2nFd-QD}>nIL_B-B(|e7c0)XT!4V;Jlc5l>~vo zsR^x0xi%KO5Z8?dj;_X`GMG}DZZktRLlh*$RqUdJ%47^ib`I%C3?-mPHPB@Xs!-je z;#dk25L>=#k`}1IWH^r|ROu$6YvL*m=f>4|Tc{mwlT4FI%Gp8P;8wlPbjApt`Xud%Gml33E8JR{{ z5ZGDe;Pc%>#>i^qpbGw4EZo1nD|+>MnfU>n)>NN7`25fX&REq^fZIf4Cx;`qqP)<^ z4<2v@?D8@X_#vacx9kFOG=$BgD#IV_j)Eo7NtN0xBRI{f#=wFO&#Dngv$pRNWqc?m9TdpEkoFH` z0#Pk!E)L39+k=293ybIU2=oJNB9cZ!EvIbKrQH4ip3-#{j!l7+QA_!urc7nTgw$|g z;6+9{rI4m2@?a>(^c0cQ2dXkiSKu^nB83yI7}Nt4Yfl)CO_~6((eiMt#t>NHEmy&A z=Rgm2sBq#IPPbebP3>|^K8ZYSqVayR~$@oNQvAB zkb!H;Cb=h0L81Zu04y{?{e;vaMP@wsyH6fPH{wM6^pm@Cb0bcMcRn5XH7zYz9_}0( z0ZoU}U>V+WeX?pb##>)EvHHb*>-zoXx{z5j1V<_hDHR*W{d;N+;v^Mh_)I;hvRVc6 zYj5w79%bvb&ztRalQ@GNrGLNPbTd}+{eV<9@2xiL&fmXJ^KVmWpnzj9a3u+?p}JN4 z&d9?p;DuSY%0g%ISf{Di2OMJuAWkA#FV@Qz%ex02q#5L?f^gtRfu;aY_RDngkc-NG zRauhPRZ%cwr%nrW(zsJ*hT^IVwi={}l>LEE>mO(kD?)yRUBxP?I58hT2Ep3*xgq;C zLB1!8vvR9J*pY^kvde%ZfLtPn8EO^%V3Ddg$PYz~ ztC~$FCKV^dR3R~N=t)zBP@W;Cr1}9AbflS-G>9`DsRZ(?0@8>;frNpndt2dZe-J0c z2DMVepnP~er8!0{Q2}v6s>sko;E*(sCIZ|8sqEEeAi#ncSw^rGCl>QToVXxP@)-FR zbMM~%7??J5T?~hXNoKIztRVENQ(NqC4EH9$w#LH;OhzjQ9EuSmCsd`xMItjo0F}I2 zE{VnrdC)_vewhoqdnzy*h?9Vyuo@JGJW0z~2Cm34z3PCH0l86u%Y=A?$+Bn?jqYlhG1%<)eCB5q8l?&G>K<7{VgE%CAkcX_}Up3KWzJP?N`PFNEJ3BBi=>{Rk0d&-Y^xY~o5f$I&38Q@MTPGX&d z5_5CaiB*PC5zQ0=FC_EdoxXYZLz=#Mi=O@Ww?`MRU%!3#_TAOdZ@+mmfA_n0@7}&m zUi{`aPv>uc_wMZv>D9^8Z@)Wv{qA*|{_ytVxhx+oUcdg~?VGphiNZ_ADZt;nc{5jk zD;-_D1v^cyPBd9PNppyJon6_=cg7jDvh0Vs@#I_Mf?n52c4a;JRzIV+dz>V5^XXIT zA_F-K7tOQh-#>RQ)09BFoIRDFo#Kqzc>Y3BEd*cUkmTy>{H3nj3xcn%t}vb-Y5Flr z5)7Y1a{fY9UtZ7vjAKWCYPj&3;N&X4a82Fxu3kg*6^>o=x#e9#475wfcxrmdYcP{! zas2$5?O(y`U&Rn(y|BEPnperyx&7kk6}q~j-zi)!csZVs?I&!qRcP zIC*(w`!O})*Rzl8(*-zaJD-`R11nHpe12?N&U}lD;tTKCIzGLi^U%=A%a=1hx*0_N z@sZ^&Zd{jh$F`l|5=NI%6#B319PIlECdVMW$@~y?V_!Dd5PTF?1U}| z$S6YItJz5qQTy`pa_+*&rxvs*I60oV^UHWUSe%{A91qcXXrX`NoSZE#FD@=%COkiJ zZhREF@SImC=kRQ37vbDga1kYFmXP)QJ!<)E^#kqIt`Dhyk z{^0EN^bDLgSmd91XRs>8LcrXI$Y22`%s}MXkC7jj4ZuaQ+oznJqpc19pmSJ=KILX& z?)zuwbMP(}2*GdQ`!HO5XfQnU!Fw}A^Yf41o9``Q7(mnw{KorJD1gs{?eGR1oSz4< z@&~{lJqQ5cy?HJLFVLK#wt8cN z_R)evrP &soundPath) this->_soundList[static_cast(i)] = RAY::Audio::Sound(soundPath.at(static_cast(i))); } } + /*for (int i = 0; i < DEATH + 1; i++) { + std::cout << i << this->_isLoad.at(static_cast(i)) << soundPath.at(static_cast(i)) << std::endl; + }*/ } SoundComponent::SoundComponent(WAL::Entity &entity) @@ -35,6 +38,7 @@ std::map &soundPath) void SoundComponent::loadSound(void) { + std::cout << this->_soundIndex << std::endl; if (!this->_isLoad.at(this->_soundIndex)) return; if (!this->_soundList[this->_soundIndex].isPlaying()) { diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 3670a151..7030294f 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -66,11 +66,11 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); - std::map musicPath= { + std::map soundPath= { {SoundComponent::IDLE, ""}, {SoundComponent::JUMP, ""}, {SoundComponent::BOMB, ""}, - {SoundComponent::MOVE, "assets/sounds/new_death.ogg"}, + {SoundComponent::MOVE, "assets/sounds/weird.wav"}, {SoundComponent::HURT, ""}, {SoundComponent::THROW, ""}, {SoundComponent::DEATH, ""} @@ -83,7 +83,7 @@ namespace BBM .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 1) .addComponent(2) .addComponent() - .addComponent(musicPath); + .addComponent(soundPath); scene->addEntity("cube") .addComponent(-5, 0, -5) .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) From 9218ebe4dcfe629bee7de8488780b40966d44a14 Mon Sep 17 00:00:00 2001 From: "arthur.jamet" Date: Mon, 7 Jun 2021 12:37:30 +0200 Subject: [PATCH 06/40] when window context is loaded, audio device is initialized --- lib/Ray/sources/Window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Ray/sources/Window.cpp b/lib/Ray/sources/Window.cpp index 2cef08f1..946c3353 100644 --- a/lib/Ray/sources/Window.cpp +++ b/lib/Ray/sources/Window.cpp @@ -40,6 +40,7 @@ RAY::Window::Window(int width, int height, std::string title, unsigned flags, bo { if (openNow) this->open(); + InitAudioDevice(); } bool RAY::Window::open(void) @@ -60,6 +61,7 @@ bool RAY::Window::shouldClose(void) const void RAY::Window::close(void) { CloseWindow(); + CloseAudioDevice(); } bool RAY::Window::isFocused(void) const From 7d7ede07e9a3a3145302ab568eda63beabae94cc Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 15:31:57 +0200 Subject: [PATCH 07/40] Sound for jump + fix sound component function name --- assets/sounds/jump.wav | Bin 0 -> 88244 bytes sources/Component/Sound/SoundComponent.cpp | 24 ++++++++---------- sources/Component/Sound/SoundComponent.hpp | 12 ++++++--- sources/Runner/Runner.cpp | 10 +++++--- .../System/Sound/PlayerSoundManagerSystem.cpp | 19 ++++++++++---- .../System/Sound/PlayerSoundManagerSystem.hpp | 2 +- 6 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 assets/sounds/jump.wav diff --git a/assets/sounds/jump.wav b/assets/sounds/jump.wav new file mode 100644 index 0000000000000000000000000000000000000000..642ae89a6905e90666bc81efe08127fe70df779e GIT binary patch literal 88244 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 +#include #include "SoundComponent.hpp" namespace BBM @@ -10,18 +11,18 @@ namespace BBM SoundComponent::SoundComponent(WAL::Entity &entity, \ std::map &soundPath) : WAL::Component(entity), - _soundIndex(IDLE) + _soundIndex(IDLE), + _soundPath(soundPath) { - for (int i = 0; i < DEATH + 1; i++) { + for (int i = 0; i <= DEATH; i++) + this->_isLoad[static_cast(i)] = false; + /*for (int i = 0; i <= DEATH; i++) { if (soundPath.at(static_cast(i)).empty()) { this->_isLoad[static_cast(i)] = false; } else { this->_isLoad[static_cast(i)] = true; this->_soundList[static_cast(i)] = RAY::Audio::Sound(soundPath.at(static_cast(i))); } - } - /*for (int i = 0; i < DEATH + 1; i++) { - std::cout << i << this->_isLoad.at(static_cast(i)) << soundPath.at(static_cast(i)) << std::endl; }*/ } @@ -36,22 +37,19 @@ std::map &soundPath) return new SoundComponent(entity); } - void SoundComponent::loadSound(void) + void SoundComponent::playSound(void) { - std::cout << this->_soundIndex << std::endl; if (!this->_isLoad.at(this->_soundIndex)) - return; - if (!this->_soundList[this->_soundIndex].isPlaying()) { - std::cout << this->_soundIndex << std::endl; + this->_soundList[this->_soundIndex] = RAY::Audio::Sound(this->_soundPath.at(this->_soundIndex)); + if (!this->_soundList[this->_soundIndex].isPlaying()) this->_soundList[this->_soundIndex].play(); - } } - void SoundComponent::unloadSound(void) + void SoundComponent::stopSound(void) { if (!this->_isLoad.at(this->_soundIndex)) return; - if (!this->_soundList[this->_soundIndex].isPlaying()) + if (this->_soundList[this->_soundIndex].isPlaying()) this->_soundList[this->_soundIndex].stop(); } diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index 1feaa261..df2d3925 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -30,10 +30,10 @@ namespace BBM soundIndex getIndex(); //! @brief load Sound - void loadSound(); + void playSound(); //! @brief unload Sound - void unloadSound(); + void stopSound(); //! @brief put Sound on hold void pauseSound(); @@ -47,11 +47,10 @@ namespace BBM //! @brief is Sound playing bool isPlaying(void); - //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new SoundComponent at a certain Sound - SoundComponent(WAL::Entity &entity, std::map &SoundPath); + SoundComponent(WAL::Entity &entity, std::map &); //! @brief A Sound component is copy constructable SoundComponent(const SoundComponent &) = default; //! @brief A default destructor @@ -63,8 +62,13 @@ namespace BBM std::map _soundList; std::map _isLoad; + + std::map _soundPath; + //! SoundIndex soundIndex _soundIndex; + + //! @brief Create a new SoundComponent linked to a specific entity explicit SoundComponent(WAL::Entity &entity); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 7030294f..d556b3b7 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -31,6 +31,7 @@ #include "Map/Map.hpp" #include "Component/Music/MusicComponent.hpp" #include "Component/Sound/SoundComponent.hpp" +#include "System/Sound/PlayerSoundManagerSystem.hpp" namespace RAY2D = RAY::Drawables::Drawables2D; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -53,12 +54,13 @@ namespace BBM .addSystem() .addSystem() .addSystem(wal) - .addSystem(); + .addSystem() + .addSystem(); } void enableRaylib(WAL::Wal &wal) { - RAY::TraceLog::setLevel(LOG_WARNING); + //RAY::TraceLog::setLevel(LOG_WARNING); RAY::Window &window = RAY::Window::getInstance(600, 400, "Bomberman", FLAG_WINDOW_RESIZABLE); wal.addSystem(wal, window); } @@ -70,7 +72,7 @@ namespace BBM {SoundComponent::IDLE, ""}, {SoundComponent::JUMP, ""}, {SoundComponent::BOMB, ""}, - {SoundComponent::MOVE, "assets/sounds/weird.wav"}, + {SoundComponent::MOVE, "assets/sounds/jump.wav"}, {SoundComponent::HURT, ""}, {SoundComponent::THROW, ""}, {SoundComponent::DEATH, ""} @@ -79,10 +81,12 @@ namespace BBM .addComponent() .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) .addComponent() + .addComponent(1) .addComponent() .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 1) .addComponent(2) .addComponent() + //.addComponent("assets/musics/music_win.ogg"); .addComponent(soundPath); scene->addEntity("cube") .addComponent(-5, 0, -5) diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp index 512a5603..187f55e3 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.cpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -6,6 +6,14 @@ namespace BBM { + + SoundManagerSystem::SoundManagerSystem() + : WAL::System({ + typeid(SoundComponent), + typeid(HealthComponent) + }) + {} + void SoundManagerSystem::onFixedUpdate(WAL::Entity &entity) { if (!entity.hasComponent()) @@ -15,12 +23,13 @@ namespace BBM { auto &health = entity.getComponent(); sound.setIndex(SoundComponent::BOMB); - controllable.bomb ? sound.loadSound() : sound.unloadSound(); + if (controllable.bomb) + sound.playSound(); sound.setIndex(SoundComponent::JUMP); - controllable.jump ? sound.loadSound() : sound.unloadSound(); + if (controllable.jump) + sound.playSound(); sound.setIndex(SoundComponent::MOVE); - (controllable.move.x != 0 || controllable.move.y != 0) ? sound.loadSound() : sound.unloadSound(); - sound.setIndex(SoundComponent::DEATH); - health.getHealthPoint() == 0 ? sound.loadSound() : sound.unloadSound(); + if (controllable.move.x != 0 || controllable.move.y != 0) + sound.playSound(); } } \ No newline at end of file diff --git a/sources/System/Sound/PlayerSoundManagerSystem.hpp b/sources/System/Sound/PlayerSoundManagerSystem.hpp index aff694c2..38cd4bfa 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.hpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.hpp @@ -20,7 +20,7 @@ namespace BBM void onFixedUpdate(WAL::Entity &entity) override; //! @brief ctor - SoundManagerSystem(WAL::Wal &wal, RAY::Window &window); + SoundManagerSystem(); //! @brief Default copy ctor SoundManagerSystem(const SoundManagerSystem &) = default; //! @brief Default dtor From 0458bde5ae6541d1706a967bf3a03225a7f8e083 Mon Sep 17 00:00:00 2001 From: Askou Date: Mon, 7 Jun 2021 15:39:57 +0200 Subject: [PATCH 08/40] add unique_ptr for sound --- sources/Component/Sound/SoundComponent.cpp | 26 ++++++++++------------ sources/Component/Sound/SoundComponent.hpp | 2 +- sources/Runner/Runner.cpp | 2 +- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index 176230f8..d4ab53b1 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -14,16 +14,14 @@ std::map &soundPath) _soundIndex(IDLE), _soundPath(soundPath) { - for (int i = 0; i <= DEATH; i++) - this->_isLoad[static_cast(i)] = false; - /*for (int i = 0; i <= DEATH; i++) { + for (int i = 0; i <= DEATH; i++) { if (soundPath.at(static_cast(i)).empty()) { this->_isLoad[static_cast(i)] = false; } else { this->_isLoad[static_cast(i)] = true; - this->_soundList[static_cast(i)] = RAY::Audio::Sound(soundPath.at(static_cast(i))); + this->_soundList[static_cast(i)] = std::unique_ptr(new RAY::Audio::Sound(soundPath.at(static_cast(i)))); } - }*/ + } } SoundComponent::SoundComponent(WAL::Entity &entity) @@ -40,24 +38,24 @@ std::map &soundPath) void SoundComponent::playSound(void) { if (!this->_isLoad.at(this->_soundIndex)) - this->_soundList[this->_soundIndex] = RAY::Audio::Sound(this->_soundPath.at(this->_soundIndex)); - if (!this->_soundList[this->_soundIndex].isPlaying()) - this->_soundList[this->_soundIndex].play(); + return; + if (!this->_soundList[this->_soundIndex].get()->isPlaying()) + this->_soundList[this->_soundIndex].get()->play(); } void SoundComponent::stopSound(void) { if (!this->_isLoad.at(this->_soundIndex)) return; - if (this->_soundList[this->_soundIndex].isPlaying()) - this->_soundList[this->_soundIndex].stop(); + if (this->_soundList[this->_soundIndex].get()->isPlaying()) + this->_soundList[this->_soundIndex].get()->stop(); } void SoundComponent::pauseSound(void) { if (!this->_isLoad.at(this->_soundIndex)) return; - this->_soundList[this->_soundIndex].pause(); + this->_soundList[this->_soundIndex].get()->pause(); } void SoundComponent::setVolume(float &volume) @@ -65,21 +63,21 @@ std::map &soundPath) if (!this->_isLoad.at(this->_soundIndex)) return; if (volume >= 0) - this->_soundList[this->_soundIndex].setVolume(volume); + this->_soundList[this->_soundIndex].get()->setVolume(volume); } void SoundComponent::setPitch(float &pitch) { if (!this->_isLoad.at(this->_soundIndex)) return; - this->_soundList[this->_soundIndex].setPitch(pitch); + this->_soundList[this->_soundIndex].get()->setPitch(pitch); } bool SoundComponent::isPlaying(void) { if (!this->_isLoad.at(this->_soundIndex)) return (false); - return (this->_soundList[this->_soundIndex].isPlaying()); + return (this->_soundList[this->_soundIndex].get()->isPlaying()); } void SoundComponent::setIndex(soundIndex index) diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index df2d3925..e4b7ed5e 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -59,7 +59,7 @@ namespace BBM SoundComponent &operator=(const SoundComponent &) = delete; private: //! @brief Sound of this entity - std::map _soundList; + std::map> _soundList; std::map _isLoad; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index d556b3b7..d4f9ccbd 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -70,7 +70,7 @@ namespace BBM auto scene = std::make_shared(); std::map soundPath= { {SoundComponent::IDLE, ""}, - {SoundComponent::JUMP, ""}, + {SoundComponent::JUMP, "assets/sounds/death.ogg"}, {SoundComponent::BOMB, ""}, {SoundComponent::MOVE, "assets/sounds/jump.wav"}, {SoundComponent::HURT, ""}, From b7d43fef6aff270c2169c03fed15024f7bafc156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Mon, 7 Jun 2021 18:01:19 +0200 Subject: [PATCH 09/40] starting to look into collisions --- CMakeLists.txt | 18 +++++++++--------- sources/Map/Map.cpp | 2 ++ sources/Runner/Runner.cpp | 14 +++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 966a6d01..8a830ed8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,15 +79,15 @@ target_link_libraries(bomberman PUBLIC wal ray) add_executable(unit_tests EXCLUDE_FROM_ALL - ${SOURCES} - tests/EntityTests.cpp - tests/MainTest.cpp - tests/EngineTests.cpp - tests/CallbackTest.cpp - tests/MoveTests.cpp - tests/ViewTest.cpp - tests/CollisionTest.cpp -) + ${SOURCES} + tests/EntityTests.cpp + tests/MainTest.cpp + tests/EngineTests.cpp + tests/CallbackTest.cpp + tests/MoveTests.cpp + tests/ViewTest.cpp + tests/CollisionTest.cpp + ) target_include_directories(unit_tests PUBLIC sources) target_link_libraries(unit_tests PUBLIC wal ray) diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index c4709164..618725b6 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -16,6 +16,8 @@ namespace BBM auto *mov = entity.tryGetComponent(); if (!mov) return; + mov->_velocity = BBM::Vector3f (); + return; auto &pos = entity.getComponent(); const auto &wallPos = wall.getComponent(); auto diff = pos.position + mov->getVelocity() - wallPos.position; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 011ffee3..1be23954 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -72,14 +72,14 @@ namespace BBM scene->addEntity("camera") .addComponent(8, 20, 7) .addComponent(Vector3f(8, 0, 8)); -// scene->addEntity("cube") -// .addComponent(5, 0, 5) -// .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) -// .addComponent() -// .addComponent() -// .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); + scene->addEntity("cube") + .addComponent(5, 0, 5) + .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent() + .addComponent() + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); std::srand(std::time(nullptr)); - MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); + //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; } From 8203532d52395fa41455d95ae01a650798e2d6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Mon, 7 Jun 2021 22:06:17 +0200 Subject: [PATCH 10/40] code style fix --- .../Collision/CollisionComponent.cpp | 45 +++++++++----- .../Collision/CollisionComponent.hpp | 60 ++++++++++--------- tests/CollisionTest.cpp | 8 +-- 3 files changed, 68 insertions(+), 45 deletions(-) diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index df727b2d..35da6cb8 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -4,31 +4,48 @@ #include "Component/Collision/CollisionComponent.hpp" - -namespace BBM +namespace BBM { CollisionComponent::CollisionComponent(WAL::Entity &entity) - : WAL::Component(entity) - { } + : WAL::Component(entity) + {} WAL::Component *CollisionComponent::clone(WAL::Entity &entity) const { return new CollisionComponent(entity); } - CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, Vector3f bound) - : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound(bound) - { } + CollisionComponent::CollisionComponent(WAL::Entity &entity, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, + Vector3f bound) + : WAL::Component(entity), + onCollide(onCollide), + onCollided(onCollided), + bound(bound) + {} - CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, float boundSize) - : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound({boundSize, boundSize, boundSize}) - { } + CollisionComponent::CollisionComponent(WAL::Entity &entity, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, + float boundSize) + : WAL::Component(entity), + onCollide(onCollide), + onCollided(onCollided), + bound({boundSize, boundSize, boundSize}) + {} CollisionComponent::CollisionComponent(WAL::Entity &entity, Vector3f bound) - : WAL::Component(entity), onCollide(), onCollided(), bound(bound) - { } + : WAL::Component(entity), + onCollide(), + onCollided(), + bound(bound) + {} CollisionComponent::CollisionComponent(WAL::Entity &entity, float boundSize) - : WAL::Component(entity), onCollide(), onCollided(), bound({boundSize, boundSize, boundSize}) - { } + : WAL::Component(entity), + onCollide(), + onCollided(), + bound({boundSize, boundSize, boundSize}) + {} } \ No newline at end of file diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 5bfe7e16..0e4caf62 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -9,43 +9,49 @@ #include "Component/Component.hpp" #include "Entity/Entity.hpp" -namespace BBM +namespace BBM { class CollisionComponent : public WAL::Component { - private: - public: - //! @brief onCollide functions to be called - WAL::Callback onCollide; - //! @brief onCollided functions to be called - WAL::Callback onCollided; - //! @brief Bound size on all axis - Vector3f bound; - //! @inherit - WAL::Component *clone(WAL::Entity &entity) const override; + public: + //! @brief onCollide functions to be called + WAL::Callback onCollide; + //! @brief onCollided functions to be called + WAL::Callback onCollided; + //! @brief Bound size on all axis + Vector3f bound; - //! @brief A component can't be instantiated, it should be derived. - explicit CollisionComponent(WAL::Entity &entity); + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; - //! @brief Constructor with a WAL::Callback - CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided,Vector3f bound); + //! @brief A component can't be instantiated, it should be derived. + explicit CollisionComponent(WAL::Entity &entity); - //! @brief Constructor with a WAL::Callback, same boundSize for all axis - CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, float boundSize = 0); + //! @brief Constructor with a WAL::Callback + CollisionComponent(WAL::Entity &entity, + const WAL::Callback& onCollide, + const WAL::Callback& onCollided, + Vector3f bound); - //! @brief Constructor of collider with no callback - CollisionComponent(WAL::Entity &entity, Vector3f bound); + //! @brief Constructor with a WAL::Callback, same boundSize for all axis + CollisionComponent(WAL::Entity &entity, + const WAL::Callback& onCollide, + const WAL::Callback& onCollided, + float boundSize = 0); - //! @brief Constructor no callback, same boundSize for all axis - CollisionComponent(WAL::Entity &entity, float boundSize); + //! @brief Constructor of collider with no callback + CollisionComponent(WAL::Entity &entity, Vector3f bound); - //! @brief Default copy constructor - CollisionComponent(const CollisionComponent &) = default; + //! @brief Constructor no callback, same boundSize for all axis + CollisionComponent(WAL::Entity &entity, float boundSize); - //! @brief default destructor - ~CollisionComponent() override = default; + //! @brief Default copy constructor + CollisionComponent(const CollisionComponent &) = default; - //! @brief A component can't be assigned - CollisionComponent &operator=(const CollisionComponent &) = delete; + //! @brief default destructor + ~CollisionComponent() override = default; + + //! @brief A component can't be assigned + CollisionComponent &operator=(const CollisionComponent &) = delete; }; } \ No newline at end of file diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp index 394b1ccc..8392aa85 100644 --- a/tests/CollisionTest.cpp +++ b/tests/CollisionTest.cpp @@ -26,10 +26,10 @@ TEST_CASE("Collision test", "[Component][System]") .addComponent() .addComponent([](Entity &actual, const Entity &) { try { - auto &pos = actual.getComponent(); - pos.position.x = 1; - pos.position.y = 1; - pos.position.z = 1; + auto &pos = actual.getComponent(); + pos.position.x = 1; + pos.position.y = 1; + pos.position.z = 1; } catch (std::exception &e) {}; }, [](Entity &, const Entity &){}, 5.0); Entity &entity = wal.scene->getEntities().front(); From 65af11f3f9833cf67638641cd8bfae1ad7c35c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Mon, 7 Jun 2021 23:37:51 +0200 Subject: [PATCH 11/40] collisions are working ok with user defined offsets --- lib/Ray/sources/Camera/Camera3D.cpp | 1 + .../Collision/CollisionComponent.cpp | 18 +++++++---- .../Collision/CollisionComponent.hpp | 16 ++++++---- sources/Map/Map.cpp | 7 +++- sources/Runner/Runner.cpp | 12 +++---- sources/System/Collision/CollisionSystem.cpp | 30 ++++++++++++----- sources/System/Renderer/RenderSystem.cpp | 32 ++++++++++++++++--- 7 files changed, 85 insertions(+), 31 deletions(-) diff --git a/lib/Ray/sources/Camera/Camera3D.cpp b/lib/Ray/sources/Camera/Camera3D.cpp index aa2b2a9b..0c4b3d13 100644 --- a/lib/Ray/sources/Camera/Camera3D.cpp +++ b/lib/Ray/sources/Camera/Camera3D.cpp @@ -10,6 +10,7 @@ RAY::Camera::Camera3D::Camera3D(const RAY::Vector3 &position, const RAY::Vector3 &target, const RAY::Vector3 &up, float fovy, Projection projection): _camera({position, target, up, fovy, projection}) { + SetCameraMode(_camera, CAMERA_FREE); } void RAY::Camera::Camera3D::setPosition(const Vector3 &Position) diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index 35da6cb8..8f7db0d7 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -18,34 +18,40 @@ namespace BBM CollisionComponent::CollisionComponent(WAL::Entity &entity, const WAL::Callback &onCollide, const WAL::Callback &onCollided, + Vector3f positionOffset, Vector3f bound) : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), - bound(bound) + bound(bound), + positionOffset(positionOffset) {} CollisionComponent::CollisionComponent(WAL::Entity &entity, const WAL::Callback &onCollide, const WAL::Callback &onCollided, + float positionOffset, float boundSize) : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), - bound({boundSize, boundSize, boundSize}) + bound({boundSize, boundSize, boundSize}), + positionOffset({positionOffset, positionOffset, positionOffset}) {} - CollisionComponent::CollisionComponent(WAL::Entity &entity, Vector3f bound) + CollisionComponent::CollisionComponent(WAL::Entity &entity, Vector3f positionOffset, Vector3f bound) : WAL::Component(entity), onCollide(), onCollided(), - bound(bound) + bound(bound), + positionOffset(positionOffset) {} - CollisionComponent::CollisionComponent(WAL::Entity &entity, float boundSize) + CollisionComponent::CollisionComponent(WAL::Entity &entity, float positionOffset, float boundSize) : WAL::Component(entity), onCollide(), onCollided(), - bound({boundSize, boundSize, boundSize}) + bound({boundSize, boundSize, boundSize}), + positionOffset({positionOffset, positionOffset, positionOffset}) {} } \ No newline at end of file diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 0e4caf62..933d2c31 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -20,6 +20,8 @@ namespace BBM WAL::Callback onCollided; //! @brief Bound size on all axis Vector3f bound; + //! @brief Offset from the position component + Vector3f positionOffset; //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; @@ -29,21 +31,23 @@ namespace BBM //! @brief Constructor with a WAL::Callback CollisionComponent(WAL::Entity &entity, - const WAL::Callback& onCollide, - const WAL::Callback& onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, + Vector3f positionOffset, Vector3f bound); //! @brief Constructor with a WAL::Callback, same boundSize for all axis CollisionComponent(WAL::Entity &entity, - const WAL::Callback& onCollide, - const WAL::Callback& onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, + float positionOffset, float boundSize = 0); //! @brief Constructor of collider with no callback - CollisionComponent(WAL::Entity &entity, Vector3f bound); + CollisionComponent(WAL::Entity &entity, Vector3f positionOffset, Vector3f bound); //! @brief Constructor no callback, same boundSize for all axis - CollisionComponent(WAL::Entity &entity, float boundSize); + CollisionComponent(WAL::Entity &entity, float positionOffset, float boundSize); //! @brief Default copy constructor CollisionComponent(const CollisionComponent &) = default; diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 618725b6..e688fa77 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -14,9 +14,14 @@ namespace BBM void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall) { auto *mov = entity.tryGetComponent(); + auto posspec = entity.getComponent(); + auto posspecwall = wall.getComponent(); + if (!mov) return; - mov->_velocity = BBM::Vector3f (); + + std::cout << "collided coords " << posspec.position << " cube " << posspecwall.position << std::endl; + //mov->_velocity = BBM::Vector3f (); return; auto &pos = entity.getComponent(); const auto &wallPos = wall.getComponent(); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 06201ebd..06ff3cb2 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -70,21 +70,21 @@ namespace BBM .addComponent() .addComponent() .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) - .addComponent(1) + .addComponent(0, 1) .addComponent() .addComponent(1, [](WAL::Entity &entity) { auto &animation = entity.getComponent(); animation.setAnimIndex(5); }); scene->addEntity("camera") - .addComponent(8, 20, 7) - .addComponent(Vector3f(8, 0, 8)); + .addComponent(10, 20, 10) + .addComponent(Vector3f(2, 0, 2)); scene->addEntity("cube") - .addComponent(5, 0, 5) - .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent(0, 0, 0) + .addComponent(Vector3f(0, 0, 0), Vector3f(3, 3, 3), RED) .addComponent() .addComponent() - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); std::srand(std::time(nullptr)); //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index 6a3e36cd..50c5662a 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -26,19 +26,33 @@ namespace BBM void CollisionSystem::onFixedUpdate(WAL::ViewEntity &entity) { auto &posA = entity.get(); - auto &col = entity.get(); - Vector3f position = posA.position; + auto &colA = entity.get(); + Vector3f pointA = posA.position + colA.positionOffset; + if (auto *movable = entity->tryGetComponent()) - position += movable->getVelocity(); - Vector3f minA = Vector3f::min(position, position + col.bound); - Vector3f maxA = Vector3f::max(position, position + col.bound); + pointA += movable->getVelocity(); + + Vector3f minA = Vector3f::min(pointA, pointA + colA.bound); + Vector3f maxA = Vector3f::max(pointA, pointA + colA.bound); + for (auto &[other, posB, colB] : this->getView()) { if (other.getUid() == entity->getUid()) continue; - Vector3f minB = Vector3f::min(posB.position, posB.position + colB.bound); - Vector3f maxB = Vector3f::max(posB.position, posB.position + colB.bound); + + auto pointB = posB.position + colB.positionOffset; + + // TODO if B is also a movable we don't check with it's changing position + Vector3f minB = Vector3f::min(pointB, pointB + colB.bound); + Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); + if (collide(minA, maxA, minB, maxB)) { - col.onCollide(entity, other); + std::cout << "collided" << std::endl + << "minA " << minA << std::endl + << "maxA " << maxA << std::endl + << "minB " << minB << std::endl + << "maxB " << maxB << std::endl; + return; + colA.onCollide(entity, other); colB.onCollided(entity, other); } } diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index cdabb452..b6ef7891 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -10,13 +10,16 @@ #include "Component/Renderer/Drawable2DComponent.hpp" #include "Drawables/ADrawable3D.hpp" + +#include "Component/Collision/CollisionComponent.hpp" + namespace BBM { RenderSystem::RenderSystem(WAL::Wal &wal, RAY::Window &window, bool debugMode) : System(wal), - _window(window), - _camera(Vector3f(), Vector3f(), Vector3f(0, 1, 0), 50, CAMERA_PERSPECTIVE), - _debugMode(debugMode) + _window(window), + _camera(Vector3f(), Vector3f(), Vector3f(0, 1, 0), 50, CAMERA_PERSPECTIVE), + _debugMode(debugMode) { this->_window.setFPS(this->FPS); } @@ -29,6 +32,26 @@ namespace BBM this->_window.useCamera(this->_camera); for (auto &[_, pos, drawable] : this->_wal.scene->view()) { + if (_.getName() == "cube") { + auto col = _.getComponent(); + DrawCubeWires({pos.position.x, pos.position.y, pos.position.z}, + col.bound.x, + col.bound.y, + col.bound.z, + WHITE); + DrawPoint3D({pos.position.x, pos.position.y, pos.position.z}, BLUE); + DrawPoint3D({pos.position.x + col.bound.x, pos.position.y + col.bound.y, pos.position.z + col.bound.z}, BLUE); + } + if (_.getName() == "player") { + auto col = _.getComponent(); + DrawCubeWires({pos.position.x, pos.position.y, pos.position.z}, + col.bound.x, + col.bound.y, + col.bound.z, + WHITE); + DrawPoint3D({pos.position.x, pos.position.y, pos.position.z}, BLUE); + DrawPoint3D({pos.position.x + col.bound.x, pos.position.y + col.bound.y, pos.position.z + col.bound.z}, BLUE); + } drawable.drawable->setPosition(pos.position); drawable.drawable->drawOn(this->_window); } @@ -44,7 +67,8 @@ namespace BBM this->_window.endDrawing(); } - void RenderSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + void + RenderSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) { const auto &pos = entity.get(); const auto &cam = entity.get(); From 22606ecf68d343130699f47756c173769f33414e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 00:19:34 +0200 Subject: [PATCH 12/40] giving the collided Axis for context to callback on collisions --- .../Collision/CollisionComponent.cpp | 8 ++-- .../Collision/CollisionComponent.hpp | 19 +++++--- sources/Map/Map.cpp | 33 +++++++------- sources/Map/Map.hpp | 2 +- sources/Runner/Runner.cpp | 4 +- sources/System/Collision/CollisionSystem.cpp | 45 ++++++++++++++----- sources/System/Collision/CollisionSystem.hpp | 2 +- 7 files changed, 70 insertions(+), 43 deletions(-) diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index 8f7db0d7..678b0898 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -16,8 +16,8 @@ namespace BBM } CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound) : WAL::Component(entity), @@ -28,8 +28,8 @@ namespace BBM {} CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize) : WAL::Component(entity), diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 933d2c31..1be3590d 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -14,10 +14,17 @@ namespace BBM class CollisionComponent : public WAL::Component { public: + //! @brief Used to tell the collided axis + enum CollidedAxis { + X = 1, + Y = 2, + Z = 4 + }; + //! @brief onCollide functions to be called - WAL::Callback onCollide; + WAL::Callback onCollide; //! @brief onCollided functions to be called - WAL::Callback onCollided; + WAL::Callback onCollided; //! @brief Bound size on all axis Vector3f bound; //! @brief Offset from the position component @@ -31,15 +38,15 @@ namespace BBM //! @brief Constructor with a WAL::Callback CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound); //! @brief Constructor with a WAL::Callback, same boundSize for all axis CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize = 0); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index e688fa77..937343c8 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -3,7 +3,8 @@ // Edited by Benjamin Henry on 5/26/21. // -#include +#include "Component/Collision/CollisionComponent.hpp" +#include "System/Collision/CollisionSystem.hpp" #include "Map.hpp" #include @@ -11,7 +12,7 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { - void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall) + void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis) { auto *mov = entity.tryGetComponent(); auto posspec = entity.getComponent(); @@ -20,20 +21,16 @@ namespace BBM if (!mov) return; - std::cout << "collided coords " << posspec.position << " cube " << posspecwall.position << std::endl; - //mov->_velocity = BBM::Vector3f (); - return; auto &pos = entity.getComponent(); const auto &wallPos = wall.getComponent(); auto diff = pos.position + mov->getVelocity() - wallPos.position; -// mov->_velocity = Vector3f(); - if (diff.x <= 0 && mov->_velocity.x < 0) + //mov->_velocity = Vector3f(); + //return; + if (collidedAxis & CollisionComponent::CollidedAxis::X) mov->_velocity.x = 0; - if (diff.x >= 0 && mov->_velocity.x > 0) + if (collidedAxis & CollisionComponent::CollidedAxis::Y) mov->_velocity.x = 0; - if (diff.z <= 0 && mov->_velocity.z < 0) - mov->_velocity.z = 0; - if (diff.z >= 0 && mov->_velocity.z > 0) + if (collidedAxis & CollisionComponent::CollidedAxis::Z) mov->_velocity.z = 0; } @@ -60,7 +57,7 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); } } @@ -74,25 +71,25 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -142,7 +139,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent(1) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -175,7 +172,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); } diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index f6b082a8..f705eebf 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -156,7 +156,7 @@ namespace BBM static const std::string secondFloorHolePath; public: - static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall); + static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis); //! @param width Width of the map diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 06ff3cb2..af08e264 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -80,11 +80,11 @@ namespace BBM .addComponent(10, 20, 10) .addComponent(Vector3f(2, 0, 2)); scene->addEntity("cube") - .addComponent(0, 0, 0) + .addComponent(-5, 0, -5) .addComponent(Vector3f(0, 0, 0), Vector3f(3, 3, 3), RED) .addComponent() .addComponent() - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); std::srand(std::time(nullptr)); //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index 50c5662a..14b6c12a 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -14,7 +14,7 @@ namespace BBM : System(wal) { } - bool CollisionSystem::collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB) + bool CollisionSystem::boxesCollide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB) { bool overlapX = (minA.x <= maxB.x && maxA.x >= minB.x) || (minB.x <= maxA.x && maxB.x >= minA.x); bool overlapY = (minA.y <= maxB.y && maxA.y >= minB.y) || (minB.y <= maxA.y && maxB.y >= minA.y); @@ -28,32 +28,55 @@ namespace BBM auto &posA = entity.get(); auto &colA = entity.get(); Vector3f pointA = posA.position + colA.positionOffset; + Vector3f pointAx; + Vector3f pointAy; + Vector3f pointAz; - if (auto *movable = entity->tryGetComponent()) - pointA += movable->getVelocity(); + if (auto *movable = entity->tryGetComponent()) { + auto vel = movable->getVelocity(); + pointAx.x += vel.x; + pointAy.y += vel.y; + pointAz.z += vel.z; + } - Vector3f minA = Vector3f::min(pointA, pointA + colA.bound); - Vector3f maxA = Vector3f::max(pointA, pointA + colA.bound); + Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound); + Vector3f maxAx = Vector3f::max(pointAx, pointAx + colA.bound); + + Vector3f minAy = Vector3f::min(pointAy, pointAy + colA.bound); + Vector3f maxAy = Vector3f::max(pointAy, pointAy + colA.bound); + + Vector3f minAz = Vector3f::min(pointAz, pointAz + colA.bound); + Vector3f maxAz = Vector3f::max(pointAz, pointAz + colA.bound); for (auto &[other, posB, colB] : this->getView()) { if (other.getUid() == entity->getUid()) continue; auto pointB = posB.position + colB.positionOffset; + int collidedAxis = 0; // TODO if B is also a movable we don't check with it's changing position Vector3f minB = Vector3f::min(pointB, pointB + colB.bound); Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); - if (collide(minA, maxA, minB, maxB)) { - std::cout << "collided" << std::endl + if (boxesCollide(minAx, maxAx, minB, maxB)) { + /* std::cout << "collided" << std::endl << "minA " << minA << std::endl << "maxA " << maxA << std::endl << "minB " << minB << std::endl - << "maxB " << maxB << std::endl; - return; - colA.onCollide(entity, other); - colB.onCollided(entity, other); + << "maxB " << maxB << std::endl;*/ + //return; + collidedAxis += CollisionComponent::CollidedAxis::X; + } + if (boxesCollide(minAy, maxAy, minB, maxB)) { + collidedAxis += CollisionComponent::CollidedAxis::Y; + } + if (boxesCollide(minAz, maxAz, minB, maxB)) { + collidedAxis += CollisionComponent::CollidedAxis::Z; + } + if (collidedAxis) { + colA.onCollide(entity, other, collidedAxis); + colB.onCollided(entity, other, collidedAxis); } } } diff --git a/sources/System/Collision/CollisionSystem.hpp b/sources/System/Collision/CollisionSystem.hpp index 2c0f5491..e1e75ede 100644 --- a/sources/System/Collision/CollisionSystem.hpp +++ b/sources/System/Collision/CollisionSystem.hpp @@ -31,6 +31,6 @@ namespace BBM CollisionSystem &operator=(const CollisionSystem &) = delete; //! @brief check AABB collision - static bool collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB); + static bool boxesCollide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB); }; } \ No newline at end of file From b0292be205d1c1f0a0e217c5db1781260d8e16ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 00:25:14 +0200 Subject: [PATCH 13/40] collisions working as expected fine on debug mode --- sources/System/Collision/CollisionSystem.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index 14b6c12a..c45f3ca1 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -28,9 +28,9 @@ namespace BBM auto &posA = entity.get(); auto &colA = entity.get(); Vector3f pointA = posA.position + colA.positionOffset; - Vector3f pointAx; - Vector3f pointAy; - Vector3f pointAz; + Vector3f pointAx = pointA; + Vector3f pointAy = pointA; + Vector3f pointAz = pointA; if (auto *movable = entity->tryGetComponent()) { auto vel = movable->getVelocity(); @@ -60,12 +60,6 @@ namespace BBM Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); if (boxesCollide(minAx, maxAx, minB, maxB)) { - /* std::cout << "collided" << std::endl - << "minA " << minA << std::endl - << "maxA " << maxA << std::endl - << "minB " << minB << std::endl - << "maxB " << maxB << std::endl;*/ - //return; collidedAxis += CollisionComponent::CollidedAxis::X; } if (boxesCollide(minAy, maxAy, minB, maxB)) { From 556021a4ef13368f03122f3c236aab7370fdfc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 00:35:34 +0200 Subject: [PATCH 14/40] map colliders seems nice --- sources/Component/Collision/CollisionComponent.hpp | 2 +- sources/Map/Map.cpp | 14 +++++++------- sources/Runner/Runner.cpp | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 1be3590d..77f5f429 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -48,7 +48,7 @@ namespace BBM const WAL::Callback &onCollide, const WAL::Callback &onCollided, float positionOffset, - float boundSize = 0); + float boundSize); //! @brief Constructor of collider with no callback CollisionComponent(WAL::Entity &entity, Vector3f positionOffset, Vector3f bound); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 937343c8..276afb29 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -57,7 +57,7 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); } } @@ -71,25 +71,25 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -139,7 +139,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent(1) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -172,7 +172,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); } diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index af08e264..39fe9fd1 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -79,14 +79,14 @@ namespace BBM scene->addEntity("camera") .addComponent(10, 20, 10) .addComponent(Vector3f(2, 0, 2)); - scene->addEntity("cube") + /*scene->addEntity("cube") .addComponent(-5, 0, -5) .addComponent(Vector3f(0, 0, 0), Vector3f(3, 3, 3), RED) .addComponent() .addComponent() - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3);*/ std::srand(std::time(nullptr)); - //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); + MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; } From 3649c8247c319869553506c432f9ba1a71ef2e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 00:47:39 +0200 Subject: [PATCH 15/40] cleanup before PR --- lib/Ray/sources/Camera/Camera3D.cpp | 1 - sources/Runner/Runner.cpp | 4 ++-- sources/System/Renderer/RenderSystem.cpp | 20 -------------------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/lib/Ray/sources/Camera/Camera3D.cpp b/lib/Ray/sources/Camera/Camera3D.cpp index 0c4b3d13..aa2b2a9b 100644 --- a/lib/Ray/sources/Camera/Camera3D.cpp +++ b/lib/Ray/sources/Camera/Camera3D.cpp @@ -10,7 +10,6 @@ RAY::Camera::Camera3D::Camera3D(const RAY::Vector3 &position, const RAY::Vector3 &target, const RAY::Vector3 &up, float fovy, Projection projection): _camera({position, target, up, fovy, projection}) { - SetCameraMode(_camera, CAMERA_FREE); } void RAY::Camera::Camera3D::setPosition(const Vector3 &Position) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 39fe9fd1..6371c648 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -77,8 +77,8 @@ namespace BBM animation.setAnimIndex(5); }); scene->addEntity("camera") - .addComponent(10, 20, 10) - .addComponent(Vector3f(2, 0, 2)); + .addComponent(8, 20, 7) + .addComponent(Vector3f(8, 0, 8)); /*scene->addEntity("cube") .addComponent(-5, 0, -5) .addComponent(Vector3f(0, 0, 0), Vector3f(3, 3, 3), RED) diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index b6ef7891..7c5cfd9a 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -32,26 +32,6 @@ namespace BBM this->_window.useCamera(this->_camera); for (auto &[_, pos, drawable] : this->_wal.scene->view()) { - if (_.getName() == "cube") { - auto col = _.getComponent(); - DrawCubeWires({pos.position.x, pos.position.y, pos.position.z}, - col.bound.x, - col.bound.y, - col.bound.z, - WHITE); - DrawPoint3D({pos.position.x, pos.position.y, pos.position.z}, BLUE); - DrawPoint3D({pos.position.x + col.bound.x, pos.position.y + col.bound.y, pos.position.z + col.bound.z}, BLUE); - } - if (_.getName() == "player") { - auto col = _.getComponent(); - DrawCubeWires({pos.position.x, pos.position.y, pos.position.z}, - col.bound.x, - col.bound.y, - col.bound.z, - WHITE); - DrawPoint3D({pos.position.x, pos.position.y, pos.position.z}, BLUE); - DrawPoint3D({pos.position.x + col.bound.x, pos.position.y + col.bound.y, pos.position.z + col.bound.z}, BLUE); - } drawable.drawable->setPosition(pos.position); drawable.drawable->drawOn(this->_window); } From ca930db44d29fded1b6cc01c45e54df7385749e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 00:55:32 +0200 Subject: [PATCH 16/40] more cleanup --- sources/Component/Collision/CollisionComponent.hpp | 3 ++- sources/Map/Map.cpp | 8 -------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 77f5f429..02eaf4b9 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -15,6 +15,7 @@ namespace BBM { public: //! @brief Used to tell the collided axis + //! @note Usage: (collidedAxis (int given by callback)) & CollidedAxis::X enum CollidedAxis { X = 1, Y = 2, @@ -53,7 +54,7 @@ namespace BBM //! @brief Constructor of collider with no callback CollisionComponent(WAL::Entity &entity, Vector3f positionOffset, Vector3f bound); - //! @brief Constructor no callback, same boundSize for all axis + //! @brief Constructor no callback, same boundSize & positionOffset for all axis CollisionComponent(WAL::Entity &entity, float positionOffset, float boundSize); //! @brief Default copy constructor diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 276afb29..30a1f21f 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -15,17 +15,9 @@ namespace BBM void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis) { auto *mov = entity.tryGetComponent(); - auto posspec = entity.getComponent(); - auto posspecwall = wall.getComponent(); if (!mov) return; - - auto &pos = entity.getComponent(); - const auto &wallPos = wall.getComponent(); - auto diff = pos.position + mov->getVelocity() - wallPos.position; - //mov->_velocity = Vector3f(); - //return; if (collidedAxis & CollisionComponent::CollidedAxis::X) mov->_velocity.x = 0; if (collidedAxis & CollisionComponent::CollidedAxis::Y) From b17c60aa6ce996e2e55ad9c23954a2e24b04df80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 01:00:05 +0200 Subject: [PATCH 17/40] fixing unit tests compil --- tests/CollisionTest.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp index 8392aa85..34bff636 100644 --- a/tests/CollisionTest.cpp +++ b/tests/CollisionTest.cpp @@ -8,6 +8,7 @@ #include "Wal.hpp" #define private public + #include "System/Collision/CollisionSystem.hpp" #include "System/Movable/MovableSystem.hpp" #include "Component/Movable/MovableComponent.hpp" @@ -24,14 +25,14 @@ TEST_CASE("Collision test", "[Component][System]") wal.scene = std::make_shared(); wal.scene->addEntity("player") .addComponent() - .addComponent([](Entity &actual, const Entity &) { + .addComponent([](Entity &actual, const Entity &, int _) { try { auto &pos = actual.getComponent(); pos.position.x = 1; pos.position.y = 1; pos.position.z = 1; } catch (std::exception &e) {}; - }, [](Entity &, const Entity &){}, 5.0); + }, [](Entity &, const Entity &, int) {}, 0, 5.0); Entity &entity = wal.scene->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); @@ -44,10 +45,10 @@ TEST_CASE("Collision test", "[Component][System]") REQUIRE(entity.getComponent().position.x == 0.0); REQUIRE(entity.getComponent().position.y == 0.0); REQUIRE(entity.getComponent().position.z == 0.0); - + wal.scene->addEntity("block") - .addComponent(2,2,2) - .addComponent(1); + .addComponent(2, 2, 2) + .addComponent(0, 1); Entity &player = wal.scene->getEntities().front(); collision.update(std::chrono::nanoseconds(1)); REQUIRE(player.hasComponent(typeid(PositionComponent))); @@ -68,17 +69,19 @@ TEST_CASE("Collsion test with movable", "[Component][System]") wal.scene = std::make_shared(); wal.scene->addEntity("player") .addComponent() - .addComponent([](Entity &actual, const Entity &) {}, [](Entity &actual, const Entity &) {}, 5.0) + .addComponent([](Entity &actual, const Entity &, int) {}, + [](Entity &actual, const Entity &, int) {}, 0, 5.0) .addComponent(); - + wal.scene->addEntity("block") .addComponent(0, 0, 0) - .addComponent([](Entity &actual, const Entity &){}, [](Entity &actual, const Entity &) { - try { - auto &mov = actual.getComponent(); - mov._velocity = Vector3f(); - } catch (std::exception &e) {}; - }, 1); + .addComponent([](Entity &actual, const Entity &, int) {}, + [](Entity &actual, const Entity &, int) { + try { + auto &mov = actual.getComponent(); + mov._velocity = Vector3f(); + } catch (std::exception &e) {}; + }, 0, 1); Entity &entity = wal.scene->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); From aba85c918e9b9093b9bb9db6521bda48dbfa19b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 01:10:15 +0200 Subject: [PATCH 18/40] adding QoL changes --- sources/Map/Map.cpp | 14 +++++++------- sources/System/Collision/CollisionSystem.cpp | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 30a1f21f..ad5b2f09 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -49,7 +49,7 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); } } @@ -63,25 +63,25 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -131,7 +131,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent(1) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -164,7 +164,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0, .90) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); } diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index c45f3ca1..cbc2c155 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -37,6 +37,7 @@ namespace BBM pointAx.x += vel.x; pointAy.y += vel.y; pointAz.z += vel.z; + pointA += vel; } Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound); From 8ac6b7d11fb83bd766e5a5538876af07d7a2fb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 01:15:50 +0200 Subject: [PATCH 19/40] rm no longer useful statement --- sources/System/Collision/CollisionSystem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index cbc2c155..c45f3ca1 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -37,7 +37,6 @@ namespace BBM pointAx.x += vel.x; pointAy.y += vel.y; pointAz.z += vel.z; - pointA += vel; } Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound); From 8c380e05b17e2d0cc7bb20ddb3a07403f7d7e9f2 Mon Sep 17 00:00:00 2001 From: TrueBabyChaise Date: Tue, 8 Jun 2021 10:45:36 +0200 Subject: [PATCH 20/40] add map for SoundSystem and fix error in MusicComponent --- sources/Component/Music/MusicComponent.cpp | 10 ++--- sources/Component/Music/MusicComponent.hpp | 9 ++-- sources/Component/Sound/SoundComponent.cpp | 12 +++--- sources/Component/Sound/SoundComponent.hpp | 2 +- .../System/Sound/PlayerSoundManagerSystem.cpp | 43 +++++++++---------- .../System/Sound/PlayerSoundManagerSystem.hpp | 6 +-- 6 files changed, 37 insertions(+), 45 deletions(-) diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index e1aaca5e..339e040d 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -7,20 +7,16 @@ namespace BBM { - MusicComponent::MusicComponent(WAL::Entity &entity, std::string &musicPath) + MusicComponent::MusicComponent(WAL::Entity &entity, const std::string &musicPath) : WAL::Component(entity), + _musicPath(musicPath), _music(RAY::Audio::Music(musicPath)) { } - MusicComponent::MusicComponent(WAL::Entity &entity) - : Component(entity), - _music() - {} - WAL::Component *MusicComponent::clone(WAL::Entity &entity) const { - return new MusicComponent(entity); + return new MusicComponent(entity, this->_musicPath); } void MusicComponent::loadMusic(void) diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index 132179f2..835a8e5c 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -35,20 +35,19 @@ namespace BBM //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new MusicComponent at a certain Music - MusicComponent(WAL::Entity &entity, std::string &musicPath); + explicit MusicComponent(WAL::Entity &entity, const std::string &musicPath); //! @brief A Music component is copy constructable MusicComponent(const MusicComponent &) = default; //! @brief A default destructor ~MusicComponent() override = default; //! @brief A Music component is not assignable MusicComponent &operator=(const MusicComponent &) = delete; + private: //! @brief music of this entity RAY::Audio::Music _music; - //! @brief Create a new MusicComponent linked to a specific entity - explicit MusicComponent(WAL::Entity &entity); - - + //! @brief patht to the music assets + const std::string _musicPath; }; } // namespace BBM \ No newline at end of file diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index d4ab53b1..3265d724 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -19,7 +19,7 @@ std::map &soundPath) this->_isLoad[static_cast(i)] = false; } else { this->_isLoad[static_cast(i)] = true; - this->_soundList[static_cast(i)] = std::unique_ptr(new RAY::Audio::Sound(soundPath.at(static_cast(i)))); + this->_soundList[static_cast(i)] = std::make_unique(soundPath.at(static_cast(i))); } } } @@ -35,7 +35,7 @@ std::map &soundPath) return new SoundComponent(entity); } - void SoundComponent::playSound(void) + void SoundComponent::playSound() { if (!this->_isLoad.at(this->_soundIndex)) return; @@ -43,7 +43,7 @@ std::map &soundPath) this->_soundList[this->_soundIndex].get()->play(); } - void SoundComponent::stopSound(void) + void SoundComponent::stopSound() { if (!this->_isLoad.at(this->_soundIndex)) return; @@ -51,7 +51,7 @@ std::map &soundPath) this->_soundList[this->_soundIndex].get()->stop(); } - void SoundComponent::pauseSound(void) + void SoundComponent::pauseSound() { if (!this->_isLoad.at(this->_soundIndex)) return; @@ -73,7 +73,7 @@ std::map &soundPath) this->_soundList[this->_soundIndex].get()->setPitch(pitch); } - bool SoundComponent::isPlaying(void) + bool SoundComponent::isPlaying() { if (!this->_isLoad.at(this->_soundIndex)) return (false); @@ -85,7 +85,7 @@ std::map &soundPath) this->_soundIndex = index; } - SoundComponent::soundIndex SoundComponent::getIndex(void) + SoundComponent::soundIndex SoundComponent::getIndex() { return (this->_soundIndex); } diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index e4b7ed5e..6c35d197 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -45,7 +45,7 @@ namespace BBM void setPitch(float &); //! @brief is Sound playing - bool isPlaying(void); + bool isPlaying(); //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp index 187f55e3..6b50f31f 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.cpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -3,33 +3,30 @@ // #include "PlayerSoundManagerSystem.hpp" +#include namespace BBM { - - SoundManagerSystem::SoundManagerSystem() - : WAL::System({ - typeid(SoundComponent), - typeid(HealthComponent) - }) + SoundManagerSystem::SoundManagerSystem(WAL::Wal &wal) + : System(wal) {} - void SoundManagerSystem::onFixedUpdate(WAL::Entity &entity) - { - if (!entity.hasComponent()) - return; - const auto &controllable = entity.getComponent(); - auto &sound = entity.getComponent(); - auto &health = entity.getComponent(); + void SoundManagerSystem::onFixedUpdate(WAL::ViewEntity &entity) + { + const auto &controllable = entity.get(); + auto &sound = entity.get(); + auto &health = entity.get(); - sound.setIndex(SoundComponent::BOMB); - if (controllable.bomb) - sound.playSound(); - sound.setIndex(SoundComponent::JUMP); - if (controllable.jump) - sound.playSound(); - sound.setIndex(SoundComponent::MOVE); - if (controllable.move.x != 0 || controllable.move.y != 0) - sound.playSound(); - } + std::map soundIndex = { + {controllable.bomb, SoundComponent::BOMB}, + {controllable.jump, SoundComponent::JUMP}, + {controllable.move.x != 0 || controllable.move.y != 0, SoundComponent::MOVE} + }; + for (auto &a : soundIndex) { + if (a.first) { + sound.setIndex(a.second); + sound.playSound(); + } + } + } } \ No newline at end of file diff --git a/sources/System/Sound/PlayerSoundManagerSystem.hpp b/sources/System/Sound/PlayerSoundManagerSystem.hpp index 38cd4bfa..2f1967ff 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.hpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.hpp @@ -13,14 +13,14 @@ namespace BBM { - class SoundManagerSystem : public WAL::System + class SoundManagerSystem : public WAL::System { public: //! @inherit - void onFixedUpdate(WAL::Entity &entity) override; + void onFixedUpdate(WAL::ViewEntity &entity) override; //! @brief ctor - SoundManagerSystem(); + SoundManagerSystem(WAL::Wal &wal); //! @brief Default copy ctor SoundManagerSystem(const SoundManagerSystem &) = default; //! @brief Default dtor From 473b6d64e8feb9cd1000c1702bac0dbcf737148b Mon Sep 17 00:00:00 2001 From: TrueBabyChaise Date: Tue, 8 Jun 2021 10:50:42 +0200 Subject: [PATCH 21/40] remove empty ctor for SoundComponent --- sources/Component/Sound/SoundComponent.cpp | 10 ++-------- sources/Component/Sound/SoundComponent.hpp | 9 ++------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index 3265d724..a6a31323 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -9,7 +9,7 @@ namespace BBM { SoundComponent::SoundComponent(WAL::Entity &entity, \ -std::map &soundPath) +const std::map &soundPath) : WAL::Component(entity), _soundIndex(IDLE), _soundPath(soundPath) @@ -24,15 +24,9 @@ std::map &soundPath) } } - SoundComponent::SoundComponent(WAL::Entity &entity) - : Component(entity), - _soundList(), - _soundIndex() - {} - WAL::Component *SoundComponent::clone(WAL::Entity &entity) const { - return new SoundComponent(entity); + return new SoundComponent(entity, this->_soundPath); } void SoundComponent::playSound() diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index 6c35d197..1df2a537 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -50,7 +50,7 @@ namespace BBM //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new SoundComponent at a certain Sound - SoundComponent(WAL::Entity &entity, std::map &); + explicit SoundComponent(WAL::Entity &entity, const std::map &); //! @brief A Sound component is copy constructable SoundComponent(const SoundComponent &) = default; //! @brief A default destructor @@ -63,16 +63,11 @@ namespace BBM std::map _isLoad; - std::map _soundPath; + const std::map _soundPath; //! SoundIndex soundIndex _soundIndex; - - //! @brief Create a new SoundComponent linked to a specific entity - explicit SoundComponent(WAL::Entity &entity); - - }; } // namespace BBM \ No newline at end of file From 23e26b59ae96410f6fd35757b243e1119e03140a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 11:30:40 +0200 Subject: [PATCH 22/40] coding style fix --- sources/System/Renderer/RenderSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index 7c5cfd9a..e735c1e9 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -47,8 +47,8 @@ namespace BBM this->_window.endDrawing(); } - void - RenderSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + void RenderSystem::onUpdate(WAL::ViewEntity &entity, + std::chrono::nanoseconds dtime) { const auto &pos = entity.get(); const auto &cam = entity.get(); From d08613a9d41192d2c61fb9c34caba304ccdd6e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 11:58:30 +0200 Subject: [PATCH 23/40] zoe has to smile ! --- .../Collision/CollisionComponent.cpp | 8 +- .../Collision/CollisionComponent.hpp | 12 +- sources/Map/Map.cpp | 46 +++- sources/Map/Map.hpp | 251 +++++++++--------- sources/System/Collision/CollisionSystem.cpp | 4 +- 5 files changed, 172 insertions(+), 149 deletions(-) diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index 678b0898..652e6727 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -16,8 +16,8 @@ namespace BBM } CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound) : WAL::Component(entity), @@ -28,8 +28,8 @@ namespace BBM {} CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize) : WAL::Component(entity), diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 02eaf4b9..06878a76 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -23,9 +23,9 @@ namespace BBM }; //! @brief onCollide functions to be called - WAL::Callback onCollide; + WAL::Callback onCollide; //! @brief onCollided functions to be called - WAL::Callback onCollided; + WAL::Callback onCollided; //! @brief Bound size on all axis Vector3f bound; //! @brief Offset from the position component @@ -39,15 +39,15 @@ namespace BBM //! @brief Constructor with a WAL::Callback CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound); //! @brief Constructor with a WAL::Callback, same boundSize for all axis CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index ad5b2f09..1fd5b0bc 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -12,7 +12,9 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { - void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis) + void MapGenerator::wallCollide(WAL::Entity &entity, + const WAL::Entity &wall, + CollisionComponent::CollidedAxis collidedAxis) { auto *mov = entity.tryGetComponent(); @@ -49,8 +51,11 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) - .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) + .addComponent(unbreakableObj, + std::make_pair(MAP_DIFFUSE, unbreakablePng)); } } } @@ -63,25 +68,33 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -97,7 +110,7 @@ namespace BBM if (map[std::make_tuple(i, 0, j)] != HOLE && map[std::make_tuple(i, -1, j)] != BUMPER) scene->addEntity("Unbreakable Wall") .addComponent(Vector3f(i, -1, j)) - .addComponent(floorObj, + .addComponent(floorObj, std::make_pair(MAP_DIFFUSE, floorPng)); } } @@ -131,7 +144,9 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent(1) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -142,7 +157,7 @@ namespace BBM scene->addEntity("Floor") .addComponent(Vector3f(coords)) - //.addComponent(1) + //.addComponent(1) .addComponent(floorObj, std::make_pair(MAP_DIFFUSE, floorPng)); } @@ -164,7 +179,9 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 0.25, .75) + .addComponent( + WAL::Callback(), + &MapGenerator::wallCollide, 0.25, .75) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); } @@ -183,7 +200,8 @@ namespace BBM if (coords.y == 0) holeEntity.addComponent(holeObj, std::make_pair(MAP_DIFFUSE, holePng)); else - holeEntity.addComponent(secondFloorObj, std::make_pair(MAP_DIFFUSE, secondFloorPng)); + holeEntity.addComponent(secondFloorObj, + std::make_pair(MAP_DIFFUSE, secondFloorPng)); /*.addComponent([](WAL::Entity &other, const WAL::Entity &entity) { if (other.hasComponent()) { auto &health = other.getComponent(); @@ -215,7 +233,7 @@ namespace BBM scene->addEntity("Stairs Block") .addComponent(coords) - //.addComponent(1) + //.addComponent(1) .addComponent(stairsObj, std::make_pair(MAP_DIFFUSE, stairsPng)); } @@ -328,7 +346,7 @@ namespace BBM return (map); } - void MapGenerator::loadMap(int width, int height, MapBlock map, std::shared_ptr scene) + void MapGenerator::loadMap(int width, int height, MapBlock map, const std::shared_ptr &scene) { generateWall(width, height, scene); generateFloor(map, width, height, scene); diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index f705eebf..82af402a 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -27,149 +27,154 @@ namespace BBM class MapGenerator { - private: - //! @brief Enum of the block available. - enum BlockType { - NOTHING, - BREAKABLE, - HOLE, - UPPERFLOOR, - FLOOR, - BUMPER, - STAIRS, - SPAWNER, - UNBREAKABLE - }; + private: + //! @brief Enum of the block available. + enum BlockType + { + NOTHING, + BREAKABLE, + HOLE, + UPPERFLOOR, + FLOOR, + BUMPER, + STAIRS, + SPAWNER, + UNBREAKABLE + }; - using MapElem = std::function scene)>; - using MapBlock = std::map, BlockType>; + using MapElem = std::function scene)>; + using MapBlock = std::map, BlockType>; - //! @brief Generate random block type - static BlockType getRandomBlockType(); + //! @brief Generate random block type + static BlockType getRandomBlockType(); - //! @param map ASCII map - //! @param x x index on the block - //! @param z z index on the block - //! @param blockType blockType to compare with position - static bool isCloseToBlockType(std::map, BlockType> map, int x, int y, int z, BlockType blockType); + //! @param map ASCII map + //! @param x x index on the block + //! @param z z index on the block + //! @param blockType blockType to compare with position + static bool isCloseToBlockType(std::map, BlockType> map, + int x, int y, int z, + BlockType blockType); - //! @param width Width of the map - //! @param height Height of the map - //! @param scene Scene where the map is instanced - //! @brief Generate the unbreakable block of the map - static void generateUnbreakableBlock(int width, int height, std::shared_ptr scene); + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the unbreakable block of the map + static void generateUnbreakableBlock(int width, int height, std::shared_ptr scene); - //! @param width Width of the map - //! @param height Height of the map - //! @param scene Scene where the map is instanced - //! @brief Generate the wall of the map - static void generateWall(int width, int height, std::shared_ptr scene); + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the wall of the map + static void generateWall(int width, int height, std::shared_ptr scene); - //! @param width Width of the map - //! @param height Height of the map - //! @param scene Scene where the map is instanced - //! @brief Generate the floor of the map - static void generateFloor(MapBlock map, int width, int height, std::shared_ptr scene); + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the floor of the map + static void generateFloor(MapBlock map, int width, int height, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create element of the map - static void createElement(Vector3f coords, std::shared_ptr scene, BlockType blockType); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create element of the map + static void createElement(Vector3f coords, std::shared_ptr scene, BlockType blockType); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create breakable of the map - static void createBreakable(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create breakable of the map + static void createBreakable(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create unbreakable of the map - static void createUnbreakable(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create unbreakable of the map + static void createUnbreakable(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create hole of the map - static void createHole(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create hole of the map + static void createHole(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create bumper of the map - static void createBumper(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create bumper of the map + static void createBumper(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create floor of the map - static void createFloor(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create floor of the map + static void createFloor(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create upper floor of the map - static void createUpperFloor(Vector3f coords, std::shared_ptr scene); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create upper floor of the map + static void createUpperFloor(Vector3f coords, std::shared_ptr scene); - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create stair of the map - static void createStairs(Vector3f coords, std::shared_ptr scene); - - //! @param map Map to load with block declared inside - //! @param width Width of the map - //! @param height Height of the map - //! @brief Generate map of block to be loaded - static MapBlock createSpawner(MapBlock map, int width, int height); + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create stair of the map + static void createStairs(Vector3f coords, std::shared_ptr scene); - //! @param map Map to load with block declared inside - //! @param width Width of the map - //! @param height Height of the map - //! @brief Generate height for the map - static MapBlock createHeight(MapBlock map, int width, int height); + //! @param map Map to load with block declared inside + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate map of block to be loaded + static MapBlock createSpawner(MapBlock map, int width, int height); - //! @param map Map to load with block declared inside - //! @param width Width of the map - //! @param height Height of the map - //! @brief Clean breakable on stairs, bumpers, etc.. - static MapBlock cleanBreakable(MapBlock map, int width, int height); + //! @param map Map to load with block declared inside + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate height for the map + static MapBlock createHeight(MapBlock map, int width, int height); - - static const std::string assetsPath; - - static const std::string wallAssetsPath; - - static const std::string imageExtension; - - static const std::string objExtension; - - static const std::string unbreakableWallPath; - - static const std::string breakableWallPath; - - static const std::string floorPath; - - static const std::string stairsPath; - - static const std::string bumperPath; - - static const std::string secondFloorPath; - - static const std::string holePath; - - static const std::string secondFloorHolePath; - - public: - static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis); + //! @param map Map to load with block declared inside + //! @param width Width of the map + //! @param height Height of the map + //! @brief Clean breakable on stairs, bumpers, etc.. + static MapBlock cleanBreakable(MapBlock map, int width, int height); - //! @param width Width of the map - //! @param height Height of the map - //! @brief Generate map of block to be loaded - static MapBlock createMap(int width, int height); + static const std::string assetsPath; + + static const std::string wallAssetsPath; + + static const std::string imageExtension; + + static const std::string objExtension; + + static const std::string unbreakableWallPath; + + static const std::string breakableWallPath; + + static const std::string floorPath; + + static const std::string stairsPath; + + static const std::string bumperPath; + + static const std::string secondFloorPath; + + static const std::string holePath; + + static const std::string secondFloorHolePath; + + public: + static void wallCollide(WAL::Entity &entity, + const WAL::Entity &wall, + CollisionComponent::CollidedAxis collidedAxis); + + + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate map of block to be loaded + static MapBlock createMap(int width, int height); + + //! @param width Width of the map + //! @param height Height of the map + //! @param map Map to load with block declared inside + //! @param scene Scene where the map is instanced + //! @brief Generate the map + static void loadMap(int width, int height, MapBlock map, const std::shared_ptr &scene); - //! @param width Width of the map - //! @param height Height of the map - //! @param map Map to load with block declared inside - //! @param scene Scene where the map is instanced - //! @brief Generate the map - static void loadMap(int width, int height, MapBlock map, std::shared_ptr scene); - }; } // namespace BBM \ No newline at end of file diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index c45f3ca1..db68e3c0 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -69,8 +69,8 @@ namespace BBM collidedAxis += CollisionComponent::CollidedAxis::Z; } if (collidedAxis) { - colA.onCollide(entity, other, collidedAxis); - colB.onCollided(entity, other, collidedAxis); + colA.onCollide(entity, other, static_cast(collidedAxis)); + colB.onCollided(entity, other, static_cast(collidedAxis)); } } } From 395566598cd6d834366d87df00fc793ccad1fd49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 12:02:56 +0200 Subject: [PATCH 24/40] last fixes --- sources/Map/Map.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 1fd5b0bc..3f8ba259 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -13,7 +13,7 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { void MapGenerator::wallCollide(WAL::Entity &entity, - const WAL::Entity &wall, + const WAL::Entity &wall, CollisionComponent::CollidedAxis collidedAxis) { auto *mov = entity.tryGetComponent(); @@ -157,7 +157,7 @@ namespace BBM scene->addEntity("Floor") .addComponent(Vector3f(coords)) - //.addComponent(1) + //.addComponent(1) .addComponent(floorObj, std::make_pair(MAP_DIFFUSE, floorPng)); } @@ -233,7 +233,7 @@ namespace BBM scene->addEntity("Stairs Block") .addComponent(coords) - //.addComponent(1) + //.addComponent(1) .addComponent(stairsObj, std::make_pair(MAP_DIFFUSE, stairsPng)); } From 856eb1adc29041cd4da32180c2460d3e1ff08bbc Mon Sep 17 00:00:00 2001 From: Askou Date: Tue, 8 Jun 2021 14:10:13 +0200 Subject: [PATCH 25/40] fuse sound assets --- assets/sounds/fuse.ogg | Bin 0 -> 9182 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/sounds/fuse.ogg diff --git a/assets/sounds/fuse.ogg b/assets/sounds/fuse.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1d3007e825fad40da8f3a5824c1b1f7865db0854 GIT binary patch literal 9182 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 literal 0 HcmV?d00001 From 6c7d8fcfcfe4ce595dda1eba3eba74f2cadc31c8 Mon Sep 17 00:00:00 2001 From: Askou Date: Tue, 8 Jun 2021 14:52:03 +0200 Subject: [PATCH 26/40] add updateMusicStream + musicSystem --- CMakeLists.txt | 2 + lib/Ray/sources/Audio/Music.cpp | 6 + lib/Ray/sources/Audio/Music.hpp | 2 + sources/Component/Music/MusicComponent.cpp | 74 ++++++----- sources/Component/Music/MusicComponent.hpp | 14 +- sources/Component/Sound/SoundComponent.cpp | 121 +++++++++--------- sources/Component/Sound/SoundComponent.hpp | 19 ++- sources/Runner/Runner.cpp | 12 +- sources/System/Music/MusicSystem.cpp | 24 ++++ sources/System/Music/MusicSystem.hpp | 31 +++++ .../System/Sound/PlayerSoundManagerSystem.cpp | 3 +- .../System/Sound/PlayerSoundManagerSystem.hpp | 2 +- 12 files changed, 198 insertions(+), 112 deletions(-) create mode 100644 sources/System/Music/MusicSystem.cpp create mode 100644 sources/System/Music/MusicSystem.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e919b9f0..3bc882f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,8 @@ set(SOURCES sources/Component/Sound/SoundComponent.cpp sources/System/Sound/PlayerSoundManagerSystem.cpp sources/System/Sound/PlayerSoundManagerSystem.hpp + sources/System/Music/MusicSystem.hpp + sources/System/Music/MusicSystem.cpp ) add_executable(bomberman sources/main.cpp diff --git a/lib/Ray/sources/Audio/Music.cpp b/lib/Ray/sources/Audio/Music.cpp index db3dae78..f58921bc 100644 --- a/lib/Ray/sources/Audio/Music.cpp +++ b/lib/Ray/sources/Audio/Music.cpp @@ -55,3 +55,9 @@ RAY::Audio::Music &RAY::Audio::Music::setPitch(float pitch) SetMusicPitch(*_music, pitch); return *this; } + +RAY::Audio::Music &RAY::Audio::Music::updateMusicStream(void) +{ + UpdateMusicStream(*_music); + return *this; +} diff --git a/lib/Ray/sources/Audio/Music.hpp b/lib/Ray/sources/Audio/Music.hpp index c28e8089..66ab0162 100644 --- a/lib/Ray/sources/Audio/Music.hpp +++ b/lib/Ray/sources/Audio/Music.hpp @@ -51,6 +51,8 @@ namespace RAY::Audio // Set pitch for a Music (1.0 is base level) Music &setPitch(float pitch) override; + Music &updateMusicStream(void); + private: std::shared_ptr<::Music> _music; diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index 339e040d..fe3867cb 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -7,49 +7,59 @@ namespace BBM { - MusicComponent::MusicComponent(WAL::Entity &entity, const std::string &musicPath) - : WAL::Component(entity), - _musicPath(musicPath), - _music(RAY::Audio::Music(musicPath)) - { - } + MusicComponent::MusicComponent(WAL::Entity &entity, const std::string &musicPath) + : WAL::Component(entity), + _musicPath(musicPath), + _music(RAY::Audio::Music(musicPath)) + { + } - WAL::Component *MusicComponent::clone(WAL::Entity &entity) const + WAL::Component *MusicComponent::clone(WAL::Entity &entity) const { return new MusicComponent(entity, this->_musicPath); } - void MusicComponent::loadMusic(void) - { - if (!this->_music.isPlaying()) - this->_music.play(); - } + void MusicComponent::playMusic(void) + { + if (!this->_music.isPlaying()) { + this->_music.play(); + this->_music.updateMusicStream(); + } + } - void MusicComponent::unloadMusic(void) - { - if (!this->_music.isPlaying()) - this->_music.stop(); - } + void MusicComponent::stopMusic(void) + { + if (!this->_music.isPlaying()) { + this->_music.stop(); + this->_music.updateMusicStream(); + } + } - void MusicComponent::pauseMusic(void) - { - this->_music.pause(); - } + void MusicComponent::pauseMusic(void) + { + this->_music.pause(); + } - void MusicComponent::setVolume(float &volume) - { - if (volume >= 0) - this->_music.setVolume(volume); - } + void MusicComponent::setVolume(float &volumeUpdate) + { + if (volumeUpdate >= 0) { + this->_music.setVolume(volume); + } + } void MusicComponent::setPitch(float &pitch) - { - this->_music.setPitch(pitch); - } + { + this->_music.setPitch(pitch); + } bool MusicComponent::isPlaying(void) - { - return (this->_music.isPlaying()); - } + { + return (this->_music.isPlaying()); + } + + void MusicComponent::updateMusicStream(void) + { + this->_music.updateMusicStream(); + } } // namespace WAL diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index 835a8e5c..5761437b 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -14,11 +14,11 @@ namespace BBM class MusicComponent : public WAL::Component { public: - //! @brief load music - void loadMusic(); + //! @brief start music + void playMusic(); - //! @brief unload music - void unloadMusic(); + //! @brief stop music + void stopMusic(); //! @brief put music on hold void pauseMusic(); @@ -31,7 +31,8 @@ namespace BBM //! @brief is music playing bool isPlaying(void); - + + void updateMusicStream(void); //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new MusicComponent at a certain Music @@ -42,7 +43,8 @@ namespace BBM ~MusicComponent() override = default; //! @brief A Music component is not assignable MusicComponent &operator=(const MusicComponent &) = delete; - + //! @brief Volume of the muisc + float volume = 1; private: //! @brief music of this entity RAY::Audio::Music _music; diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index a6a31323..dd492c03 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -8,80 +8,81 @@ namespace BBM { - SoundComponent::SoundComponent(WAL::Entity &entity, \ + SoundComponent::SoundComponent(WAL::Entity &entity, \ const std::map &soundPath) - : WAL::Component(entity), - _soundIndex(IDLE), - _soundPath(soundPath) - { - for (int i = 0; i <= DEATH; i++) { - if (soundPath.at(static_cast(i)).empty()) { - this->_isLoad[static_cast(i)] = false; - } else { - this->_isLoad[static_cast(i)] = true; - this->_soundList[static_cast(i)] = std::make_unique(soundPath.at(static_cast(i))); - } - } - } + : WAL::Component(entity), + _soundIndex(IDLE), + _soundPath(soundPath) + { + for (int i = 0; i <= DEATH; i++) { + if (soundPath.at(static_cast(i)).empty()) { + this->_isLoad[static_cast(i)] = false; + } else { + this->_isLoad[static_cast(i)] = true; + this->_soundList[static_cast(i)] = std::make_unique(soundPath.at(static_cast(i))); + } + } + } - WAL::Component *SoundComponent::clone(WAL::Entity &entity) const + WAL::Component *SoundComponent::clone(WAL::Entity &entity) const { return new SoundComponent(entity, this->_soundPath); } void SoundComponent::playSound() - { - if (!this->_isLoad.at(this->_soundIndex)) - return; - if (!this->_soundList[this->_soundIndex].get()->isPlaying()) - this->_soundList[this->_soundIndex].get()->play(); - } + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (!this->_soundList[this->_soundIndex].get()->isPlaying()) + this->_soundList[this->_soundIndex].get()->play(); + } - void SoundComponent::stopSound() - { - if (!this->_isLoad.at(this->_soundIndex)) - return; - if (this->_soundList[this->_soundIndex].get()->isPlaying()) - this->_soundList[this->_soundIndex].get()->stop(); - } + void SoundComponent::stopSound() + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (this->_soundList[this->_soundIndex].get()->isPlaying()) + this->_soundList[this->_soundIndex].get()->stop(); + } - void SoundComponent::pauseSound() - { - if (!this->_isLoad.at(this->_soundIndex)) - return; - this->_soundList[this->_soundIndex].get()->pause(); - } + void SoundComponent::pauseSound() + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + this->_soundList[this->_soundIndex].get()->pause(); + } - void SoundComponent::setVolume(float &volume) - { - if (!this->_isLoad.at(this->_soundIndex)) - return; - if (volume >= 0) - this->_soundList[this->_soundIndex].get()->setVolume(volume); - } + void SoundComponent::setVolume(float &volumeUpdate) + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + if (volumeUpdate >= 0) + this->volume = volumeUpdate; + this->_soundList[this->_soundIndex].get()->setVolume(this->volume); + } void SoundComponent::setPitch(float &pitch) - { - if (!this->_isLoad.at(this->_soundIndex)) - return; - this->_soundList[this->_soundIndex].get()->setPitch(pitch); - } + { + if (!this->_isLoad.at(this->_soundIndex)) + return; + this->_soundList[this->_soundIndex].get()->setPitch(pitch); + } bool SoundComponent::isPlaying() - { - if (!this->_isLoad.at(this->_soundIndex)) - return (false); - return (this->_soundList[this->_soundIndex].get()->isPlaying()); - } - - void SoundComponent::setIndex(soundIndex index) - { - this->_soundIndex = index; - } + { + if (!this->_isLoad.at(this->_soundIndex)) + return (false); + return (this->_soundList[this->_soundIndex].get()->isPlaying()); + } + + void SoundComponent::setIndex(soundIndex index) + { + this->_soundIndex = index; + } - SoundComponent::soundIndex SoundComponent::getIndex() - { - return (this->_soundIndex); - } + SoundComponent::soundIndex SoundComponent::getIndex() + { + return (this->_soundIndex); + } } // namespace WAL diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index 1df2a537..a953f6da 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -15,6 +15,7 @@ namespace BBM { public: + //! @brief All sounds of the player enum soundIndex { IDLE, JUMP, @@ -25,15 +26,17 @@ namespace BBM DEATH, }; + //! @brief to set what sound should be played void setIndex(soundIndex index); + //! @brief to know which sound is selected soundIndex getIndex(); - //! @brief load Sound + //! @brief start sound void playSound(); - //! @brief unload Sound - void stopSound(); + //! @brief stop sound + void stopSound(); //! @brief put Sound on hold void pauseSound(); @@ -57,14 +60,16 @@ namespace BBM ~SoundComponent() override = default; //! @brief A Sound component is not assignable SoundComponent &operator=(const SoundComponent &) = delete; + //! @brief Volume of the sounds + float volume = 1; + private: - //! @brief Sound of this entity + //! @brief Sounds of this entity std::map> _soundList; - + //! @brief map to know if sound is loaded std::map _isLoad; - + //! @brief All sounds path const std::map _soundPath; - //! SoundIndex soundIndex _soundIndex; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index d977d757..244c3ae5 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -30,6 +30,7 @@ #include "Component/Music/MusicComponent.hpp" #include "Component/Sound/SoundComponent.hpp" #include "System/Sound/PlayerSoundManagerSystem.hpp" +#include "System/Music/MusicSystem.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; @@ -52,7 +53,8 @@ namespace BBM .addSystem() .addSystem() .addSystem() - .addSystem(); + .addSystem() + .addSystem(); } void enableRaylib(WAL::Wal &wal) @@ -69,12 +71,12 @@ namespace BBM auto scene = std::make_shared(); std::map soundPath= { {SoundComponent::IDLE, ""}, - {SoundComponent::JUMP, "assets/sounds/death.ogg"}, - {SoundComponent::BOMB, ""}, + {SoundComponent::JUMP, "assets/sounds/jump.wav"}, + {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, {SoundComponent::MOVE, "assets/sounds/jump.wav"}, {SoundComponent::HURT, ""}, {SoundComponent::THROW, ""}, - {SoundComponent::DEATH, ""} + {SoundComponent::DEATH, "assets/sounds/death.ogg"} }; scene->addEntity("player") .addComponent() @@ -85,7 +87,7 @@ namespace BBM .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(1) .addComponent() - //.addComponent("assets/musics/music_win.ogg"); + .addComponent("assets/musics/music_win.ogg") .addComponent(soundPath) .addComponent(1, [](WAL::Entity &entity) { auto &animation = entity.getComponent(); diff --git a/sources/System/Music/MusicSystem.cpp b/sources/System/Music/MusicSystem.cpp new file mode 100644 index 00000000..94cb7c7e --- /dev/null +++ b/sources/System/Music/MusicSystem.cpp @@ -0,0 +1,24 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include "MusicSystem.hpp" +#include + +namespace BBM { + + MusicSystem::MusicSystem(WAL::Wal &wal) + : System(wal) + {} + + void MusicSystem::onFixedUpdate(WAL::ViewEntity &entity) + { + auto &music = entity.get(); + + music.setVolume(music.volume); + if (!music.isPlaying()) + music.playMusic(); + music.updateMusicStream(); + + } +} \ No newline at end of file diff --git a/sources/System/Music/MusicSystem.hpp b/sources/System/Music/MusicSystem.hpp new file mode 100644 index 00000000..ce65321c --- /dev/null +++ b/sources/System/Music/MusicSystem.hpp @@ -0,0 +1,31 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#pragma once + +#include "System/System.hpp" +#include "Window.hpp" +#include "Component/Music/MusicComponent.hpp" +#include "Component/Health/HealthComponent.hpp" +#include +#include "Wal.hpp" + +namespace BBM +{ + class MusicSystem : public WAL::System + { + public: + //! @inherit + void onFixedUpdate(WAL::ViewEntity &entity) override; + + //! @brief ctor + MusicSystem(WAL::Wal &wal); + //! @brief Default copy ctor + MusicSystem(const MusicSystem &) = default; + //! @brief Default dtor + ~MusicSystem() override = default; + //! @brief A SoundManager screen system can't be assigned. + MusicSystem &operator=(const MusicSystem &) = delete; + }; +} diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp index 6b50f31f..487a4081 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.cpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -16,7 +16,8 @@ namespace BBM { const auto &controllable = entity.get(); auto &sound = entity.get(); auto &health = entity.get(); - + + sound.setVolume(sound.volume); std::map soundIndex = { {controllable.bomb, SoundComponent::BOMB}, {controllable.jump, SoundComponent::JUMP}, diff --git a/sources/System/Sound/PlayerSoundManagerSystem.hpp b/sources/System/Sound/PlayerSoundManagerSystem.hpp index 2f1967ff..42869888 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.hpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.hpp @@ -16,7 +16,7 @@ namespace BBM class SoundManagerSystem : public WAL::System { public: - //! @inherit + //! @inherit void onFixedUpdate(WAL::ViewEntity &entity) override; //! @brief ctor From 2f312db8db8dc4a5a4c37a7eca535ea5e28c8b27 Mon Sep 17 00:00:00 2001 From: Askou Date: Tue, 8 Jun 2021 15:02:09 +0200 Subject: [PATCH 27/40] add check if music is playing --- sources/System/Music/MusicSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/System/Music/MusicSystem.cpp b/sources/System/Music/MusicSystem.cpp index 94cb7c7e..ea909d9a 100644 --- a/sources/System/Music/MusicSystem.cpp +++ b/sources/System/Music/MusicSystem.cpp @@ -14,11 +14,11 @@ namespace BBM { void MusicSystem::onFixedUpdate(WAL::ViewEntity &entity) { auto &music = entity.get(); - + music.setVolume(music.volume); - if (!music.isPlaying()) + if (!music.isPlaying()) { music.playMusic(); + } music.updateMusicStream(); - } } \ No newline at end of file From 64c8d12bcee06f18af14672e01877f219e0f62f1 Mon Sep 17 00:00:00 2001 From: Askou Date: Tue, 8 Jun 2021 15:02:58 +0200 Subject: [PATCH 28/40] remove useless updateStream --- sources/Component/Music/MusicComponent.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index fe3867cb..a792a186 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -23,16 +23,13 @@ namespace BBM { if (!this->_music.isPlaying()) { this->_music.play(); - this->_music.updateMusicStream(); } } void MusicComponent::stopMusic(void) { - if (!this->_music.isPlaying()) { + if (this->_music.isPlaying()) this->_music.stop(); - this->_music.updateMusicStream(); - } } void MusicComponent::pauseMusic(void) From afc945c1748156b472df9d90da6f6385bd429db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 16:23:29 +0200 Subject: [PATCH 29/40] setting player's hitbox on his head too --- sources/Runner/Runner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 08a51d76..d6a20b6d 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -78,7 +78,7 @@ namespace BBM .addComponent() .addComponent() .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) - .addComponent(0, 1) + .addComponent(BBM::Vector3f{0.25, 0, 0.25}, BBM::Vector3f{.75, 2, .75}) .addComponent() .addComponent() .addComponent(1, [](WAL::Entity &entity) { From f12497ced636fc1a647a84c4d488bb66f679992e Mon Sep 17 00:00:00 2001 From: Askou Date: Tue, 8 Jun 2021 16:48:31 +0200 Subject: [PATCH 30/40] fix non static volume --- sources/Component/Music/MusicComponent.cpp | 1 + sources/Component/Music/MusicComponent.hpp | 2 +- sources/Component/Sound/SoundComponent.cpp | 1 + sources/Component/Sound/SoundComponent.hpp | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index a792a186..49bb03ff 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -12,6 +12,7 @@ namespace BBM _musicPath(musicPath), _music(RAY::Audio::Music(musicPath)) { + this->volume = 1; } WAL::Component *MusicComponent::clone(WAL::Entity &entity) const diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index 5761437b..2d291e47 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -44,7 +44,7 @@ namespace BBM //! @brief A Music component is not assignable MusicComponent &operator=(const MusicComponent &) = delete; //! @brief Volume of the muisc - float volume = 1; + static float volume; private: //! @brief music of this entity RAY::Audio::Music _music; diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index dd492c03..ddbddb77 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -14,6 +14,7 @@ const std::map &soundPath) _soundIndex(IDLE), _soundPath(soundPath) { + this->volume = 1; for (int i = 0; i <= DEATH; i++) { if (soundPath.at(static_cast(i)).empty()) { this->_isLoad[static_cast(i)] = false; diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index a953f6da..792140ab 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -61,7 +61,7 @@ namespace BBM //! @brief A Sound component is not assignable SoundComponent &operator=(const SoundComponent &) = delete; //! @brief Volume of the sounds - float volume = 1; + static float volume; private: //! @brief Sounds of this entity From 3b2eeba83f08898953bb45cdb08da32c5d10dfdb Mon Sep 17 00:00:00 2001 From: "arthur.jamet" Date: Tue, 8 Jun 2021 17:58:20 +0200 Subject: [PATCH 31/40] sound now has a shared ptr --- sources/Component/Sound/SoundComponent.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index 792140ab..8b4a4fef 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -65,7 +65,7 @@ namespace BBM private: //! @brief Sounds of this entity - std::map> _soundList; + std::map> _soundList; //! @brief map to know if sound is loaded std::map _isLoad; //! @brief All sounds path From 44afd5cd44eeddfab26cab4afddf8446032321ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 18:27:12 +0200 Subject: [PATCH 32/40] adding joystick support for gamepad controller --- lib/Ray/sources/Controllers/Gamepad.cpp | 5 +++++ lib/Ray/sources/Controllers/Gamepad.hpp | 4 ++++ sources/Component/Gamepad/GamepadComponent.hpp | 6 ++++++ sources/Runner/Runner.cpp | 4 +++- sources/System/Gamepad/GamepadSystem.cpp | 11 ++++++----- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/Ray/sources/Controllers/Gamepad.cpp b/lib/Ray/sources/Controllers/Gamepad.cpp index b51bcc95..7845411e 100644 --- a/lib/Ray/sources/Controllers/Gamepad.cpp +++ b/lib/Ray/sources/Controllers/Gamepad.cpp @@ -42,3 +42,8 @@ void RAY::Controller::GamePad::setID(int id) { this->_id = id; } + +float RAY::Controller::GamePad::getAxisValue(int index) +{ + return GetGamepadAxisMovement(this->_id, index); +} \ No newline at end of file diff --git a/lib/Ray/sources/Controllers/Gamepad.hpp b/lib/Ray/sources/Controllers/Gamepad.hpp index 893c674f..9f17acc8 100644 --- a/lib/Ray/sources/Controllers/Gamepad.hpp +++ b/lib/Ray/sources/Controllers/Gamepad.hpp @@ -17,6 +17,7 @@ namespace RAY::Controller { class GamePad { public: typedef ::GamepadButton Button; + typedef ::GamepadAxis Axis; //! @brief A default constructor //! @param The id of the controller @@ -44,6 +45,9 @@ namespace RAY::Controller { //! @param Button The keycode of the button bool isReleased(Button); + //! @brief Get the value of an axis + float getAxisValue(int index); + //! @brief Returns true if Button is up on the gamepad //! @param Button The keycode of the button bool isUp(Button); diff --git a/sources/Component/Gamepad/GamepadComponent.hpp b/sources/Component/Gamepad/GamepadComponent.hpp index be00a49b..3825645d 100644 --- a/sources/Component/Gamepad/GamepadComponent.hpp +++ b/sources/Component/Gamepad/GamepadComponent.hpp @@ -10,6 +10,7 @@ #include "Entity/Entity.hpp" using Button = RAY::Controller::GamePad::Button; +using Axis = RAY::Controller::GamePad::Axis; using Gamepad = RAY::Controller::GamePad; namespace BBM @@ -35,6 +36,11 @@ namespace BBM //! @brief move down key Button keyDown = GAMEPAD_BUTTON_LEFT_FACE_DOWN; + Axis LeftStickX = GAMEPAD_AXIS_LEFT_X; + Axis LeftStickY = GAMEPAD_AXIS_LEFT_Y; + Axis RightStickX = GAMEPAD_AXIS_RIGHT_X; + Axis RightStickY = GAMEPAD_AXIS_RIGHT_Y; + //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index d6a20b6d..6a047352 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -76,7 +76,8 @@ namespace BBM .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) .addComponent() .addComponent() - .addComponent() + //.addComponent() + .addComponent(0) .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(BBM::Vector3f{0.25, 0, 0.25}, BBM::Vector3f{.75, 2, .75}) .addComponent() @@ -96,6 +97,7 @@ namespace BBM .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3);*/ std::srand(std::time(nullptr)); MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); + return scene; } diff --git a/sources/System/Gamepad/GamepadSystem.cpp b/sources/System/Gamepad/GamepadSystem.cpp index f6d67d99..ee4b8767 100644 --- a/sources/System/Gamepad/GamepadSystem.cpp +++ b/sources/System/Gamepad/GamepadSystem.cpp @@ -31,10 +31,11 @@ namespace BBM for (auto key : keyPressedMap) key.second = gamepad.isPressed(key.first); - controllable.move = Vector2f(); - controllable.move.x += gamepad.isPressed(gamepadComponent.keyRight); - controllable.move.x -= gamepad.isPressed(gamepadComponent.keyLeft); - controllable.move.y += gamepad.isPressed(gamepadComponent.keyUp); - controllable.move.y -= gamepad.isPressed(gamepadComponent.keyDown); + controllable.move.x = gamepad.getAxisValue(gamepadComponent.LeftStickX) * -1; + controllable.move.y = gamepad.getAxisValue(gamepadComponent.LeftStickY) * -1; + controllable.move.x -= gamepad.isDown(gamepadComponent.keyRight); + controllable.move.x += gamepad.isDown(gamepadComponent.keyLeft); + controllable.move.y += gamepad.isDown(gamepadComponent.keyUp); + controllable.move.y -= gamepad.isDown(gamepadComponent.keyDown); } } \ No newline at end of file From efacfb53e37087587522f857ca3b1bf92c60c800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 18:37:57 +0200 Subject: [PATCH 33/40] fixing keyboard (he was switching between a and d) --- sources/Component/Keyboard/KeyboardComponent.hpp | 4 ++-- sources/Runner/Runner.cpp | 4 ++-- sources/System/Keyboard/KeyboardSystem.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sources/Component/Keyboard/KeyboardComponent.hpp b/sources/Component/Keyboard/KeyboardComponent.hpp index bd0f2ab7..2ad2e6f2 100644 --- a/sources/Component/Keyboard/KeyboardComponent.hpp +++ b/sources/Component/Keyboard/KeyboardComponent.hpp @@ -23,9 +23,9 @@ namespace BBM //! @brief pause key Key keyPause = KEY_ESCAPE; //! @brief move right key - Key keyRight = KEY_A; + Key keyRight = KEY_D; //! @brief move left key - Key keyLeft = KEY_D; + Key keyLeft = KEY_A; //! @brief move up key Key keyUp = KEY_W; //! @brief move down key diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 6a047352..591ce261 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -76,8 +76,8 @@ namespace BBM .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) .addComponent() .addComponent() - //.addComponent() - .addComponent(0) + .addComponent() + //.addComponent(0) .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(BBM::Vector3f{0.25, 0, 0.25}, BBM::Vector3f{.75, 2, .75}) .addComponent() diff --git a/sources/System/Keyboard/KeyboardSystem.cpp b/sources/System/Keyboard/KeyboardSystem.cpp index 740b9e3a..0f2a0cef 100644 --- a/sources/System/Keyboard/KeyboardSystem.cpp +++ b/sources/System/Keyboard/KeyboardSystem.cpp @@ -31,9 +31,9 @@ namespace BBM key.second = Keyboard::isPressed(key.first); controllable.move = Vector2f(); if (Keyboard::isDown(keyboard.keyRight)) - controllable.move.x += 1; - if (Keyboard::isDown(keyboard.keyLeft)) controllable.move.x -= 1; + if (Keyboard::isDown(keyboard.keyLeft)) + controllable.move.x += 1; if (Keyboard::isDown(keyboard.keyUp)) controllable.move.y += 1; if (Keyboard::isDown(keyboard.keyDown)) From 783704d11ed9a4ab42a24f67b0e5842638d1c723 Mon Sep 17 00:00:00 2001 From: "arthur.jamet" Date: Tue, 8 Jun 2021 19:17:12 +0200 Subject: [PATCH 34/40] fix sound asset --- assets/musics/music_win.ogg | Bin 76428 -> 24385 bytes lib/Ray/sources/Window.cpp | 2 +- sources/Component/Music/MusicComponent.cpp | 2 ++ sources/Component/Sound/SoundComponent.cpp | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/musics/music_win.ogg b/assets/musics/music_win.ogg index eadd8eff4af8279292eeb96afaf3ce3c2864cddc..ee5195e351818d5e4e03c79a4530217ca498e5c8 100644 GIT binary patch literal 24385 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 A2><{9 literal 76428 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
      3v9vn3ibijSr9(>0MO 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 diff --git a/lib/Ray/sources/Window.cpp b/lib/Ray/sources/Window.cpp index e91f6112..a9a1d9bf 100644 --- a/lib/Ray/sources/Window.cpp +++ b/lib/Ray/sources/Window.cpp @@ -40,7 +40,6 @@ RAY::Window::Window(int width, int height, std::string title, unsigned flags, bo { if (openNow) this->open(); - InitAudioDevice(); } bool RAY::Window::open(void) @@ -50,6 +49,7 @@ bool RAY::Window::open(void) } InitWindow(this->_dimensions.x, this->_dimensions.y, this->_title.c_str()); this->_isOpen = true; + InitAudioDevice(); return true; } diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index 49bb03ff..8d2656e3 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -15,6 +15,8 @@ namespace BBM this->volume = 1; } + float MusicComponent::volume; + WAL::Component *MusicComponent::clone(WAL::Entity &entity) const { return new MusicComponent(entity, this->_musicPath); diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index ddbddb77..b74fcc9b 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -25,6 +25,8 @@ const std::map &soundPath) } } + float SoundComponent::volume; + WAL::Component *SoundComponent::clone(WAL::Entity &entity) const { return new SoundComponent(entity, this->_soundPath); From ff7d9d411b36cf018278c98b661e88714442fab8 Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 09:53:28 +0200 Subject: [PATCH 35/40] full map not needed anymore --- sources/Component/Music/MusicComponent.cpp | 8 ++++---- sources/Component/Sound/SoundComponent.cpp | 19 +++++++++---------- sources/Runner/Runner.cpp | 6 +----- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/sources/Component/Music/MusicComponent.cpp b/sources/Component/Music/MusicComponent.cpp index 8d2656e3..40dc33b1 100644 --- a/sources/Component/Music/MusicComponent.cpp +++ b/sources/Component/Music/MusicComponent.cpp @@ -7,16 +7,15 @@ namespace BBM { + float MusicComponent::volume = 0.75; + MusicComponent::MusicComponent(WAL::Entity &entity, const std::string &musicPath) : WAL::Component(entity), _musicPath(musicPath), _music(RAY::Audio::Music(musicPath)) { - this->volume = 1; } - float MusicComponent::volume; - WAL::Component *MusicComponent::clone(WAL::Entity &entity) const { return new MusicComponent(entity, this->_musicPath); @@ -43,7 +42,8 @@ namespace BBM void MusicComponent::setVolume(float &volumeUpdate) { if (volumeUpdate >= 0) { - this->_music.setVolume(volume); + this->volume = volumeUpdate; + this->_music.setVolume(this->volume); } } diff --git a/sources/Component/Sound/SoundComponent.cpp b/sources/Component/Sound/SoundComponent.cpp index b74fcc9b..f3c18292 100644 --- a/sources/Component/Sound/SoundComponent.cpp +++ b/sources/Component/Sound/SoundComponent.cpp @@ -7,26 +7,25 @@ #include "SoundComponent.hpp" namespace BBM -{ +{ + float SoundComponent::volume = 0.75; + SoundComponent::SoundComponent(WAL::Entity &entity, \ const std::map &soundPath) : WAL::Component(entity), _soundIndex(IDLE), _soundPath(soundPath) { - this->volume = 1; for (int i = 0; i <= DEATH; i++) { - if (soundPath.at(static_cast(i)).empty()) { - this->_isLoad[static_cast(i)] = false; - } else { - this->_isLoad[static_cast(i)] = true; - this->_soundList[static_cast(i)] = std::make_unique(soundPath.at(static_cast(i))); - } + this->_isLoad[static_cast(i)] = false; + } + for (auto &soundPath : soundPath) + { + this->_isLoad[soundPath.first] = true; + this->_soundList[soundPath.first] = std::make_unique(soundPath.second); } } - float SoundComponent::volume; - WAL::Component *SoundComponent::clone(WAL::Entity &entity) const { return new SoundComponent(entity, this->_soundPath); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 1936d978..4e324535 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -67,7 +67,7 @@ namespace BBM void enableRaylib(WAL::Wal &wal) { - //RAY::TraceLog::setLevel(LOG_WARNING); + RAY::TraceLog::setLevel(LOG_WARNING); RAY::Window &window = RAY::Window::getInstance(600, 400, "Bomberman", FLAG_WINDOW_RESIZABLE); wal.addSystem() .addSystem() @@ -78,12 +78,8 @@ namespace BBM { auto scene = std::make_shared(); std::map soundPath= { - {SoundComponent::IDLE, ""}, {SoundComponent::JUMP, "assets/sounds/jump.wav"}, {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, - {SoundComponent::MOVE, "assets/sounds/jump.wav"}, - {SoundComponent::HURT, ""}, - {SoundComponent::THROW, ""}, {SoundComponent::DEATH, "assets/sounds/death.ogg"} }; scene->addEntity("player") From 16da280d152a6e4aa999b49a0960c127ad48c5ac Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 10:52:30 +0200 Subject: [PATCH 36/40] fix little beauty issues --- assets/sounds/death_wav.wav | Bin 259406 -> 0 bytes assets/sounds/new_death.ogg | Bin 9601 -> 0 bytes assets/sounds/weird.wav | Bin 6246 -> 0 bytes sources/Component/Sound/SoundComponent.cpp | 27 +++++++++++---------- sources/Component/Sound/SoundComponent.hpp | 18 +++++++------- 5 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 assets/sounds/death_wav.wav delete mode 100644 assets/sounds/new_death.ogg delete mode 100644 assets/sounds/weird.wav diff --git a/assets/sounds/death_wav.wav b/assets/sounds/death_wav.wav deleted file mode 100644 index 53f4bb258a29805df9703bc1ca502cce53f2f078..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 259406 zcmeF(cbpW}`XKzyIrsGRq)szKlpr}H2#5s92q>T=k)$9XAQ{P$gMgrtlOz$5oFqyR z5P_LaGt-kgP4{%pv(Gd4*8BF(qQ86Z?z{W$=Tr6lqpGV8CnU2LZMPY?3WFk{^zJcmPzKEJ(dVtcJqErtNCeZpM}7WL zi`I==wQSVn_17t5N6i>TfwhnW838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!g zi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O! z02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a} z838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec z0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{ zG6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)? z0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz)1jq=G5g;Q#Mu3a}838f^ zWCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6G}-$Ow=TAR|CVfQ$ec0Wtz) z1jq=G5g;Q#Mu3a}838f^WCX|vkP#pwKt_O!02u)?0%Qcp2#^sVBS1!gi~tz{G6JuT z0G09&ul|;t`~SBHRQ+@KclYZ*UGCrA&i{_|#Ie*I|0mlf&i|U@zgt)GcKCh_^N(!Xl{f4c2gt&5n4 z>m;WC)A4_DEX20{XO<<_@qc>!zv6fKU-3KqD{=Tw<4qi6^7vob-v8}sl8-le`v3Oh z`cL%?*LzT;%#BW5yu@d7~rTbrXOn-M=#P*3Xu^%;$iTM1g zeM+83tOv(5Kzt_F`>HXqJf=+^lDAoNIyv3{m(#>{U$u>z`%Qd)Roed@^N3j2jAQb) zlhgcH)5*)>G!cvcWL$GyuiD4I+n<`t|2vO^QvwAtMiC;;276S3^k{TZ4%?ZN=M9p)tFc|dEKu{mpm_dnO7}`$C;cSr(czh zNJGR0KPOKU-zSg%tM8N3CQm2tGv3z-$@4LN&Gpy(oScUEE_s}&`iJCsIGwyNHK*}= zTq=3MG|Bt+SJO4u^{UUrdSCTj^1OdFUGg%?(>3>z_>P!Qd?v=k_Fi@DL>e3?FHbC! z{5_Ede^WZZF)l;QPhOr_j+jTJBj&$qOlBRgm;bAECvO|qNi6$U>1%G6*ak75 z_>5y>eaZ7)HI3*$*6KQKs<92Eef3AiGf~_0m8pr?Xfct~-#hft;a71WV*R+EH3wq9lGlf6i2Wv}lRx7;V!7mP;ynB= zdBEieIG@-KP80KSObocM#BWI)FR=`ciFvqPA|0_0_+9dPiQk~+^2BFiT{uo&NAfhL zCH9S2ck+6PWr=m+vN(;$M4S`E`GB8^WpQ1&ZelrNJ;~>9^7lBMybQ4&Vm`5N#CCCv z-w`oN-VRO^1F;;Aalqw>WpNwC{t)SLjNcRII-c){ScX_Pt_zQ~=JkN{alrIMJZg^d zI~;IZxIUc5?L|Ns;24*|?{OcAoPgL@V!!b-u{^E=r-``XXJVg;c{pbN6Ha3q+z#>k z;b+_?4!Evl_#Ls|I86+=JjNgd{J;lr8q?yoctG$^d&I=$ff8f_EyxA6|EU(GR`tAeN_ur#+)q5t z#sK%HC+G`$gU+A{&;UGEj0FxD1LFL^->@9yfrsEaI0KIU)A_3NRWAW9Qx9|pBfuwM zK3EOD27AE|;55KvzXP6tKLL(!fTLgyz-8YBxGs!i9e{B*R2izyf^WcbFbhlplfdU- z9XJVo2PL2q;BQ8p&v-51dGtCM0u}?@r$0a(WK*-Ltw9Tr0-jNxQN93pj^pw60+B={ zaTV+ad%(}&H}DiZ2KT^Ca2;F$zXCnrSMjTQfYsnGzD`O0`T`Z0Py&yf&QQcr~{gT_rXSh+r@JqV~gkFb6^8@-~d4& zpbDrtpd?3^W2tzy_g2DB%Z!DnV5%@FBq8 z4bNBHr&9pWA3XQ)xBe2CK{skQ>i56|s5B}~2%^*|^(Gh(yc92G2Ecm;UL)3oH8Bh1 z0&CnFzX-O2rC>SO0gi*80e<%Y*g<+CJuwno0QIZtR~-a+zU>E@)J*D^;0`c=U%_(F z6yQGY26Ms3;62a{;IeoucuZe|_TWY0MfJWlOEgPlfF@u%_!Ho@j^`}?zEiuPvRGMcDQE_wFzCSp@ECYN`&j$fA&?u-jUNIH6Ai1cozYdJ ztMHzW_srqc;nWh)ht`L-2J8pl0gS~&&=X_>JJn9z4eD!2?hpl_mY;ts%T2=5PgZ)!zt zMcob_f|uX|z~7`1D5sQDeg?}ydw}=7-r!o|TJ<@$GrluU1=C{FVoY#1dN+Ck90lh= z0mzDF#XbTTLG5_$_*pO^F(Hvzm05j<$9vyca2QyCj;f>107YOpZ8+^ZhyWg)M-S7& zv@4(=xJ%lzm z5ts!o08WBa{ku;}OiJtncrK(@rB~l8-3d2brOy*ZfKkPOGq7RR41oKzm9mwhrmCs$ zgZ`imz&xrk5Cc39iU5PkfU~6)btL!%%mS+b-WR?Ccn`;UUxQ2F33v?fo_Y&B1$dt; z00B^oR*NS6K zK}k?n0W1??nW{6;f!1ImzVXu{8sPjgAc;z% zjlq1tim_t5Kzckq{xxWmXaiTSH-Y7u0)XXAEYDzh=?cJo>O<{AJqHvt1+4>U2=Kf* z0J;D?f0hC)Ltwn|Sn+qld>4Vt-$E^yIZ^hJOVF48X2HiLO!8dwSNTvgB&bS-#EdrA8kxTvn`d&oS>Jj$0< zUsfGV987S*SMjgnfmk5c1$-C%E}988L^ebU!Uf^iz_HM=&}ZNSFbb>({4hWKE0__P z5%Gc%(Gk`8;F#E$*h|np-adXB^iT9p(5vWGdja03uzYb3L;w_nsD6r{;sH!5lUf^e z1p`5EfO!JuSLeYT&=24}bS0<&SbqBr=x93HB9I5@Ft9)-!24$eEN3idl!3a;y37e+ z2lxW8z*5H2>Uiqu`s(z4nxA$6>;`!6zX}e4Gaw2&(L2#Q0-XK@VB9|f7+bs^@mXY9 z)v~I~iOUIN+*o~%@?-p1pJ<=xp2(gEUhlq;FBAv{f^sk+Fd-24$Nj$p2N)9=6Q~`m z9h8UUA!?W!{v9lgER1NQ+UP0pTI{vh4*<{q0f_+#d|sGEnMLVN?G8DFg*ucrl(rpU zxvCprfl6v6H3*#GJeUkH)_9M_=NT;L;BPY=JOEf8TmbF@HBC($17?CL;A^0yE9sBH z2F3=)TgI*@FVp{Y9*zzI*)t3>h&rt=U}<_NbE@U^=^$=Bk5pJcu@G;(6=E+&=G6`J`8*q z*yP{jrvrn};8XY&@M)8ONMK0d^Wf*f-$K8Iu)^edqOev<^0$5Hs0SW--ad@A= z``{b&H|U1|-b3-4o(0YT7ih<9$NU+LWsPNN*;@8tPzs8`H-HPeu)45jGiNhP8KsOX zzz5!DzRg??4uJjOQ{ZR#8E=6N^bPbXT2=Ku!B6!=$>Vh@mhCrGZK(Pw@l#@3d|UjT z*gLV5Xi8KQ(L_E9e-!>X^mE7+bOoD%HGwsO3;qlKuYF(p=6L6LtsbjK>XmvggVVm# zK8xSt9~K-Iw1%vqj7Uc08*mnQz_jQztZIp_kFAgOi}#CTIpJ#6)hc{G+fUt(r#BVz z(G-CB1KtZUpZ^qKp1cT*0quYi;JwrZ@OkYDSV&t)>p<^7&j&pjJsE2O#_~D9^Q=AC z4jQl;u%ZCtc!+a|Bjd`r9I&6WpCbk1+2h$~SZ7!|kjKnpnm`6CgY_Bs1zZGkfE?^( z?qouC%}4>2v`QN8#~#Wa%C@R)RbM2&NZ@@h5luv$5od%2v|(+yeyDz^U9es7gTM!Y z#s04EMvOHOyZr*O*Yrbo~0f7O5%fZXRXQ5}I4dD%8 zZA2Tn48Dkd5$zW17E{C(aV+;YuWDX}_eOlK!}84%@H?Q=sdNL)Q2m^R_oi}y`4%1E z^91HaSSKI@833P8pMe{+8?veU-!#_;c<-$U8pgWw0jIe|HWW&UOU zdA@nRHr_VgCzVesFS;+f$ATB&Y30+(G;f-BgKvYcPM}U;YjA6DZfI`k55Nwy!!v*~ zqKw=HTccZ}KgE8EHBB^4;Ik%&%Avjhcz?%drH25^f%xpy7)%D3H{kOTJ~v_o9iG#8 ztrr14jZZrU@VMGB+A&suZ^0ALl-ZQI80-c{@D=MT)_V4O_G->*&LHj}E)RwuK@_Y3 z%el+Bi#dxqL3WV+0=xtjpe3gz=R5El7z-A%7qaKE=CRf?*D}{J)-ig~d(nTV{!YdE zAw`v<3W|b>;#hI)K=eSgPoz&I914fd1A*j z{Jpp+CW@6tN+Umne+YLAbqoC-_&u<|zra7sH_La>d(ivD^Tbn8Sy8D1-QC@*nu-%zP6}rQHgn$+OPIM3Oov&3Z4pFwzw!0Q0>oZHlYm_wUG%cbX5pU30q6(d z6IAdk_;#M1rv$%nf8iE_NxVrsClK<5{Ik5XyeK!yE#wq(-ebSV9?u-l#QGZzRYS%4 zOMDhx7+o0UNB9v&m=RWnlp%k>A2{nj>)-C%?%U$s;vME0=DF#<>2Bj{gej&Xy0hh2MwJKowf>F#bWnjx6-5Z8-sj#WAtEj8! zJh%rQf^UIMXcJ0z7KvMd^hlJKa0~1W?G2p@ zp9*h`Y>a#z{W@AFUMHSYl~YB90ppcUPp_`Gn@OKZ$Md!w!1|CFz`W`#C;+YLt*h(% z8Z#O*x`I*QHRfx~$E?S!p{hXis#PfPAxd^IPd5L zhTDhRJJ>qdmRgru&w_`xhqe)p5srox4J#J87rBRfhkGmh75<^Yp}~{j4(Jl<5~?2t zk@}Gq(H7BLv0E{0+ra1fU9?@*vHF4j13eC&0(_?KNb5*r0<5ncMjr;HrEjY1>!vZL zF~%^*Fv|g!YZ^egvopIhTgVl15AY7~hVX~*r-GxPfuMolYj6`lHIHDIaF=kOXrJh$ z_@sEaWVqx6cmeK$0br?ksrU!c4;@A%a6lD!$YostGc{o^cuZf57#rwJ<6?cDO?_>$BFmME%q&TjN3R6 zum-I4K&SFf<@Pdr+1&EEE0{u*Gpaw=~sZ=_(P;Ca-}tza`45B7uE;@RSTl6{gJ(i_t4vhA{LdA58acn`dky_7|y5ox8QQsNPN#Pz|? zqMt>J!5d(|F7O(z0Ew$ zJYTxMbYHEwTG7VY#wl?~9CSO~{=)jgdaC?X`IE9IWevgP(#fS$N~V+?Ek0U&2^=mt zT=H7kYh|BVKeOI&+;Dv7{?7f-`_S9l-`hU~^aDA8oIrzMgWxv63b8_G!)L=-uY&cB zSE*O2WwbI{h#sP2ozVg?jxmmrpe1M*0JfKW#`uh(WGa~!kju_x58({q>;p}}$DjeP z0q-ZlPXfHAzZ8Edz5!xjjAV@D0{8>q^(~YNrPqKQh96UYOmQe2iqBF%OWh8xgY)2; z;+kTie4)HhQYdL5ZXsSLS|=(J776DI<_i|`7V_G0+Hr0(Z!@tjuomHiL7e~d> znW34Xh5m*9N1jKXGIyDKwrjS_;dD5&9odeBwuQEF)^XMy?bA z4?w6mRD2Me2RS7;aF$kHUtSA%^XxPpY0&-G}yHZ11~Azej%r8UQZ12-Y*!Gs?jr<{;*`tZ!Lw zaNgjganrbO0~U`}T_&0=0+Pv+jna+M4`m<9`pWyt=_&LS5x6P8DL)Hv`Z)MR@rj~U zYOB-$SfX5_JPY=NjzE?wOLfUz@=4N3(yrpJ;va-R2;UXFD+urcys6x&+^g)X>{HBB z%xro#{bOhceH4Eb&yD6rJA^ufzVLtHf5-cd_fX}bN{L(IZdTE(VyR=P^cAA6b8P{_Mo^ zf!rha)Cb=Im)GS@^{4vZ2KPaaP>&F{GoDMFOJIXgCe$ZeXcpQ_#!JRU=0!L|>oTV> zrZ5UY3>wD1V12<_4Z5r>aK?o#ejPE4DaRyVzF`ZG`rZl~Q&TavmY^%was@>bGT z(w^d;;xC0?3Ne3c$!p1L!)?R8#lFQ(VWu##4FTI|v2OXj(0id4{ucfhl`ksmxaznj zJ10ABcALG4t%>be`LXg}%6=)M0(vRE^ic7k;-QwImPJL2ib92t$U`YHH}jha zn+WlK7?Osh;uLYp0mT7DQEE}@J>@-R{j~aNVP#mk0*nXpGP-B;bKD^^$ZarSY}bIfxzvp2K%u=cQiT=sEU>(bVx z^GoKJEGu4CJk>JQ5-Exl2`xg)qoPMe3h+bW4~4H6y4Q8ESpI~3%T;a^%&EV06bm36(Q1LOzG09x%TC>l*tS`wz|^oHA}1w?4l< z|El1sV2EglXp?x8c%5XO#3VIIopPsqV(P@yb!qF;Z0WZ2RT--?)&T)%n%*>hPTHKb zC179rzVz*x+cQlnlZvC|XxHl2>Ry5?+AG=x>ILeLGC#_Es(h+!pVB@hO`0aXF1jun zBpf6hCKx8*!vM{{oW`uiEUW|jGVx_X6;Va7KDfE3xd-cu{&4)^m|>e?gYFV#r%O(k zlvqkETZ^_9Z7$qgc&Fe_K{vn$H_bQALZCP5je87x3=w@q-^S3!@Rso{BiGC|A1ORi zm|2opa-;l4`3w6CyRt%Aam{tj#jE61{tobgWDcv&6H+FC{M}i)4#r4N@AUoKT!l3{ehIE=gaKUX)ps`J?Jb)l~IV^(?R! z_&^Iy3yls80)w@KwO4glbqBK#X3qyxbW?P0ja$Q3v(2P^F>?X9e>tS?Gml^ z2hcwF9{s)QM#>B93v8^r?auAa?Z@lKd(MB(e^2AJ2H1<-c;RGP1j7Y=*B#Ss(`^UK50<}Q_I_FK(%z+YOX`+jJcbkvDY{;8y7H3qJptM}#k^3wCu^M~t)>wh==Zpby|npzdKD%fh-YI(Qp-7=+3 zX`61JZg1;o>-fa^iBsuPx@Nd%xHndAtlaM1?&SyhL3hL*>6Pe}r~`ew#K9YST^Q3rET&b>9?40r-?Lk_%jBXiYv&LpM zR5w&BGz!g5Fi<;CTUS?CcLJOR3&BKy_r;@N328jR zRjw+JmBdQ!7vC=)2QFAHSTJ99m>uT!ruL>!jh`BA2AkoW{+zxvuQcz@%R4XY<<-k; zncp)1PtZ@_PyfL1z;MNU#XQn7(lV}eTxp;3KIQm~bk}~@e${!^$#St=QE;I0K;<~! zIN#0S&0w8qohY`=&!*0%V*4vz&kMKaG-<7&6b%K0?yp5!dL@tyI|KR??UB+6* z8V~(PFrVHN-xJ>!*%lcS920EiYvt=!*{yPG#nuXuL*&?M-D<60R=*4$i;Fv2I$9!y zk-|p>j|xVbN1Cr1uNo&ACKk#Pm%3Ywdmn|d31 zS6{zP@|)x@$y<`g1&)`FmtFI^=4It)HTijLJReDx-R`y298!1OqkEV7?@01?M2xQ>>>^;?cs&6#k zXi~FNv-jrg&542R-0a+2piiwnwW@Nfa#KLxoW41c>`3+x;JWU*E?b+e?Wpdk?vm9d z>vsC>^tq{XQ_soH$)GqdF5(yQrCceuCkxPf(sdLaMHCmsv0qU^pdj$J_igW8*IieA zXMN{l`(isZVb}s?fwJi((@S2ryly#Jc(U-Tg0BklOnIg)hAoDC7(M`>03K+U*DkN@ zW!cLUc_;E(=v(M9%>m;9<6!e(bAzG=MT1HPm7FL$QP#-X$hyO}!#3A3*RiK!Pj%h9 z&ZF~;^o{i04c-l6-$(2tbqD(O>KHl(mT}f{)^f1CTbEy#KS?l2Fi28HvQA<`!HdQoLq~&Y*gE)gYkC=~` z_38EL%_+?(!B{Z1KD<7R{a&!WtF)rDg6rTqu3N8LFPB{|J6UqFIE#(0|hoBOfNVqJ7yG&7NzI72x@ z!FHTOtV1jbSHiu(yTI!s=p(@TukDiUl3ZD?teL!-e0j?9l#!_;QwO9CNP}jz?1V0%gVQei9e@XLU3*-?(iB#;dKew(N2Fa1?h55-M;UeKy@mBFN=`!hg*?HM! z`DXd^l;VYAvzUEp zeQ9vZPhh*0Ib;q&wNJp{F?iOw*15iOeCOz9>t<_F-l9BS5-&MxIcq5{EG|4-aJKpx zHWyX(Y^O@?I>Zs1@Z-Qx`Zylb{qy5uo$eS^rrOo&^J3Lo)d2rX%tx;TpWaMMgCcyS)QL< zKe_HY?mDnRen;7kvQZ_YO8Qv(SauffESyp>rC^15g?XuIsi~u}qtU1L=`rtp7aYht zkmr2qe0c$2{!&X{OW(rS!Z_bN-wf3tMFqtL#hc1Dl^wGlvnuUMdlyF+$93m*=kKoH zUGI3_@nrZj{8&G?Ke|84tYTK_pg*9UVP{NXPhlVA9^|g$uj4~FgiA$BMRu`W{HgR) zsbA)oO-`AdVpUib^Of_Jt+30@0#YA=4fecX&q5IqBOfWyLdp+ zfTHgUzAs2Mr<$?CwE_6V@QLAb{pb2V`F--=$$Ka7-phM0Zvj=F3QCBjd4u$W^rMZV zjaSWA&DtVu(d^>c#ebImS((B3V=Q|t`!M$~_aXlwAKRSX7QZbXFBvbvvhG&dRvFf#j#P|PI8&Xe zchl~su`*ei3sehK&os|8`21EYr&dlBbjj_Kn*;K5@^iiei@|u14mM?P%J%BKy4v7( z&F`91s#7X^hCKu89d@PcO6e}`F1;hXBkaNJ!NdM<*s~hsqC?_bKgD8n%QjcM9(m7MY98{Z0K%G$XD0yz8Xzq%Y1d&fg8% zf=79e@(zN0@Lv9V`5p8f^w$m74GB}ibhYqm;kx2=#p*J3**xn!>mB zTG?9Jtdvk}HN8>qk5ey!b{y*V4NRb#F(cSNlbwKjp(;9Y>_m>J+e z&Vigm*@v=s>2~RsYnN-=YuanptJbS#WzNc!q)XB#q)tekDxWIPkYq?U2{s9^9CLzs zf{A@Nd&4^wJz_m#W5Z*^djfj`_@d(Y%JG#qD{fX`gL!vrck7nYEv2$zS@HA2=Y{3w za`SN0a8oy9H{(}^uMBwY_5nNccjSBWJbCj$e=rqStNcvZiKC z&FH4=raUD-C5Ng^Nf$vE0rn4aGMo(T`B9OmNYszjk97-o3%?O~Bhb{_)GKfc+~*wU z980WAtc9h8rEq!`r&-c09~XXHSYR$NpD>*;-7wxT-ZtDeY}aqsZ_D47&jrWwj^*_O z7{BcN?0kIA+il!!Twq>co?SS*5Idcg!qCv#&^pyN)wapL$-dsX-r3pR+5OD(%v0g3 z@If_J@L~927~glncOv)0yF}PO6rbtF^2YM!3g!x)3ZDvjVxAbwFkNL`WozVX1tXu!kgA`ipEz<%iX zPA9hac|xAhZ2xTkbkB6pY1e7jbH{TB-^RE7UiN!gZfS1m^5W&ihl&mrJuP@zu-LrV ze9Cmnbjx_l__5(*Lp^;x{iFOx`Iz5!2iAOR{x<-chV^e6-ZWe@UNg2gw>S4K>{~d$ zcz!W<_?cpxVtZZ;+Nw7lKzry;HdPdbi91L+?HZXk)%pe4=N8T85xX>)mf{vcBpr# z8)_SBx9PU&@HqpoV@<9mcUjJ|>bzq|_Kxhn;Fj)|P7O9`H))k%v}Uv>Rh_C%%Sy|_ zdT(q;!29b($wf(TVQ=9j?j>#~Rwou#sIw?6iaailGoh~?C&&p-^-cBF^VIX4aGh{r z8~$zUZR?P-A!UG_S%0$nar<%gd_A8h;)xcD7m9~ThDqv4>q+~``pNdo_sdxdmf~{ig3kRh2lnao^c}kL^izEnvL~ZY_LJQL2K5S zHCUhUMD;|qIBRj%PZ>XDU>m~wiuV;`Wn*Q%#J$8=x2E7IIFlHY82GMFUwAidW^`tB zZD?%>ipBns-jUv&?w#%_&MD5pw!zis;GL2?B@ZkQELi`1*?if&-n8C?o%P_>V>IXu zdUw7%e;4=&6y_D?jRxmHLw!TN$S5-IHSIO^D(F@4r07YJqr_3NrhH9#FIz9$Bl{zJ zfwRE5(!J81@FYCti>zX+ z7@EMV+wD5aJIcGKbWiE1=%|>HIwMt_CQkFG`>U^Eqspk-quHZrqHCg?kv$_D>tC?k zEC>Cv`(^LZ?a|c&=e6gxjlp8gVojbpPu&#^Qw>w?&)lEcExlX%$<&jn74nMe_Ncdn zZwY_o{>UA|8dCi%{2ufnpAerA|3314gd5_9uzhWgXO3sSYrbojW0#}YT5KItHm0m? zN!yYcmKhdLp{Hkwt}*ttURSWg_Fujh30%E<|TD9>ts$-O;bVFL`@%U zAMKyIKXv_c`savq#kr4j9_QGz?b+qJa;R

      )L4BXtBJwTfJM|5+qa!)jBXGYf9F{ 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 VU~0oJ8HOJmApSM|fb*~Ee*pk@LG1tl diff --git a/assets/sounds/weird.wav b/assets/sounds/weird.wav deleted file mode 100644 index 101029c5bf0abad9fc68bbaea63b55abbb97d982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6246 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 &soundPath) + SoundComponent::SoundComponent(WAL::Entity &entity, + const std::map &soundPath) : WAL::Component(entity), _soundIndex(IDLE), _soundPath(soundPath) { for (int i = 0; i <= DEATH; i++) { - this->_isLoad[static_cast(i)] = false; + this->_isSoundLoad[static_cast(i)] = false; } for (auto &soundPath : soundPath) { - this->_isLoad[soundPath.first] = true; + this->_isSoundLoad[soundPath.first] = true; this->_soundList[soundPath.first] = std::make_unique(soundPath.second); } } @@ -33,7 +33,7 @@ const std::map &soundPath) void SoundComponent::playSound() { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return; if (!this->_soundList[this->_soundIndex].get()->isPlaying()) this->_soundList[this->_soundIndex].get()->play(); @@ -41,7 +41,7 @@ const std::map &soundPath) void SoundComponent::stopSound() { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return; if (this->_soundList[this->_soundIndex].get()->isPlaying()) this->_soundList[this->_soundIndex].get()->stop(); @@ -49,40 +49,41 @@ const std::map &soundPath) void SoundComponent::pauseSound() { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return; this->_soundList[this->_soundIndex].get()->pause(); } void SoundComponent::setVolume(float &volumeUpdate) { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return; - if (volumeUpdate >= 0) + if (volumeUpdate >= 0) { this->volume = volumeUpdate; this->_soundList[this->_soundIndex].get()->setVolume(this->volume); + } } void SoundComponent::setPitch(float &pitch) { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return; this->_soundList[this->_soundIndex].get()->setPitch(pitch); } bool SoundComponent::isPlaying() { - if (!this->_isLoad.at(this->_soundIndex)) + if (!this->_isSoundLoad.at(this->_soundIndex)) return (false); return (this->_soundList[this->_soundIndex].get()->isPlaying()); } - void SoundComponent::setIndex(soundIndex index) + void SoundComponent::setIndex(SoundIndex index) { this->_soundIndex = index; } - SoundComponent::soundIndex SoundComponent::getIndex() + SoundComponent::SoundIndex SoundComponent::getIndex() { return (this->_soundIndex); } diff --git a/sources/Component/Sound/SoundComponent.hpp b/sources/Component/Sound/SoundComponent.hpp index 8b4a4fef..f5278114 100644 --- a/sources/Component/Sound/SoundComponent.hpp +++ b/sources/Component/Sound/SoundComponent.hpp @@ -16,21 +16,21 @@ namespace BBM public: //! @brief All sounds of the player - enum soundIndex { + enum SoundIndex { IDLE, JUMP, BOMB, MOVE, HURT, THROW, - DEATH, + DEATH }; //! @brief to set what sound should be played - void setIndex(soundIndex index); + void setIndex(SoundIndex index); //! @brief to know which sound is selected - soundIndex getIndex(); + SoundIndex getIndex(); //! @brief start sound void playSound(); @@ -53,7 +53,7 @@ namespace BBM //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief Create a new SoundComponent at a certain Sound - explicit SoundComponent(WAL::Entity &entity, const std::map &); + explicit SoundComponent(WAL::Entity &entity, const std::map &); //! @brief A Sound component is copy constructable SoundComponent(const SoundComponent &) = default; //! @brief A default destructor @@ -65,13 +65,13 @@ namespace BBM private: //! @brief Sounds of this entity - std::map> _soundList; + std::map> _soundList; //! @brief map to know if sound is loaded - std::map _isLoad; + std::map _isSoundLoad; //! @brief All sounds path - const std::map _soundPath; + const std::map _soundPath; //! SoundIndex - soundIndex _soundIndex; + SoundIndex _soundIndex; }; From 544def1dbdbe4351d4077c6cff51ff854ebc86fb Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 10:55:08 +0200 Subject: [PATCH 37/40] fix system name --- sources/Component/Music/MusicComponent.hpp | 2 +- sources/System/Music/MusicSystem.hpp | 2 +- sources/System/Sound/PlayerSoundManagerSystem.cpp | 6 +++--- sources/System/Sound/PlayerSoundManagerSystem.hpp | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sources/Component/Music/MusicComponent.hpp b/sources/Component/Music/MusicComponent.hpp index 2d291e47..7898fd6e 100644 --- a/sources/Component/Music/MusicComponent.hpp +++ b/sources/Component/Music/MusicComponent.hpp @@ -31,7 +31,7 @@ namespace BBM //! @brief is music playing bool isPlaying(void); - + //! @brief update music stream void updateMusicStream(void); //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/System/Music/MusicSystem.hpp b/sources/System/Music/MusicSystem.hpp index ce65321c..d524d300 100644 --- a/sources/System/Music/MusicSystem.hpp +++ b/sources/System/Music/MusicSystem.hpp @@ -25,7 +25,7 @@ namespace BBM MusicSystem(const MusicSystem &) = default; //! @brief Default dtor ~MusicSystem() override = default; - //! @brief A SoundManager screen system can't be assigned. + //! @brief A MusicManager screen system can't be assigned. MusicSystem &operator=(const MusicSystem &) = delete; }; } diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp index 487a4081..2bd4b6ab 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.cpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -7,18 +7,18 @@ namespace BBM { - SoundManagerSystem::SoundManagerSystem(WAL::Wal &wal) + PlayerSoundManagerSystem::PlayerSoundManagerSystem(WAL::Wal &wal) : System(wal) {} - void SoundManagerSystem::onFixedUpdate(WAL::ViewEntity &entity) + void PlayerSoundManagerSystem::onFixedUpdate(WAL::ViewEntity &entity) { const auto &controllable = entity.get(); auto &sound = entity.get(); auto &health = entity.get(); sound.setVolume(sound.volume); - std::map soundIndex = { + std::map soundIndex = { {controllable.bomb, SoundComponent::BOMB}, {controllable.jump, SoundComponent::JUMP}, {controllable.move.x != 0 || controllable.move.y != 0, SoundComponent::MOVE} diff --git a/sources/System/Sound/PlayerSoundManagerSystem.hpp b/sources/System/Sound/PlayerSoundManagerSystem.hpp index 42869888..6e49763b 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.hpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.hpp @@ -13,19 +13,19 @@ namespace BBM { - class SoundManagerSystem : public WAL::System + class PlayerSoundManagerSystem : public WAL::System { public: //! @inherit void onFixedUpdate(WAL::ViewEntity &entity) override; //! @brief ctor - SoundManagerSystem(WAL::Wal &wal); + PlayerSoundManagerSystem(WAL::Wal &wal); //! @brief Default copy ctor - SoundManagerSystem(const SoundManagerSystem &) = default; + PlayerSoundManagerSystem(const PlayerSoundManagerSystem &) = default; //! @brief Default dtor - ~SoundManagerSystem() override = default; + ~PlayerSoundManagerSystem() override = default; //! @brief A SoundManager screen system can't be assigned. - SoundManagerSystem &operator=(const SoundManagerSystem &) = delete; + PlayerSoundManagerSystem &operator=(const PlayerSoundManagerSystem &) = delete; }; } From 5df29e87c63a399091904d52585dc3fb1d61e6fe Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 11:01:19 +0200 Subject: [PATCH 38/40] fix wrong system name in runner --- sources/Runner/Runner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 4e324535..7f45eab2 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -61,7 +61,7 @@ namespace BBM .addSystem() .addSystem() .addSystem() - .addSystem() + .addSystem() .addSystem(); } @@ -77,7 +77,7 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); - std::map soundPath= { + std::map soundPath= { {SoundComponent::JUMP, "assets/sounds/jump.wav"}, {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, {SoundComponent::DEATH, "assets/sounds/death.ogg"} From 14328a68a028b28d3db2dd7032b6a23ca27e0818 Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 11:21:13 +0200 Subject: [PATCH 39/40] add move sound --- assets/sounds/move.ogg | Bin 0 -> 16997 bytes sources/Runner/Runner.cpp | 1 + .../System/Sound/PlayerSoundManagerSystem.cpp | 1 + 3 files changed, 2 insertions(+) create mode 100644 assets/sounds/move.ogg diff --git a/assets/sounds/move.ogg b/assets/sounds/move.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fc0355090ab23569cbdf438d4b2855ad84b94c71 GIT binary patch literal 16997 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 literal 0 HcmV?d00001 diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 7f45eab2..bd02ec03 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -79,6 +79,7 @@ namespace BBM auto scene = std::make_shared(); std::map soundPath= { {SoundComponent::JUMP, "assets/sounds/jump.wav"}, + {SoundComponent::MOVE, "assets/sounds/move.ogg"}, {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, {SoundComponent::DEATH, "assets/sounds/death.ogg"} }; diff --git a/sources/System/Sound/PlayerSoundManagerSystem.cpp b/sources/System/Sound/PlayerSoundManagerSystem.cpp index 2bd4b6ab..dac45304 100644 --- a/sources/System/Sound/PlayerSoundManagerSystem.cpp +++ b/sources/System/Sound/PlayerSoundManagerSystem.cpp @@ -19,6 +19,7 @@ namespace BBM { sound.setVolume(sound.volume); std::map soundIndex = { + {health.getHealthPoint() <= 0, SoundComponent::DEATH}, {controllable.bomb, SoundComponent::BOMB}, {controllable.jump, SoundComponent::JUMP}, {controllable.move.x != 0 || controllable.move.y != 0, SoundComponent::MOVE} From 77cf1a93e123083a80b9eda203113ba25ebdba97 Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 12:05:18 +0200 Subject: [PATCH 40/40] fix indent on runner --- sources/Runner/Runner.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index bd02ec03..9f9e48d8 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -77,12 +77,12 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); - std::map soundPath= { - {SoundComponent::JUMP, "assets/sounds/jump.wav"}, - {SoundComponent::MOVE, "assets/sounds/move.ogg"}, - {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, - {SoundComponent::DEATH, "assets/sounds/death.ogg"} - }; + std::map soundPath ={ + {SoundComponent::JUMP, "assets/sounds/jump.wav"}, + {SoundComponent::MOVE, "assets/sounds/move.ogg"}, + {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, + {SoundComponent::DEATH, "assets/sounds/death.ogg"} + }; scene->addEntity("player") .addComponent() .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png"))