首页 > 解决方案 > SFML c ++如何在包含文件中的游戏中发生事件时为我的游戏创建带有铃声功能的声音类?

问题描述

在我的示例中,我只能通过在主函数中设置所有内容来使其工作令人困惑奇怪。我希望知道是否可能创建一个新类来将新类游戏声音中的所有函数组织在一个包含文件中。如果可能的话帮助

处理 cpp 文件的主要功能,但我希望创建一个包含文件,我认为它更好

      int main()
{
    //all inside main function not good confuse
    //sound play fire function
    sf::SoundBuffer fire;
    fire.loadFromFile("sounds/fire.wav");
    sf::Sound fired;
    fired.setBuffer(fire);

    // sound hit asteroid
    sf::SoundBuffer astHit;
    astHit.loadFromFile("sounds/explo_asteroid.wav");
    sf::Sound hited;
    hited.setBuffer(astHit);

    // sound Dead player
    sf::SoundBuffer pDead;
    pDead.loadFromFile("sounds/dead_player.wav");
    sf::Sound dead;
    dead.setBuffer(pDead);

    // sound Thrust Ship
    sf::SoundBuffer thrust;
    thrust.loadFromFile("sounds/thrust.wav");
    sf::Sound sthrust;
    sthrust.setBuffer(thrust);
    sthrust.setVolume(30);

     while (app.isOpen())
    {
        Event event;
        while (app.pollEvent(event))
        {
            if (event.type == Event::Closed)
                app.close();

            if (event.type == Event::KeyPressed)
             if (event.key.code == Keyboard::Space)
              {
                bullet *b = new bullet();
                b->settings(sBullet,p->x,p->y,p->angle,10);
                entities.push_back(b);
                fired.play();//fire play Sound
              }
        }

    if (Keyboard::isKeyPressed(Keyboard::Right)) p->angle+=3;
    if (Keyboard::isKeyPressed(Keyboard::Left))  p->angle-=3;
    if (Keyboard::isKeyPressed(Keyboard::Up)) p->thrust=true;
    else p->thrust=false;

    for(auto a:entities)
     for(auto b:entities)
     {
      if (a->name=="asteroid" && b->name=="bullet")
       if ( isCollide(a,b) )
           {
            hited.play();//Hited asteroid Sound
            a->life=false;
            b->life=false;

            Entity *e = new Entity();
            e->settings(sExplosion,a->x,a->y);
            e->name="explosion";
            entities.push_back(e);


            for(int i=0;i<2;i++)
            {
             if (a->R==15) continue;
             Entity *e = new asteroid();
             e->settings(sRock_small,a->x,a->y,rand()%360,15);
             entities.push_back(e);
            }

           }

      if (a->name=="player" && b->name=="asteroid")
       if ( isCollide(a,b) )
           {
            dead.play();//Dead Player Sound
            b->life=false;

            Entity *e = new Entity();
            e->settings(sExplosion_ship,a->x,a->y);
            e->name="explosion";
            entities.push_back(e);

            p->settings(sPlayer,W/2,H/2,0,20);
            p->dx=0; p->dy=0;
           }
     }


    if (p->thrust){   
        p->anim = sPlayer_go;
        sthrust.play();
    }   
    else   p->anim = sPlayer;
 }

}

标签: c++audiosfml

解决方案


我为您编写了一个“概念证明”,您应该能够使用您需要的所有声音来构建它。

首先,我们将制作一个头文件:

#ifndef SOUNDMANAGER
#define SOUNDMANAGER

#include <iostream>
#include <SFML/Audio.hpp>

class SoundManager {
public:
    SoundManager();

    void Fire();
    void AstHit();

private:
    sf::SoundBuffer sb_fire;
    sf::Sound s_fire;
    sf::SoundBuffer sb_astHit;
    sf::Sound s_astHit;
};

#endif

和一个cpp文件:

#include "SoundManager.h"

using namespace sf;

// Constructor
SoundManager::SoundManager() {
    if (!sb_fire.loadFromFile("sounds/fire.wav")) {
        std::cout << "ERROR: sounds/fire.wav didn't load" << endl;
    } else {
        s_fire.setBuffer(sb_fire);
    }

    if (!sb_astHit.loadFromFile("sounds/explo_asteroid.wav")) {
        std::cout << "ERROR: sounds/explo_asteroid.wav didn't load" << endl;
    } else {
        s_astHit.setBuffer(sb_astHit);
    }
}

//Functions
void SoundManager::Fire() {
    s_fire.play();
}

void SoundManager::AstHit() {
    s_astHit.play();
}

关于如何用自己的标题构建一个类有很多微妙之处,我不会对你说所有的“101类”,但要知道:

  • 头文件 (.h) 包含“定义”,我的意思是类声明、原型等。
  • 实现文件 (.cpp) 包含与您放入头文件的定义/原型/等相关的代码。

现在,您可以将此行添加到 main.cpp:

#include "SoundManager.h" //or whatever you named it

现在,在main.cpp您曾经声明一堆声音的地方,您可以改为声明 SoundManager 类的 ONE 实例:

SoundManager gameSounds;

当你这样做时,计算机会创建一个我们刚刚编写的类的实例。然后,它运行构造函数,这是一个初始化对象的函数。如果您阅读此构造函数,您会看到我们设置了声音以便稍后播放它们。该对象将跟踪他自己的东西,所以我们不必加载已经加载的东西。

另外,我是那种喜欢跟踪我的程序中的错误的人,所以我 ninja-ed 了一条线,所以当你的声音没有正确加载时,它会在你的控制台中这样说。

这就是说,现在在你的main()循环中,只要你想播放声音,你就可以去

gameSounds.Fire();

并播放相关声音。玩得开心!

(我有一段时间没有在 cpp 中编码了,所以如果比我更年轻的人​​发现了一些错误,请告诉我,以便我可以将它们编辑出来以供后代使用。)


推荐阅读