2013-02-10 108 views
0

首先我想说我不确定标题是否合适,但这是我能找到的唯一合理解释。SFML2 Mouse :: isButtonPressed填满事件队列

我想要做的是通过点击一个精灵(有点像模拟一个标题栏)来移动我的窗口。 所有工作正常,直到我放开鼠标按钮发出新的鼠标事件的速度会降低,并且在它们之间有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; 
}; 
+0

一些代码证明这个问题会很好。 – 2013-02-10 19:46:07

+0

新增了一些代码 – user1233963 2013-02-10 19:56:20

回答

0

sf::Mouse类以及sf::Keyboardsf::Joystick没有连接到事件系统,但是完全独立,因此不可能对事件产生任何影响。

当您按下鼠标左键时,代码中的真正问题是'无限'循环。如果按下鼠标左键,则应用程序中发生的所有事情都是窗口四处移动。将不会有任何事件派发(=处理),并且在该时间内发生的每个事件都将被放入事件队列中。因此,当您返回处理事件时,您的队列将比平常长,并将开始分派最早的事件。 所以,如果你现在将你的窗户移动2秒钟,你会得到一个值得2秒的队列,这可能会延迟进一步的处理。

要解决此问题,您最有可能必须在移动窗口时分派所有事件。

+0

我应该怎么做?我尝试添加window.pollEvent(window.events);在while循环内但没有成功。 – user1233963 2013-02-13 08:43:02

+0

那么你基本上检查是否按下鼠标每一帧迭代,如果是这样的窗口移动。在每次帧迭代时都会自动处理事件。所以你实际上想用if语句来替换while循环,这会检查'clicked'状态。 – Lukas 2013-02-13 13:16:01