我已经使用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。
任何帮助都将不胜感激。
答案 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::Sound
从sf::SoundBuffer
创建std::list
对象。然后,您只需在列表对象上使用emplace_back
并将sf::SoundBuffer
作为参数传递。
希望它有所帮助。