【问题标题】:How do I properly organize and implement SFML audio in C++?如何在 C++ 中正确组织和实现 SFML 音频?
【发布时间】:2015-01-29 21:38:03
【问题描述】:

对于我的一个高中独立学习项目,我必须使用 Visual C++ 中的 SFML 制作一个简单的游戏(特别是游戏“Snake”)(是的,我是 C++ 和 SFML 的新手)。我已经编写了游戏的核心和图形,现在我正在处理音频和声音效果。我已经阅读了 SFML 书中有关音频的一些内容,但仍然对如何在我的代码中正确实现这一点感到困惑。我知道我必须创建一个 sf:Sound 和一个 sf::SoundBuffer 对象,分别使用 loadFromFile 和 openFromFile 加载声音和音乐,并使用 sound.play() 和 sound.stop() 分别播放和停止。然而,这就是问题所在。我是否在 main 方法中加载这些对象,我是否将它们作为全局对象,以便我可以在整个代码中使用,我是否在发生 sfx 的函数中加载,我做一个包含所有声音的对象?...通常,我如何在我的代码中正确组织和实现这些音频文件。这是我目前所拥有的:

主要方法

/*Main method*///
int main(){
    /*Initialize the objects*/
    Snake snake = Snake();
    sf::Text textCount;
    Apple apple(0, 0);
    apple.locateApple();
    sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "SFML Application" );
    /*Load the audio*/

    sf::Music backgroundMusic;
    sf::Sound eating;
    sf::SoundBuffer sb_eating;
    sf::Sound moving;
    sf::SoundBuffer sb_moving;
    sf::Sound losing;
    sf::SoundBuffer sb_losing;
    sf::Sound begin;
    sf::SoundBuffer sb_begin;

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

    eating.setBuffer(sb_eating);
    moving.setBuffer(sb_moving);
    losing.setBuffer(sb_losing);
    begin.setBuffer(sb_begin);

    moving.setVolume(50);

    backgroundMusic.setLoop(true);
    backgroundMusic.play();

    /*Load the font*/
    sf::Font font;
    if (!(font.loadFromFile("arial.ttf")))
        std::cout << "Error loading fonts" << std::endl;
    /*Create the text*/
    textCount.setFont(font);
    textCount.setString(std::string("points: ") + std::to_string(points));
    textCount.setColor(sf::Color::Red);
    textCount.setCharacterSize(20);
    textCount.setPosition(windowWidth / 2 - (textCount.getString().getSize()*(textCount.getCharacterSize() / 5)), textCount.getCharacterSize() - 5);
    textCount.setStyle(sf::Text::Bold);

    window.draw(textCount);

    /*Set Framerate fps*/
    window.setFramerateLimit(15);

    /*MAIN GAME LOOP*/
    counterTick = 1;


    while (inGame)
    {
        std::string counter = std::to_string(counterTick);
        std::cout << "Tick: " + counter << std::endl;

        window.clear(sf::Color::Black);
        sf::Event event;
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) break;
        /*Call Updates*/
        snake.input();
        snake.checkReals();
        snake.moveUpdate();
        moving.play();

        /*Call Collisions*/
        std::cout << "     Outside Collision Loop " << std::endl;
        checkApple(snake, apple);
        checkBoundary(snake);

        /*Call Draw*/
        std::vector<sf::RectangleShape> shapearray = snake.draw();
        for (int i = shapearray.size() - 1; i >= 0; i--){
            window.draw(shapearray[i]);
        }
        window.draw(textCount);
        window.draw(apple.draw());
        window.display();

        counterTick++;

    }
    losing.play();
    backgroundMusic.stop();
    std::system("PAUSE");//bad practice, debuggin purposes
    return 0;
}

例如,当蛇撞到苹果时,我将如何播放“吃”的音效?这是我的 checkApple() 方法:

检查 Apple 方法

void checkApple(Snake mA, Apple& mB){
    if ((mA.x[0] == mB.x()) && (mA.y[0] == mB.y())){
        dots += dotInterval;
        std::cout << "In Collision Method" << std::endl;
        points++;
        textCount.setString(std::string("points: ") + std::to_string(dots - 3));
        mB.locateApple();

    }
}

我也是这些论坛的新手,如果有任何问题,请提出。

【问题讨论】:

    标签: c++ visual-studio-2012 audio sfml


    【解决方案1】:

    首先,我对 C++ 和 SFML 还很陌生。我确信有比我现有的更好的解决方案来解决您的问题,但这里就是这样。

    我有一个名为 loadAudio(std::string source) 的方法和一个存储音频的向量。

    class Audio {
    
    private:
        sf::SoundBuffer buffer;
        sf::Sound sound;
        std::string _src;
    public:
        void init(std::string src) {        //Initialize audio
            _src = src;
            buffer.loadFromFile(src);
            sound.setBuffer(buffer);
        }
        void play(){
            sound.play();       // Play queued audio
        }
        void stop(){
            sound.stop();
        }
        //void setVolume(), void setPitch() ....
    
    
    };
    
    std::vector<Audio*> audio;
    
    void loadAudio(std::vector<std::string> src) {
        audio.push_back(new Audio());
        audio.back()->init(src[i]);
    }
    

    所以基本上在游戏开始时我声明的声音是这样的:

    loadAudio("sound/foo.wav");
    loadAudio("sound/bar.wav");
    

    然后我可以使用 audio[0]-&gt;play() 访问存储在向量中的声音

    【讨论】:

    • 非常简单但高效的代码。在我的另一个问题中,一位非常乐于助人的成员为我提供了另一种处理音频的好方法。祝我学习 SFML 好运,因为我也是新手。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2012-05-21
    • 2018-09-24
    • 2018-06-26
    • 1970-01-01
    • 2011-02-08
    相关资源
    最近更新 更多