From 9bb9d0fbcc4221750eae3115ae4b8ac9be6e1c97 Mon Sep 17 00:00:00 2001 From: freezarite Date: Tue, 28 Jan 2025 19:08:05 +0100 Subject: [PATCH] removed maps regarding music and sound effects from the AssetManager reworked SoundManager to use enum classes as keys in its maps and to no longer use the AssetManager added possibility to set sound effect of projectiles when creating them (was hard coded) --- include/AssetManager.h | 13 +----- include/BackgroundMusic.h | 3 ++ include/ProjectileComponent.h | 7 ++- include/SoundEffects.h | 3 ++ include/SoundManager.h | 33 ++++++++++----- src/AssetManager.cpp | 23 +--------- src/ProjectileComponent.cpp | 2 +- src/SoundManager.cpp | 80 +++++++++++++++++++++++++++++------ 8 files changed, 106 insertions(+), 58 deletions(-) create mode 100644 include/BackgroundMusic.h create mode 100644 include/SoundEffects.h diff --git a/include/AssetManager.h b/include/AssetManager.h index a5f635f..eb4d104 100644 --- a/include/AssetManager.h +++ b/include/AssetManager.h @@ -6,6 +6,7 @@ #include #include "Entity.h" +#include "SoundEffects.h" class Vector2D; class Manager; @@ -24,24 +25,14 @@ public: AssetManager(Manager* manager); ~AssetManager(); - void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner); + void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner, SoundEffects soundEffect); void createPowerup(Vector2D pos, std::function pickupFunc, Textures texture); Vector2D calculateSpawnPosition(); PowerupType calculateType(); - // sound management - void addSoundEffect(std::string id, const char* path); - - void addMusic(std::string id, const char* path); - - Mix_Chunk* getSound(std::string id); - Mix_Music* getMusic(std::string id); - private: Manager* man; - std::map soundEffects; - std::map music; }; diff --git a/include/BackgroundMusic.h b/include/BackgroundMusic.h new file mode 100644 index 0000000..48516a4 --- /dev/null +++ b/include/BackgroundMusic.h @@ -0,0 +1,3 @@ +#pragma once + +enum class BackgroundMusic; diff --git a/include/ProjectileComponent.h b/include/ProjectileComponent.h index da67ff6..d9f5071 100644 --- a/include/ProjectileComponent.h +++ b/include/ProjectileComponent.h @@ -3,6 +3,7 @@ #include "Component.h" #include "Vector2D.h" #include "Constants.h" +#include "SoundEffects.h" class TransformComponent; @@ -11,8 +12,8 @@ class ProjectileComponent : public Component //can maybe be split in separate .cpp file public: - ProjectileComponent(int range, int speed, Vector2D direction, Entity* owner) - : range(range), speed(speed), direction(direction), owner(owner) {} + ProjectileComponent(int range, int speed, Vector2D direction, Entity* owner, SoundEffects soundEffect) + : range(range), speed(speed), direction(direction), owner(owner), soundEffect(soundEffect) {} ~ProjectileComponent() {} void init() override; @@ -28,4 +29,6 @@ private: Entity* owner = nullptr; Vector2D direction; + + SoundEffects soundEffect; }; \ No newline at end of file diff --git a/include/SoundEffects.h b/include/SoundEffects.h new file mode 100644 index 0000000..609b9a5 --- /dev/null +++ b/include/SoundEffects.h @@ -0,0 +1,3 @@ +#pragma once + +enum class SoundEffects; diff --git a/include/SoundManager.h b/include/SoundManager.h index 38a6b2c..a4b0594 100644 --- a/include/SoundManager.h +++ b/include/SoundManager.h @@ -6,6 +6,8 @@ #include "ECS.h" #include "TextureManager.h" +#include "BackgroundMusic.h" +#include "SoundEffects.h" class GameInternal; @@ -17,8 +19,12 @@ class GameInternal; */ class SoundManager { + public: - SoundManager() {} + + SoundManager() { + this_instance = this; + } ~SoundManager() { for (auto& it : this->sound_cache) { Mix_FreeChunk(it.second); @@ -32,35 +38,32 @@ class SoundManager SoundManager(SoundManager const&) = delete; void operator=(SoundManager const&) = delete; - std::map music_cache; - std::map sound_cache; - - /*! + /* * \brief Loads music from a file (mp3) * \returns a pointer to Mix_Music * \sa AssetManager::AddMusic(std::string id, const char* path) - */ + Mix_Music* loadMusic(const char* fileName); /*! * \brief Loads sound effects from a file (wav) * \returns a pointer to Mix_Chunk * \sa AssetManager::AddSound(std::string id, const char* path) - */ - Mix_Chunk* loadSound(const char* fileName); + Mix_Chunk* loadSound(const char* fileName); + */ /*! * \brief Handles playing of sound effects * * Handles if sounds can overlap, how often they can loop, as well as the volume at which the specified sound effect should play * and on which channel the soundeffect should play. */ - static void playSound(GameInternal* game, std::string sound, bool canOverlap, int loops, int volume, int channel); + static void playSound(SoundEffects sound, bool canOverlap, int loops, int volume, int channel); /*! * \brief Handles playing of music * * Handles how often track can loop, as well as the volume at which the specified track should play and if it fades in. */ - static void playMusic(GameInternal* game, std::string sound, int loops, int volume, int ms); + static void playMusic(BackgroundMusic sound, int loops, int volume, int ms); static void setSoundVolume(int volume, int channel); //!< Volume handling for sound effects (either all or on a specific channel) static void setMusicVolume(int volume); //!< Volume handling for music track @@ -73,5 +76,15 @@ class SoundManager static void fadeOutMusic(int ms); //!< Handles fading out a music track + static void addSingleSoundEffect(SoundEffects soundEffect, const char* path); + static void addSoundEffects(const std::map &effects); + static void addSingleBackgroundMusic(BackgroundMusic backgroundMusic, const char* path); + static void addBackgroundMusic(const std::map &backgroundMusic); + + private: + + std::map music_cache; + std::map sound_cache; + static SoundManager* this_instance; }; \ No newline at end of file diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 75e78ec..a7789fc 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -22,32 +22,13 @@ AssetManager::AssetManager(Manager* manager) : man(manager) {} AssetManager::~AssetManager() {} -void AssetManager::addSoundEffect(std::string id, const char* path) -{ - soundEffects.emplace(id, this->man->getGame()->soundManager->loadSound(path)); -} -void AssetManager::addMusic(std::string id, const char* path) -{ - music.emplace(id, this->man->getGame()->soundManager->loadMusic(path)); -} - - -Mix_Chunk* AssetManager::getSound(std::string id) { - return soundEffects.at(id); -} - -Mix_Music* AssetManager::getMusic(std::string id) -{ - return music.at(id); -} - -void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner) { +void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner, SoundEffects soundEffect) { auto& projectile(man->addEntity()); projectile.addComponent(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects projectile.addComponent(textureEnum, 4); - projectile.addComponent(range, speed, velocity, owner); + projectile.addComponent(range, speed, velocity, owner, soundEffect); projectile.addComponent("projectile", 0.6f); projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE); } diff --git a/src/ProjectileComponent.cpp b/src/ProjectileComponent.cpp index e1df015..3f5f13c 100644 --- a/src/ProjectileComponent.cpp +++ b/src/ProjectileComponent.cpp @@ -14,7 +14,7 @@ void ProjectileComponent::init() { transformComponent = &entity->getComponent(); transformComponent->direction = direction; - SoundManager::playSound(this->entity->getManager().getGame(), "throw_egg", true, PLAY_ONCE, MAX_VOLUME, -1); + SoundManager::playSound(this->soundEffect, true, PLAY_ONCE, MAX_VOLUME, -1); } void ProjectileComponent::update(uint_fast16_t diffTime) diff --git a/src/SoundManager.cpp b/src/SoundManager.cpp index 6775725..15475f4 100644 --- a/src/SoundManager.cpp +++ b/src/SoundManager.cpp @@ -8,9 +8,10 @@ #include "GameInternal.h" #include "AssetManager.h" +/* Mix_Music* SoundManager::loadMusic(const char* fileName) { - auto it = this->music_cache.find(fileName); + //auto it = this->music_cache.find(fileName); if (it != this->music_cache.end()) { return it->second; @@ -48,14 +49,21 @@ Mix_Chunk* SoundManager::loadSound(const char* fileName) return sound; } -void SoundManager::playSound(GameInternal* game, std::string sound, bool canOverlap, int loops, int volume, int channel) +*/ + +void SoundManager::playSound(SoundEffects sound, bool canOverlap, int loops, int volume, int channel) { + if (!this_instance->sound_cache.contains(sound)) { + std::cerr << "Error playing Sound-Effect: sound effect not found" << std::endl; + return; + } + if(!canOverlap) { // dev needs to specify a channel for this check to work, if they set it to -1 and let sdl pick the first available // channel mix_getchunk() won't work if (Mix_Playing(channel) != 0 && - Mix_GetChunk(channel) == game->assets->getSound(sound) && + Mix_GetChunk(channel) == this_instance->sound_cache.at(sound) && channel != -1) { return; @@ -64,25 +72,30 @@ void SoundManager::playSound(GameInternal* game, std::string sound, bool canOver Mix_HaltChannel(channel); } - if(Mix_VolumeChunk(game->assets->getSound(sound), volume) == -1) + if(Mix_VolumeChunk(this_instance->sound_cache.at(sound), volume) == -1) { std::cerr << "Error adjusting volume: " << SDL_GetError() << std::endl; } - if (Mix_PlayChannel(channel, game->assets->getSound(sound), loops) == -1) + if (Mix_PlayChannel(channel, this_instance->sound_cache.at(sound), loops) == -1) { - std::cerr << "Error playing sound '" << sound << "': " << SDL_GetError() << std::endl; + std::cerr << "Error playing sound " << ": " << SDL_GetError() << std::endl; } } -void SoundManager::playMusic(GameInternal* game, std::string music, int loops, int volume, int ms) +void SoundManager::playMusic(BackgroundMusic music, int loops, int volume, int ms) { + if (!this_instance->music_cache.contains(music)) { + std::cerr << "Error playing music: music not found" << std::endl; + return; + } + if (Mix_PlayingMusic() != 0 || Mix_Fading() == Mix_Fading::MIX_FADING_IN) return; if(ms > 0) { - Mix_FadeInMusic(game->assets->getMusic(music), loops, ms); + Mix_FadeInMusic(this_instance->music_cache.at(music), loops, ms); return; } @@ -90,11 +103,6 @@ void SoundManager::playMusic(GameInternal* game, std::string music, int loops, i { std::cerr << "Error adjusting volume: " << SDL_GetError() << std::endl; } - - if (Mix_PlayMusic(game->assets->getMusic(music), loops) == -1) - { - std::cerr << "Error playing music '" << music << "': " << SDL_GetError() << std::endl; - } } void SoundManager::setSoundVolume(int volume, int channel) @@ -134,3 +142,49 @@ void SoundManager::fadeOutMusic(int ms) Mix_FadeOutMusic(ms); } + +void SoundManager::addSingleSoundEffect(SoundEffects soundEffect, const char *path) { + if (this_instance->sound_cache.contains(soundEffect)) { + std::cerr << "Error when adding Sound-Effect: sound-effect with that key already in cache" << std::endl; + return; + } + + Mix_Chunk* sound = Mix_LoadWAV(path); + + if (sound == nullptr) { + std::cerr << "Error when loading Sound-Effect: could not load sound effect from " << path << std::endl; + return; + } + + this_instance->sound_cache.emplace(soundEffect, sound); +} + +void SoundManager::addSingleBackgroundMusic(BackgroundMusic backgroundMusic, const char *path) { + if (this_instance->music_cache.contains(backgroundMusic)) { + std::cerr << "Error when adding Sound-Effect: sound-effect with that key already in cache" << std::endl; + return; + } + + Mix_Music* music = Mix_LoadMUS(path); + + if (music == nullptr) { + std::cerr << "Error when loading Sound-Effect: could not load sound effect from " << path << std::endl; + return; + } + + this_instance->music_cache.emplace(backgroundMusic, music); +} + +void SoundManager::addSoundEffects(const std::map &effects) { + for (auto effect : effects) + addSingleSoundEffect(effect.first, effect.second); +} + +void SoundManager::addBackgroundMusic(const std::map &backgroundMusic) { + for (auto track : backgroundMusic) + addSingleBackgroundMusic(track.first, track.second); +} + + + +