mirror of
https://github.com/Nimac0/SDL_Minigame
synced 2026-01-12 12:33:43 +00:00
Merge e215fbd5b67f44957d85be11ec5f9ac9a0ff0f36 into 361687f09f5218d2e7f8cf1dbc2e7b81d0e722b4
This commit is contained in:
commit
d7329953c2
@ -6,6 +6,7 @@
|
||||
#include <functional>
|
||||
|
||||
#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<void (Entity*)> 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<std::string, Mix_Chunk*> soundEffects;
|
||||
std::map<std::string, Mix_Music*> music;
|
||||
};
|
||||
|
||||
3
include/BackgroundMusic.h
Normal file
3
include/BackgroundMusic.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
enum class BackgroundMusic;
|
||||
@ -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;
|
||||
};
|
||||
3
include/SoundEffects.h
Normal file
3
include/SoundEffects.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
enum class SoundEffects;
|
||||
@ -6,6 +6,8 @@
|
||||
|
||||
#include "ECS.h"
|
||||
#include "TextureManager.h"
|
||||
#include "BackgroundMusic.h"
|
||||
#include "SoundEffects.h"
|
||||
|
||||
class GameInternal;
|
||||
|
||||
@ -17,8 +19,17 @@ class GameInternal;
|
||||
*/
|
||||
class SoundManager
|
||||
{
|
||||
|
||||
public:
|
||||
SoundManager() {}
|
||||
|
||||
SoundManager() {
|
||||
if (this_instance == nullptr) {
|
||||
this_instance = this;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("SoundManager instance already exists!");
|
||||
}
|
||||
}
|
||||
~SoundManager() {
|
||||
for (auto& it : this->sound_cache) {
|
||||
Mix_FreeChunk(it.second);
|
||||
@ -32,35 +43,32 @@ class SoundManager
|
||||
SoundManager(SoundManager const&) = delete;
|
||||
void operator=(SoundManager const&) = delete;
|
||||
|
||||
std::map<const char*, Mix_Music*> music_cache;
|
||||
std::map<const char*, Mix_Chunk*> 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 +81,19 @@ 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<SoundEffects, const char*> &effects);
|
||||
static void addSingleBackgroundMusic(BackgroundMusic backgroundMusic, const char* path);
|
||||
static void addBackgroundMusic(const std::map<BackgroundMusic, const char*> &backgroundMusic);
|
||||
|
||||
static SoundManager* getInstance() {
|
||||
return this_instance;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::map<BackgroundMusic, Mix_Music*> music_cache;
|
||||
std::map<SoundEffects, Mix_Chunk*> sound_cache;
|
||||
static SoundManager* this_instance;
|
||||
};
|
||||
@ -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<TransformComponent>(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects
|
||||
projectile.addComponent<SpriteComponent>(textureEnum, 4);
|
||||
projectile.addComponent<ProjectileComponent>(range, speed, velocity, owner);
|
||||
projectile.addComponent<ProjectileComponent>(range, speed, velocity, owner, soundEffect);
|
||||
projectile.addComponent<ColliderComponent>("projectile", 0.6f);
|
||||
projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE);
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ void ProjectileComponent::init()
|
||||
{
|
||||
transformComponent = &entity->getComponent<TransformComponent>();
|
||||
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)
|
||||
|
||||
@ -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,51 @@ 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<SoundEffects, const char *> &effects) {
|
||||
for (auto effect : effects)
|
||||
addSingleSoundEffect(effect.first, effect.second);
|
||||
}
|
||||
|
||||
void SoundManager::addBackgroundMusic(const std::map<BackgroundMusic, const char *> &backgroundMusic) {
|
||||
for (auto track : backgroundMusic)
|
||||
addSingleBackgroundMusic(track.first, track.second);
|
||||
}
|
||||
|
||||
SoundManager* SoundManager::this_instance = nullptr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user