2014-12-01 57 views
1

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

主要方法

/*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; 
} 

例如,我将如何能够当蛇与苹果碰撞玩“吃” SFX?这里是我的checkApple()方法:

检查苹果的方法

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(); 

    } 
} 

我是新来的这些论坛,以及因此,如果有任何疑问,请询问。

回答

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]->play()

+0

非常简单而高效的代码访问存储在向量的声音。一位非常有帮助的成员给了我另一个在另一个问题上处理音频问题的好方法。因为我也是新手,所以学习SFML祝你好运。谢谢 – codingbash 2015-01-26 02:18:06