【问题标题】:Qt stop key events for a short period for a game loopQt在游戏循环的短时间内停止关键事件
【发布时间】:2017-03-17 11:21:17
【问题描述】:

我正在重写 keyPressEvent 以在 QGraphicsScene 中移动玩家。播放器有一个需要 1000 毫秒的动画(应该在继续之前完成)。

我的问题是,如果用户按住键,它会发送大量事件,实际上会导致明显的延迟。除了设置一些布尔值之外,还有什么方法可以暂时禁用事件监听?

进一步的问题;我有一个游戏循环,所有运动都应该以例如间隔发生。 1000 毫秒(想想所有玩家都在同一滴答声上移动的旧游戏 - 一切都保持同步)。除非用户在确切的时刻点击,否则他们将不得不等待下一个滴答声才能出现。所以这里的问题是我如何缓冲用户按下例如在滴答声前 200 毫秒,在滴答声发生的那一刻,它会执行最近的一次按下(上、下、左、右)。

或者我是不是搞错了?

【问题讨论】:

  • 我在游戏开发方面没有任何经验,但对于第一个问题,设置布尔值似乎是最好的选择。至于第二个问题,您可以创建一个仅保存一个关键事件的对象,当您开始“移动”时,您只需在其中写入第一个关键事件并丢弃所有其他事件

标签: c++ qt keyboard-events game-loop


【解决方案1】:

听起来你可能想做的是让你的 keyPressEvent() 回调方法变得非常轻量级;也就是说,除了设置一个变量来指示用户按下了什么键之外,它什么都不做:

void MyClass :: keyPressEvent(QKeyEvent * keyEvent)
{
   // all we'll do for now is remember what the user pressed (overwriting any previously-cached value)
   this->userPressedKey = key->key();  
   keyEvent->accept();
}

void MyClass :: tick()  // called every 200mS or whatever
{
   if (this->userPressedKey != Qt::Key_Unknown)
   {
      processKeyPressPerMyGameLogic(this->userPressedKey);
      this->userPressedKey = Qt::Key_Unknown;  // clear the state in preparation for the next tick() call
   }
   doOtherGameLogicHere();
}

如果您希望用户每回合能够执行多个键事件,而不仅仅是一个,您可以将this->userPressedKey(当前为int 类型的成员变量)替换为QSet<int> 或类似名称。

【讨论】:

  • QSet 不会保存有关哪个事件先发生的信息,QVector 会保存
  • @sfk92fksdf QVector 的问题是,如果用户按住一个键,因此应用程序接收到“键事件的负载”,正如提问者所描述的那样,那么最后 QVector 将包含负载条目,用户将回到他原来的问题。不过,我同意保留有关接收事件顺序的信息可能很有用;具有可以实现的适当数据结构(或 QVector 和仅插入的算法)。
猜你喜欢
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多