如何使关键字在 Qt::4.6 (C++) 中立即无延迟地工作?

nik*_*_02 2 c++ visual-studio-2008 qt4.6

操作系统:: win xp sp3。

Qt::4.6

我有一个游戏板类,其中有一些矩形。我为该矩形定义了 keyPressEvent,以便在屏幕上移动他。Key_A :: 矩形.moveToLeft 和 Key_D :: 矩形.moveToRight。问题是按键有延迟。当我释放一个键并按下另一个键时,需要一些时间才能开始工作。我检查了 Qt 在线文档,现在了解了这种效果,但现在不知道如何使这些键立即工作而不会在它们之间产生延迟?

代码片段:

//in Gameboard class    

ship = new QRect(x,y,w,h);

void Gameboard::keyPressEvent(QKeyEvent* event)
{
switch(event->key())  {

case Qt::Key_A :
{ 
    x = x-10;
    ship->moveTo(x,y);
    break; 
}

case Qt::Key_D :
{
    x = x+10;
    ship->moveTo(x,y);
    break; 
}


}



}
Run Code Online (Sandbox Code Playgroud)

Sep*_*ram 5

将输入光标放入任何适用的文本框中,然后按“A”键。您将看到的是,一旦按下该键,就会打印字母“A”,然后会有一个暂停,然后第一个字母“A”很快就会出现许多其他字母。这就是按键事件的工作方式。而你的程序正是这样接收它们的。首先,当实际按下按键时,您会收到一个事件,然后在延迟后,您会收到许多自动重复的事件,以防用户想要多次输入一个字符。

它非常适合文本输入,但在游戏中您通常需要平滑的移动。如果是这种情况,您不需要在收到事件时移动您的飞船,而是定期移动您的飞船,例如在计时器事件上。您需要捕获 keyPressEvent 和 keyRelease 事件并使用它们来记住当前按下的移动键。所以你可以这样做:

struct Ship {
    bool is_moving_left, is_moving_right;
    QPoint position;
    int speed;

    ...

    void timerEvent()
    {
        if (is_moving_left) position.setX (position.x() - speed);
        if (is_moving_right) position.setX (position.x() + speed);
    }

    ...
};

...

void Gameboard::keyPressEvent (OKeyEvent *_event)
{
    switch(event->key())  {

    case Qt::Key_A :
        ship->is_moving_left = true;
        break; 

    case Qt::Key_D :
        ship->is_moving_right = true;
        break; 
    }
}

...

void Gameboard::keyReleaseEvent (OKeyEvent *_event)
{
    switch(event->key())  {

    case Qt::Key_A :
        ship->is_moving_left = false;
        break; 

    case Qt::Key_D :
        ship->is_moving_right = false;
        break; 
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需确保在游戏中的每个计时器事件上调用 Ship::timerEvent() 即可。