声明sf :: SoundBuffer会导致程序在终止时崩溃

时间:2017-07-30 19:24:47

标签: c++ audio sfml

我已经使用SFML很长一段时间了,但直到现在我才从未使用过音频模块。

我想为我的游戏添加声音效果,所以我的第一种方法与此类似......

class Deck : public sf::Drawable
{
public:
    ...

private:
    sf::Sound shuffleSound;

    ...

    static sf::SoundBuffer soundBuffer;
};

计划是初始化soundBuffer一次并在每个对象的构造函数中执行shuffleSound.setBuffer(soundBuffer);。但我得到了这个错误:

AL lib: (EE) alc_cleanup: 1 device not closed

Assertion failed: (lockret == althrd_success), function LockLists, file /Users/m/Desktop/tmp/openal/build_deps/openal-soft-openal-soft-1.17.2/Alc/ALc.c, line 776.
(lldb) 

在谷歌搜索这个错误之后,我看到了一条关于不将SFML资源放在全局范围内的晦涩信息。找出static变量是导致错误的原因,我试过这个:

class Deck : public sf::Drawable
{
public:
    ...

private:
    sf::Sound shuffleSound;

    ...

    static std::unique_ptr<sf::SoundBuffer> bufptr;
};

如果对象为空,则通过调用make_unique初始化指针,然后在构造函数中执行shuffleSound.setBuffer(*bufptr)

但是,我仍然得到同样的错误。在程序即将终止之前,错误不会发生,BTW。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

我无法添加任何评论,因为我的声誉太低,所以我会写下答案。

一开始,我建议您创建一些可以保留所有资源的课程。 检查一下:https://github.com/SFML/SFML-Game-Development-Book/tree/master/02_Resources/Include/Book

有SFML游戏开发书的源代码 - 你可以在SFML Github上找到很多有用的资料。

因此,在您的情况下,您可以创建该类类型的对象:ResourceHolder<sf::SoundBuffer, ID> mSoundHolder;其中ID为enum类型,以标识每个声音。

然后播放您的声音只需创建sf::Sound s类型的对象,然后使用s.setBuffer(mSoundHolder.getResource(<YOUR_ID>)s.play()

确保sf::Sound不是本地对象,因为它不会播放,因为它会自动快速销毁。然后在课堂上创建它,或者如果你想在同一个创建更多的声音,例如std::list<sf::Sound> sounds,它会播放声音。要检查播放完毕,请使用:sound.getStatus() == sf::Sound::Stopped比较,然后从列表中删除声音。

您可以使用sf::Soundsf::SoundBuffer创建std::list对象。然后,您只需在列表对象上使用emplace_back并将sf::SoundBuffer作为参数传递。

希望它有所帮助。