2010-12-16 2 views
1

OS :: win xp sp3.Wie man Schlüsselwort sofort ohne Verzögerung in Qt :: 4.6 (C++) arbeiten lassen?

Qt :: 4.6

Ich habe Klasse Gameboard, in dem ich habe einige rectangle.I keyPressEvent, um für das Rechteck definiert ihn um die screen.Key_A :: rectangle.moveToLeft & Key_D :: Rechteck zu bewegen. moveToRight.Problem ist, dass Tasten mit Verzögerung arbeiten. Wenn ich einen Schlüssel loslasse und einen anderen drücke, dauert es einige Zeit, bis dieser beginnt zu arbeiten. Ich habe Qt Online-Dokumentation überprüft und jetzt für diesen Effekt aber nicht jetzt, wie man diese Schlüssel sofort ohne Verzögerung zwischen ihnen arbeiten lässt?

Code-Schnipsel:

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


} 



} 
+0

Können Sie Code aus keyPressEvent() einfügen? – Septagram

+0

sollten Sie keine Verzögerung beim Tastendruck fühlen. Machst du schweres Zeichnen in ui thread? –

+0

Ich mache leichte Sachen, aber die Tasten reagieren nicht sofort. –

Antwort

3

Put Eingabecursor in einem anwendbaren Textfeld ein und drücken Sie die 'A' -Taste. Was Sie sehen werden, ist, sobald Sie die Taste drücken, wird der Buchstabe "A" gedruckt, dann wird es eine Pause geben, und dann werden dem ersten Buchstaben "A" schnell viele andere folgen. So funktionieren Keypress-Events. Und Ihr Programm empfängt sie genau so. Zuerst erhalten Sie ein Ereignis, wenn die Taste tatsächlich gedrückt wird, und dann nach einer Verzögerung erhalten Sie eine Menge automatisch wiederholter Ereignisse, falls Benutzer ein Zeichen viele Male eingeben möchte.

Es funktioniert perfekt für Texteingabe, aber in Spielen, die Sie normalerweise reibungslose Bewegung benötigen. Wenn dies der Fall ist, müssen Sie Ihr Schiff nicht beim Empfang des Ereignisses bewegen, sondern regelmäßig, beispielsweise bei einem Timer-Ereignis. Und Sie müssen sowohl das keyPressEvent- als auch das keyRelease-Ereignis abfangen und verwenden, um sich daran zu erinnern, welche Bewegungstasten gerade gedrückt werden. So könnte man zum Beispiel tun:

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

Dann nur sicherstellen, dass Schiff :: timerevent() auf jedem Timer-Ereignisse im Spiel aufgerufen wird.

+0

Wie stoppen Sie das Schiff? Dein Code schaltet nie is_moving_xxx aus. In der Tat werden beide eingestellt! – TonyK

+0

@TonyK Nach unten scrollen, das Schiff stoppt mit keyReleaseEvent(). – Septagram

+1

OK, ich bin dumm. – TonyK

Verwandte Themen