SFML 音频 Visual Studio C++

问题描述 投票:0回答:1

我正在使用 Visual Studio 运行一个简单的 SFML,它是超级马里奥的克隆。 我尝试复制这个问题,但失败了,所以只是用实际问题更新了这篇文章。我知道这是很大的,但已尽力保留所有必要的功能。任何复制该问题的建议也将不胜感激。

问题
在我的游戏中,

registerAction()
函数将与场景相关的每个键盘输入设置为一个动作,完成后,在游戏循环中调用
sUserInput()
中的
GameEngine
,检查是否有任何有效的按键输入,然后调用 sDoAction( ) 相关场景。在每个场景的每个游戏循环中,它都会调用
sMovement()
并更新各个实体的位置。

现在我想在玩家跳跃时播放音频,当检测到播放跳跃时,我已将其添加到

sMovement()
下,但音频不会播放,除非我在那之后添加了睡眠。添加睡眠会使游戏延迟,因为游戏会冻结几秒钟。那么知道如何在不睡觉的情况下添加声音吗?

完整源代码:https://github.com/Shreyas9699/SuperMarioClone

void Scene_Play::init(const std::string& levelPath)
{
    std::cout << "Level Scene init started" << std::endl;
    registerAction(sf::Keyboard::P,      "PAUSE");
    registerAction(sf::Keyboard::Escape, "QUIT");
    registerAction(sf::Keyboard::T,      "TOGGLE_TEXTURE");         // toggle drawring (T)extures
    registerAction(sf::Keyboard::C,      "TOGGLE_COLLISION");       // toggle drawring (T)extures
    registerAction(sf::Keyboard::G,      "TOGGLE_GRID");            // toggle drawring (T)extures
    registerAction(sf::Keyboard::W,      "UP");
    registerAction(sf::Keyboard::A,      "LEFT");
    registerAction(sf::Keyboard::D,      "RIGHT");
    registerAction(sf::Keyboard::Space,  "FIRE");

    m_gridText.setCharacterSize(2);
    m_gridText.setFont(m_game->getAssets().getFont("dogica"));

    // Game Score
    m_scoreText.setCharacterSize(30);
    m_scoreText.setFont(m_game->getAssets().getFont("Mario"));
    m_scoreText.setFillColor(sf::Color::White);

    // Level Timre
    m_timerText.setCharacterSize(30);
    m_timerText.setFont(m_game->getAssets().getFont("Mario"));
    m_timerText.setFillColor(sf::Color::White);

    sf::View view = m_game->window().getView();
    view.setSize(width() / 4.0f, height() / 4.0f);
    m_game->window().setView(view);
    auto start = std::chrono::high_resolution_clock::now();
    loadLevel(levelPath);
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "Time taken to load Scene and its scene entities : " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start) << std::endl;
}
void Scene_Play::sDoAction(const Action& action)
{
    auto& input = m_player->getComponent<CInput>();

    if (action.type() == "START")
    {
        if      (action.name() == "TOGGLE_TEXTURE")     { m_drawTexture = !m_drawTexture; }
        else if (action.name() == "TOGGLE_COLLISION")   { m_drawCollision = !m_drawCollision; }
        else if (action.name() == "TOGGLE_GRID")        { m_drawGrid = !m_drawGrid; }
        else if (action.name() == "PAUSE")              { m_paused = !m_paused; }
        else if (action.name() == "QUIT")               { onEnd(); }
        else if (action.name() == "UP")                 { input.up = true; }
        else if (action.name() == "DOWN")               { input.down = true; }
        else if (action.name() == "RIGHT")              { input.right = true; }
        else if (action.name() == "LEFT")               { input.left = true; }
        else if (action.name() == "FIRE" && !input.shoot)
        {
            input.shoot = true;
            spawnBullet(m_player); 
        }
    }
    else if (action.type() == "END")
    {
        if      (action.name() == "UP")     { input.up = false; }
        else if (action.name() == "DOWN")   { input.down = false; }
        else if (action.name() == "RIGHT")  { input.right = false; }
        else if (action.name() == "LEFT")   { input.left = false; }
        else if (action.name() == "FIRE")   { input.shoot = false; }
    }
}
void Scene_Play::sMovement()
{
    // Player movement
    auto& input = m_player->getComponent<CInput>();
    auto& transform = m_player->getComponent<CTransform>();

    if (input.up && input.canJump)
    {
        transform.velocity.y -= m_playerConfig.JUMP;
        input.canJump = false;
        sf::Sound m_sound;
        m_sound.setBuffer(m_game->getAssets().getSound("MarioAir"));
        m_sound.play();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    float xSpeed = 0.0f;
    if (input.right)
    {
        xSpeed += m_playerConfig.SPEED;
        transform.scale.x = -1.0f;
    }
    if (input.left)
    {
        xSpeed -= m_playerConfig.SPEED;
        transform.scale.x = 1.0f;
    }
    transform.velocity.x = xSpeed;

    if (xSpeed == 0.0f)
    {
        if (m_isSuperMario && m_player->getComponent<CState>().state != "SuperMarioStand")
        {
            m_player->getComponent<CState>().state = "SuperMarioStand";
            m_StateChanged = true;
        }
        else if (!m_isSuperMario &&  m_player->getComponent<CState>().state != "MarioStand")
        {
            m_player->getComponent<CState>().state = "MarioStand";
            m_StateChanged = true;
        }
    }
    else
    {
        if (m_isSuperMario && m_player->getComponent<CState>().state != "SuperMarioRun")
        {
            m_player->getComponent<CState>().state = "SuperMarioRun";
            m_StateChanged = true;
        }
        else if (!m_isSuperMario && m_player->getComponent<CState>().state != "MarioRun")
        {
            m_player->getComponent<CState>().state = "MarioRun";
            m_StateChanged = true;
        }
    }

    auto& gravity = m_player->getComponent<CGravity>();
    transform.velocity.y += gravity.gravity;

    if (transform.velocity.y >= m_playerConfig.MAXSPEED)
    {
        transform.velocity.y = m_playerConfig.MAXSPEED;
    }

    transform.prevPos = transform.pos;
    transform.pos += transform.velocity;
    // rest code for different input handle
}
void GameEngine::sUserInput()
{
    sf::Event event;
    while (m_window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        {
            std::cout << "Exiting the game!\n";
            quit();
        }
        if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::X)
        {
            std::cout << "trying to save screeshot to " << "test.png" << std::endl;
            sf::Texture t;
            t.create(m_window.getSize().x, m_window.getSize().y);
            t.update(m_window);
            if (t.copyToImage().saveToFile("test.png"))
            {
                std::cout << "screenshot saved to " << "test.png" << std::endl;
            }
        }
        if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
        {
            if (getCurrentScene()->getActionMap().find(event.key.code) == getCurrentScene()->getActionMap().end())
            {
                continue;
            }
            const std::string actionType = (event.type == sf::Event::KeyPressed) ? "START" : "END";
            getCurrentScene()->sDoAction(Action(getCurrentScene()->getActionMap().at(event.key.code), actionType));
        }
    }
}
audio graphics c++17 rendering sfml
1个回答
1
投票

因为声音一开始播放程序就结束了,所以你什么也听不到。

sound.play()
启动一个新线程,以不阻塞接下来的代码,但由于主函数随后结束,子线程也会结束。您可以尝试将睡眠功能放在
sound.play();
之后,但在
return 0;

之前
© www.soinside.com 2019 - 2024. All rights reserved.