如何制作 sf::sound 的矢量

How to make a vector of sf::sound

我使用 SFML 库,更具体地说是 SFML 的音频部分。我想存储多个 sf::Sound,所以我想到制作一个 class 来处理声音并制作一个 sf::Sound 的向量。 但是,当我尝试播放声音时,只能播放矢量列表的最后一个元素,其余的不会播放。 我真的不明白为什么。

audio.hpp

#ifndef AUDIO_HPP
#define AUDIO_HPP
#pragma once

#include <SFML/Audio.hpp>
#include <vector>
#include <string>

enum {SELECTION_SOUND, DEAD_SOUND};
enum {MAIN_THEME_MUSIC, GAME_MUSIC, GAME_OVER_MUSIC};

class Audio
{
public:
    Audio();
    void setVolumeMusic(const float v);
    void setVolumeSound(const float v);
    float getVolumeSound() const;
    float getVolumeMusic() const;
    void playSound(const unsigned int soundExecute);
    void stopMusic();
    void deleteMusicTheme();
    ~Audio();
private:
    bool m_musicThemeUse;
    float m_volumeMusic, m_volumeSound;
    std::vector <sf::SoundBuffer> m_buffer;
    std::vector <bool> accessMusic, accessSound;
    std::vector <sf::Sound> m_sound;
    std::vector <sf::Music*> m_music;
    std::vector <std::string> m_nameFileMusic, m_nameFileSound;

    /*
    * m_musicThemeUse : If this variable is equal to "true" then, the main menu music is deleted from memory.
    * m_volumeMusic, m_volumeSound : Music/sound volume, it is fixed between 0.f and 100.f.
    * m_buffer: vector containing the audio files of the sounds.
    * accessMusic, accessSound : bool vector determining whether a music is available for playback or not. Useful when a file is deleted.
    * m_sound: vector containing the audio files of the sounds.
    * m_music: vector containing the audio files of the musics.
    * m_nameFileMusic, m_nameFileSound : vector of string containing the path of the audio files.
    */
};

#endif

Audio的构造函数class.

Audio::Audio() : m_nameFileMusic{ "data/mainTheme.ogg", "data/game.ogg", "data/gameOver.ogg" }, m_nameFileSound{"data/selectionSound.ogg", "data/dead.ogg" },
m_musicThemeUse(true), m_volumeMusic(0.f), m_volumeSound(100.f)
{
    //Fill the values of accessMusic and accessSound to "true"
    accessMusic.assign(std::size(m_nameFileMusic), true);
    accessSound.assign(std::size(m_nameFileSound), true);

    //Loads music files.
    for (unsigned int i = 0; i < std::size(m_nameFileMusic); i++)
    {
        m_music.push_back(new sf::Music);
        if (!m_music[i]->openFromFile(m_nameFileMusic[i]))
            accessMusic[i] = false;
    }

    //Set the music files by setting the volume to them and activating repeat when the music files are finished.
    setVolumeMusic(m_volumeMusic);
    for(unsigned int i = 0; i < std::size(m_music); i++)
        if(m_nameFileMusic[i] != "data/gameOver.ogg")
            m_music[i]->setLoop(true);

    //Load sound files.
    const sf::SoundBuffer a;
    const sf::Sound b;
    for (unsigned int i = 0; i < std::size(m_nameFileSound); i++)
    {
        m_buffer.push_back(a);
        m_sound.push_back(b);
        if (!m_buffer[i].loadFromFile(m_nameFileSound[i]))
            accessSound[i] = false;
        else
            m_sound[i].setBuffer(m_buffer[i]);
    }
    //Fix the volume of the sound files.
    setVolumeSound(m_volumeSound);
    //If the main menu music file is available then play the music file.
    if(accessMusic[0])
        m_music[0]->play();

    m_sound[0].play();
}

当您复制 SFML 声音对象时,它们会停止播放。这就是在 std::vector 中重新定位对象时发生的情况。我建议将它们存储在指针中,如

using SoundPtr = std::shared_ptr<sf::Sound>;
std::vector< SoundPtr > m_sound;

是的,我回来告诉你我已经解决了这个问题,实际上我不得不将 std::vector 的初始化阶段和 [=15= 的初始化阶段分开] std::shared_ptr

谢谢大家!

    //Loads Buffer file
for (unsigned int i = 0; i < std::size(m_nameFileSound); i++)
{
    m_buffer.push_back(sf::SoundBuffer{});
    if (!m_buffer[i].loadFromFile(m_nameFileSound[i]))
        accessSound[i] = false;
}

//Loads Sound file
for (unsigned int i = 0; i < std::size(m_buffer); i++)
{
    m_sound.push_back(std::make_shared<sf::Sound>(sf::Sound{}));
    if (accessSound[i])
        m_sound[i]->setBuffer(m_buffer[i]);
}