2010-02-10 25 views
3

Je suis en train de programmer un jeu en "OpenGL" et en utilisant "Gtkmm" comme gestionnaire de fenêtres. Je veux utiliser le clavier pour déplacer la caméra (ainsi, «UP-key» pour avancer, «DOWN-key» pour reculer, etc ...)Jeu OpenGL/Gtkmm - Déplacement du clavier

Il y a quelque temps, quand j'ai programmé en Java, j'ai Lorsque l'application a reçu par exemple le signal "UP-key- press", elle a ensuite défini l'indicateur "shouldMoveForward" sur "true" et a ensuite reçu la touche "UP". - release "signal, il remet le drapeau à" false ". Et la "boucle de jeu" continuellement vérifié pour ce drapeau, et si c'était vrai, il déplace la caméra vers l'avant, sinon il n'a rien fait.

Alors que je voudrais utiliser la même technique dans "Gtkmm". Je viens donc de overrided ces fonctions de mon « Gtk :: DrawingArea »:

bool Gtk::Widget::on_key_press_event(GdkEventKey* event) 
bool Gtk::Widget::on_key_release_event(GdkEventKey* event) 

Mais le problème est en ceci: quand je par exemple appuyer sur la touche « UP » et maintenez-le pendant 5 secondes, cette séquence de signaux est émis:

press ...<little time waiting>... release press release press release press release .......... press release press release 

La situation précédente apparaît lorsque je courais mon jeu « sur Linux ».

Quand je suis « sous Windows », il est comme je veux que ce soit, ainsi:

press ...<little time waiting>... press press press press press .......... press press release 

Donc, cela semble être une solution « non-portable » pour caméra mobile dans Gtkmm. solution pour obtenir la caméra mobile à l'aide Gtkmm en tant que gestionnaire de fenêtres

Ainsi est-il un autre (« PORTABLE »)?

Répondre

2

This thread décrit le problème (qui n'est pas dans GTK + lui-même), et quelques solutions de contournement.

0

Je viens de rencontrer la "fonctionnalité" répétition automatique dans mon jeu java, et je l'ai corrigé.

Puisque vous savez java vous ne devriez pas avoir des problèmes de portage le code suivant:

// Keyboard 
private final List<Integer> keysPressed = new LinkedList<Integer>(); 
private final List<Integer> keysDown = new LinkedList<Integer>(); 
private final List<Integer> keysRemove = new LinkedList<Integer>(); 

public final void keyPressed(final KeyEvent e) { 
    int key = e.getKeyCode(); 

    // Fix AutoKeyRepeat under X11 
    if (keysRemove.contains(key)) { 
     keysRemove.remove(Integer.valueOf(key)); 
    } 

    if (!keysDown.contains(key)) { 
     keysDown.add(key); 
     keysPressed.add(key); 
    } 
    e.consume(); 
} 

public final void keyReleased(final KeyEvent e) { 
    int key = e.getKeyCode(); 
    keysRemove.add(key); 
    e.consume(); 
} 

public final void clearKeys() { 
    for (Integer key : keysRemove) { 
     keysDown.remove(Integer.valueOf(key)); 
     if (keysPressed.contains(key)) { 
      keysPressed.remove(Integer.valueOf(key)); 
     } 
    } 
    keysRemove.clear(); 
    keysPressed.clear(); 
} 

La méthode clearKeys est appelée dans la boucle principale juste après l'état du jeu a été mis à jour (vérifié pour la saisie du clavier/DEPLACE objets) le tour est ici le premier si keyPressed. Les événements clés générés automatiquement se produisent exactement au même moment, il est donc presque impossible que quelque chose se passe entre les faux événements keyReleased et keyPressed. La seule façon dont une clé peut être dans la liste keyRemove lorsqu'un événement keyPressed se produit est qu'il s'agit d'un faux événement. Dans ce cas, nous supprimons simplement la clé de la liste keyRemove. Lorsque vous relâchez la touche normalement, elle n'est pas suivie d'un événement keyPressed immédiat, elle n'est donc pas supprimée de la liste et traitée par clearKeys.

Pour le reste du code (comme vérifier si une clé est en panne ou a été pressé) vérifier la source: http://github.com/BonsaiDen/Bonsai-Game-Library/blob/master/src/org/bonsai/dev/GameInput.java