0

首先我想说我不确定标题是否合适,但这是我能找到的唯一合乎逻辑的解释。

我想要做的是通过单击精灵来移动我的窗口(有点像模拟标题栏)。一切正常,直到我放开鼠标按钮,新鼠标事件的发射率要低得多,并且它们之间有 1.5~2 秒的巨大停顿。

sf::Mouse::isBUttonPressed 是否可能正在填充队列,还是另一个问题?

编辑:窗口类有一个 sf::Event 对象并将其传递给每个对象的事件处理程序。sprite 类有一个这种形式的事件处理程序:

bool object::handleEvents(sf::Event& event)
{
    switch(event.type)
    {
        case sf::Event::MouseMoved:
        case sf::Event::MouseButtonPressed:
        case sf::Event::MouseButtonReleased:
        {
            auto mouse_pos = sf::Mouse::getPosition(*this->parent);

            if(this->isPointInside(mouse_pos))
            {
                if(event.type == sf::Event::MouseMoved)
                {
                    this->hovering = true;

                    if(this->callback["onHover"])
                        this->callback["onHover"](this, nullptr);

                    return true;
                }
                else if(event.type == sf::Event::MouseButtonPressed)
                {
                    this->clicked = true;
                    this->focused = true;

                    if(event.mouseButton.button == sf::Mouse::Left)
                        if(this->callback["onLClick"])
                            this->callback["onLClick"](this, ref(mouse_pos));

                    if(event.mouseButton.button == sf::Mouse::Right)
                        if(this->callback["onRClick"])
                            this->callback["onRClick"](this, ref(mouse_pos));

                    return true;
                }
                else if(event.type == sf::Event::MouseButtonReleased && this->clicked)
                  {
                        this->clicked = false;

                        if(event.mouseButton.button == sf::Mouse::Left)
                            if(this->callback["onLClickReleased"])
                                this->callback["onLClickReleased"](this, ref(mouse_pos));

                        if(event.mouseButton.button == sf::Mouse::Right)
                            if(this->callback["onRClickReleased"])
                                this->callback["onRClickReleased"](this, ref(mouse_pos));

                        return true;
                  }
                }
            else
            {
                if(this->hovering)
                {
                    if(this->callback["onHoverLost"])
                        this->callback["onHoverLost"](this, nullptr);
                    this->hovering = false;
                }
            }
        }break;

        default: ;
    }
    return false;
}

以及负责移动窗口的代码:

titlebar->callback["onLClick"] = [&](object* obj, void* data)
{
    sf::Vector2i* relpos = (sf::Vector2i*)(data);
    while(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        sf::Vector2i abspos = sf::Mouse::getPosition();
        window.setPosition(sf::Vector2i((abspos.x - relpos->x),(abspos.y - relpos->y)));
    }
    titlebar->clicked = false;
};
4

1 回答 1

0

该类sf::Mouse与事件系统无关,而是完全独立的sf::Keyboardsf::Joystick因此不可能isButtonPressed对事件产生任何影响。

代码中的真正问题是按下鼠标左键时的“无限”循环。如果按下鼠标左键,那么在您的应用程序中发生的一切都是,窗口会四处移动。不会有任何事件分派(= 处理),并且在那段时间内发生的每个事件都将被放入事件队列中。因此,当您返回处理事件时,您将拥有比平时更长的队列,并且会从最旧的事件开始调度。因此,如果您现在将窗口移动 2 秒,您将获得一个 2 秒的填充队列,这可能会延迟进一步的处理。

要解决此问题,您很可能必须在移动窗口时调度所有事件。

于 2013-02-13T04:11:24.750 回答