【问题标题】:Managing multiple RenderWindow's in sfml在 sfml 中管理多个 RenderWindow
【发布时间】:2015-02-05 16:17:29
【问题描述】:

在 SFML C++ 中管理多个窗口时,我似乎遇到了一些麻烦。当我尝试管理多个窗口时,它们都正确打开并且我可以在较大的窗口中进行交互,但是,较小的窗口在创建时与较大的窗口重叠,直到我将大窗口移开才能与之交互。下面的图像有助于视觉。下面也是我的代码的主循环。

代码主循环如下:

while (MainWin.isOpen() || F1Menu.isOpen())
{
    sf::Event Event;
    if (MainWin.pollEvent(Event))
    {
        switch (Event.type)
        {
            case sf::Event::Closed:
                MainWin.close();
                if (F1Menu.isOpen())
                    F1Menu.close();
            break;

            case sf::Event::Resized:
                MainView.reset(sf::FloatRect(0.f, 0.f, (MainWin.getSize().x*0.9f), (MainWin.getSize().y*0.9)));
                MainWin.setView(MainView);
            break;

            case sf::Event::KeyPressed:
                if (Event.key.code == sf::Keyboard::F1)
                    F1Menu.create(sf::VideoMode(200, 500), "SFML 2D - F1 Menu");
                else if (Event.key.code == sf::Keyboard::Escape)
                {
                    MainWin.close();
                    if (F1Menu.isOpen())
                        F1Menu.close();
                }
            break;
        }
    }

    if (F1Menu.pollEvent(Event))
    {
        switch (Event.type)
        {
            case sf::Event::Closed:
                F1Menu.close();
            break;

            case sf::Event::MouseButtonReleased:
                if (Event.mouseButton.button == sf::Mouse::Left)
                    if (LMButton.mouseIn(F1Menu))
                        LoadMap("MapA.dat");
            break;

            case sf::Event::MouseMoved:
                if (LMButton.mouseIn(F1Menu))
                    LMButton.setColor(sf::Color::Yellow);
                else
                    LMButton.setColor(sf::Color::White);
            break;
        }
    }

    moveClock.restart();
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        player.move(0, -4 * time);
        player.setDirection(sfm::Direction::Up);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        player.move(0, 4 * time);
        player.setDirection(sfm::Direction::Down);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        player.move(-4 * time, 0);
        player.setDirection(sfm::Direction::Left);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        player.move(4 * time, 0);
        player.setDirection(sfm::Direction::Right);
    }

    if (F1Menu.isOpen())
    {
        F1Menu.clear();
        F1Menu.draw(LMButton);
        F1Menu.display();
    }

    if (MainWin.isOpen())
    {
        MainWin.clear();
        if (SplashScreen.didAnimate)
            SplashScreen.Animate(MainWin, sfg::Animation::FadeIn);
        if (inMenu)
        {

        }
        if (isPlaying)
        {
            DrawMap(MainWin);
            MainWin.draw(player);
        }
        MainWin.display();
    }
}

【问题讨论】:

  • 你是在一个事件中创建你的第二个窗口吗?这通常是一个非常糟糕的主意,因为您不想为 F1 调用大量的创建调用是否有一个原因?这可能会给您以后带来一些麻烦
  • 我将为 F1 菜单添加一个检查,如果它已经打开,请不要再次打开它,或者关闭它。 if没有具体原因,我可以改成while。你对提出的问题有什么想法吗?
  • 您的事件检查从根本上就存在缺陷。每次轮询可以有多个事件,使用 while 将允许您从堆栈顶部弹出并继续处理 所有 事件。你应该修复你的代码,看看你的问题是否得到解决。请注意,您不应该在 inside 事件循环中创建窗口,因为您不能保证它只会被调用一次(除非您只是将它嵌套在 if 中以检查是否尚未创建窗口)
  • 问题依然存在。并将窗口创建嵌套在 if 中一直是这个想法

标签: c++ window render sfml


【解决方案1】:

据我所知,您无法使用一个 sf::Event 对象轮询两个单独的窗口。这是因为在轮询事件时,您实际上是 弹出 事件堆栈并处理每个事件。 pollEvent 的签名是

bool pollEvent(sf::Event &event);

注意这里没有const 限定符,因为每个已处理的事件都会从事件堆栈中弹出。当您完成轮询主窗口时,您的其他窗口没有任何事件。这可能是您的窗口无法聚焦的原因。你的第二个窗口应该使用它自己独立的sf::Event

另外,我强烈建议您将数据封装在类中。你可以找到一个很好的参考here 来了解如何去做。这是一种很好的编码实践,有助于在寻找错误时最大程度地减少混乱

【讨论】:

  • 已将其更改为两个事件。我正在将所有内容添加到类中,并尝试先解决此问题。编辑:已阅读提供的文章,稍后将使用它。
  • @Reborn 有两个事件不能解决问题吗?
  • 两个事件什么都不做。问题依然存在。
  • @Reborn 好的快速问题那么,当您单击窗口的 上部 部分时,您的第二个窗口是否聚焦? (靠近标题,而不是窗口主体)
  • 不,它不聚焦,但是当将其他窗口拖走时,较小的窗口不再在它前面,然后我可以聚焦在较小的窗口上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 2017-05-15
相关资源
最近更新 更多