音乐播放,但不是声音?为什么? 我正在学习C++中的SFML库。我一直在尝试实现一种在游戏中组织音频的有效方法,方法是创建一个音频类,该类包含两个单独的std::map,分别用于音乐(sf::music)和声音(sf::sound)。但是,当我运行该程序时,只有音乐可以播放,但不能播放音效。我相信声音确实加载良好,因为它不会抛出错误消息。这是我的代码和信息。(由于我是新来的,可能也会给出关于我的代码的提示:D) 提前谢谢

音乐播放,但不是声音?为什么? 我正在学习C++中的SFML库。我一直在尝试实现一种在游戏中组织音频的有效方法,方法是创建一个音频类,该类包含两个单独的std::map,分别用于音乐(sf::music)和声音(sf::sound)。但是,当我运行该程序时,只有音乐可以播放,但不能播放音效。我相信声音确实加载良好,因为它不会抛出错误消息。这是我的代码和信息。(由于我是新来的,可能也会给出关于我的代码的提示:D) 提前谢谢,c++,audio,sfml,C++,Audio,Sfml,VS2012,SFML 2.1 SFML_Snake.h(游戏头文件) #pragma一次 #ifndef GUARD_SFML_SNAKE #定义保护\u SFML\u蛇 #包括“SFML/Audio.hpp” #包括“SFML/Graphics.hpp” #包括“Snake.h” #包括“Apple.h” #包括“Audio.h” #包括 类SFML_蛇{ 公众: SFML_Snake(); 无效运行(); 私人: 无效检查边界(Snake); 无效检查苹果(蛇和,苹果和,音频和); std

VS2012,SFML 2.1

SFML_Snake.h(游戏头文件)

#pragma一次
#ifndef GUARD_SFML_SNAKE
#定义保护\u SFML\u蛇
#包括“SFML/Audio.hpp”
#包括“SFML/Graphics.hpp”
#包括“Snake.h”
#包括“Apple.h”
#包括“Audio.h”
#包括
类SFML_蛇{
公众:
SFML_Snake();
无效运行();
私人:
无效检查边界(Snake);
无效检查苹果(蛇和,苹果和,音频和);
std::vector loadGrid();
私人:
bool processEvents();
无效更新(音频和音频);
无效渲染(std::vector&);
公众:
sf::RenderWindow窗口;
sf::文本文本计数;
蛇;
苹果;
};
int main(){
SFML_蛇形启动;
start.run();
}
#恩迪夫
SFML_Snake.cpp(游戏源文件)

/*导入语句*/
#包括
#包括
#包括
#包括
#包括“Snake.h”
#包括“variables.h”
#包括“Apple.h”
#包括“Audio.h”
#包括“SFML_Snake.h”
#包括
#包括
#包括
#包括
#包括
#包括
SFML_Snake::SFML_Snake():
窗口(sf::视频模式(窗口宽度、窗口高度),“SFML应用程序”),
snake(snake()),apple(apple(0,0)),textCount(sf::Text())
{
设置帧速率限制(帧速率);
}
void SFML_Snake::检查边界(Snake s){
对于(int z=点;z>0;z--){
如果((s.x[0]==s.x[z])&(s.y[0]==s.y[z]))
inGame=false;
}
如果(s.y[0]>=窗高)
inGame=false;
if(s.y[0]=窗宽)
inGame=false;
如果(s.x[0]=0;i--){
窗口绘制(网格[i]);
}
window.draw(textCount);
window.display();
}
std::vector SFML_Snake::loadGrid(){
矢量网格;

对于(int k=dotSize/2;k,
sf::SoundBuffer
有效地保存要播放的音频数据。要这样做,数据需要在播放时就存在。但是,在代码中,您可以在
audio::loadAudio()中加载缓冲区
但一旦您离开该函数,缓冲区就会被破坏,并且您的
sf::Sound
对象没有任何类型的数据可供播放


您更希望存储
sf::SoundBuffer
对象,而不是
sf::Sound
对象。

您基本上需要一个声音管理器,这是我用来管理声音的

头文件

#pragma once
#ifndef GUARD_SFML_SNAKE
#define GUARD_SFML_SNAKE

#include "SFML/Audio.hpp"
#include "SFML/Graphics.hpp"
#include "Snake.h"
#include "Apple.h"
#include "Audio.h"
#include <iostream>

class SFML_Snake{
public:
    SFML_Snake();
    void run();
private:
    void checkBoundary(Snake);
    void checkApple(Snake&, Apple&, Audio& );
    std::vector<sf::RectangleShape> loadGrid();
private:
    bool processEvents();
    void update(Audio&);
    void render(std::vector<sf::RectangleShape>&);

public:
    sf::RenderWindow window;
    sf::Text textCount;
    Snake snake;
    Apple apple;
};

int main(){
    SFML_Snake start;
    start.run();
}
#endif
#pragma once

#include "SFML/Audio.hpp"
#include "Enums.h"
#include <map>
#include <vector>
#include <iostream>

class SoundLoader
{
public:
    //SoundNames is an enum
    SoundLoader();
    ~SoundLoader();

    void LoadSounds();
    void PlaySound(SoundNames soundName);

    std::map<SoundNames, sf::SoundBuffer> Sounds;
    std::vector<sf::Sound> playingSounds;
};

希望这对您有所帮助,如果您需要更多帮助,请告诉我。

因此,我只需在另一个函数(如我的main)中将soundbuffer设置为新声音即可为了播放?不,声音缓冲区必须在您想要播放声音时存在。如果您只是加载它们,然后让它们超出范围,就像您在
Autio::loadAudio()中所做的那样
音频数据不存在,由于不存在音频数据,因此无法播放声音。只需将soundbuffer视为硬盘上的WAV文件,如果它不再存在,音频播放器是否仍能播放它?解决此问题的最佳方法是创建一个名为SoundManager的新类,该类存储sf::soundbuffer的向量,然后是c创建SoundManager,然后使用访问器访问向量并播放声音。我不一定推荐
std::vector
,因为它不是一个稳定的容器,因此如果容器扩展,它将重新分配自身并使所有引用无效,这意味着
sf::sound
对象将失去“连接”到缓冲区(就像播放音频文件时移动音频文件一样)。
#pragma once
#ifndef GUARD_AUDIO_H
#define GUARD_AUDIO_H
#include "variables.h"
#include "SFML\Graphics.hpp"
#include "SFML\Audio.hpp"
#include <memory>

struct Audio{
    std::map<std::string, sf::Sound> sounds;
    std::map<std::string, std::unique_ptr<sf::Music>> musics;
    //std::map<std::string, sf::Sound> sounds;
    //std::map<std::string, sf::Music> musics;

    Audio();

    void Audio::addSound(sf::Sound&, sf::SoundBuffer& , const std::string&);

    void Audio::addSound(sf::Sound&, const std::string&);

    void Audio::addMusic(const std::string&, std::unique_ptr<sf::Music> );

    sf::Sound &Audio::getSound(std::string);

    sf::Music &Audio::getMusic(std::string);

    void Audio::loadAudio();
};

#endif//GUARD_AUDIO_H
#include "Audio.h"
#include <iostream>
    Audio::Audio(){
        loadAudio();
    }
    void Audio::addSound(sf::Sound& s, sf::SoundBuffer& sb, const std::string &key){
        s.setBuffer(sb);
        sounds.insert(std::pair<std::string, sf::Sound>(key, std::move(s)));
    }
    void Audio::addSound(sf::Sound& s, const std::string &key){
        sounds.insert(std::pair<std::string, sf::Sound>(key, s));
    }
    void Audio::addMusic(const std::string &key, std::unique_ptr<sf::Music> value){
        musics.insert(std::pair<std::string, std::unique_ptr<sf::Music> >(key, std::move(value)));
    }
    sf::Sound &Audio::getSound(std::string key){
        return sounds.at(key);
    }
    sf::Music &Audio::getMusic(std::string key){
        return *musics.at(key);
    }
    void Audio::loadAudio(){

    //sf::Music backgroundMusic;
    sf::Sound s_eating;
    sf::SoundBuffer sb_eating;
    sf::Sound s_moving;
    sf::SoundBuffer sb_moving;
    sf::Sound s_losing;
    sf::SoundBuffer sb_losing;
    sf::Sound s_begin;
    sf::SoundBuffer sb_begin;

    auto backgroundMusic = std::unique_ptr<sf::Music>(new sf::Music());

    if (!backgroundMusic->openFromFile("backgroundmusic.wav"))
        if(DEBUG)
            std::cerr << "Error opening \"backgroundmusic.wav\"" << std::endl;
    if (!sb_eating.loadFromFile("eatingsfx.wav"))
        if(DEBUG)
            std::cerr << "Error opening \"eatingsfx.wav\"" << std::endl;
    if (!sb_moving.loadFromFile("movingsfx.wav"))
        if(DEBUG)
            std::cerr << "Error opening \"movingsfx.wav\"" << std::endl;
    if (!sb_losing.loadFromFile("losingsfx.wav"))
        if(DEBUG)
            std::cerr << "Error opening \"losingsfx.wav\"" << std::endl;
    if (!sb_begin.loadFromFile("beginsfx.wav"))
        if(DEBUG)
            std::cerr << "Error opening \"beginsfx.wav\"" << std::endl;

    //s_eating.setBuffer(sb_eating);
    //s_moving.setBuffer(sb_moving);
    //s_losing.setBuffer(sb_losing);
    //s_begin.setBuffer(sb_begin);
    addMusic(std::string("backgroundMusic"), std::move(backgroundMusic));
    addSound(s_eating, sb_eating, std::string("eating"));
    addSound(s_moving, sb_moving, std::string("moving"));
    addSound(s_losing, sb_losing, std::string("losing"));
    addSound(s_begin, sb_begin, std::string("begin"));
}
#pragma once

#include "SFML/Audio.hpp"
#include "Enums.h"
#include <map>
#include <vector>
#include <iostream>

class SoundLoader
{
public:
    //SoundNames is an enum
    SoundLoader();
    ~SoundLoader();

    void LoadSounds();
    void PlaySound(SoundNames soundName);

    std::map<SoundNames, sf::SoundBuffer> Sounds;
    std::vector<sf::Sound> playingSounds;
};
#include "SoundLoader.h"

SoundLoader::SoundLoader()
{

}

SoundLoader::~SoundLoader()
{

}

void SoundLoader::LoadSounds()
{
    Sounds[SoundNames::sound1].loadFromFile("Assets/Sounds/sound1.wav");
}

void SoundLoader::PlaySound(SoundNames soundName)
{
    if (playingSounds.size() == 0)
    {
        playingSounds.push_back(sf::Sound());
        playingSounds.at(0).setBuffer(Sounds[soundName]);
        playingSounds.at(0).play();
    }
    else
    {
        int location = -1;
        for (int i = 0; i < playingSounds.size(); i++)
        {
            if (playingSounds.at(i).getStatus() != sf::Sound::Playing && location == -1)
            {
                location = i;
            }
        }

        if (location != -1)
        {
            playingSounds.at(location).setBuffer(Sounds[soundName]);
            playingSounds.at(location).play();
        }
        else
        {
            playingSounds.push_back(sf::Sound());
            playingSounds.at(playingSounds.size()-1).setBuffer(Sounds[soundName]);
            playingSounds.at(playingSounds.size() - 1).play();
        }

    }
}
SoundLoader sl;
sl.LoadSounds();
sl.Play(SoundNames::sound1);