Question

OS:: win xp sp3.

Qt:: 4.6

I have class Gameboard in which i have some rectangle.I defined keyPressEvent for that rectangle in order to move him around the screen.Key_A :: rectangle.moveToLeft & Key_D :: rectangle.moveToRight.Problem is that keys work with delay. When i release one key and press another one it takes some time before that one begin to work.I checked Qt online documentation and now for that effect but dont now how to make those keys to work instantly without delay beetween them?

code snippet:

//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; 
}


}



}
Was it helpful?

Solution

Put input cursor into any applicable text box and press the 'A' key. What you'll see is once you press the key, letter 'A' will be printed, then there will be a pause, and then first letter 'A' will be quickly followed by many others. That's the way keypress events work. And your program is receiving them exactly like this. First you receive one event when the key is actually pressed, and then after a delay you get a lot of automatically repeated events, in case user wants to enter one character many-many times.

It works perfectly for text input, but in games you usually need smooth movement. If that's the case, you need to move your ship not upon receiving the event, but regularly, for example, on timer event. And you will need to catch both keyPressEvent and keyRelease event and use them to remember what movement keys are currently pressed. So you could for example do this:

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; 
    }
}

Then just make sure Ship::timerEvent() gets called on every timer event in the game.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top