1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

KeyListener verzögerung!

  • INoNameI
  • 1. September 2011 um 20:14
  • Unerledigt
  • INoNameI
    3
    INoNameI
    Mitglied
    Punkte
    80
    Beiträge
    13
    • 1. September 2011 um 20:14
    • #1

    Hallo,

    ich habe folgendes Problem:
    Wenn ich versuche mit einem KeyListener ein KeyEvent abzufangen, funktioniert alles
    eigendlich ganz gut, nur wenn man eine Taste gedrückt hält, kommt eine Verzögerung zwischen dem drücken der Taste und dem Taste gedrückt halten, hmm schwierig zu erklären ... seht euch einfach mal den Code an:

    Java
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package javaapplication13;
    
    
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import javax.swing.JFrame;
    
    
    public class KeyListenerTest extends JFrame implements KeyListener {
    
    
        /**
         * @param args the command line arguments
         */
    
        public KeyListenerTest () {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.addKeyListener((KeyListener) this);
        }
    
        public static void main(String[] args) {
            java.awt.EventQueue.invokeLater(new Runnable() {
    
    
                @Override
                public void run() {
                    new KeyListenerTest().setVisible(true);
                }
            });
        }
    
    
        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("KeyTyped");
        }
    
    
        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println("KeyPressed");
        }
    
    
        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("KeyReleased");
        }
    }
    Alles anzeigen

    Bei diesem Code würde die Ausgabe dann so aussehen:


    KeyPressed
    KeyTyped

    /* Hier wäre dann die Verzögerung wenn man die Taste gedrückt hält (ca. 0.5 sec)*/

    KeyPressed
    KeyTyped
    KeyPressed
    KeyTyped
    KeyPressed
    KeyTyped
    .
    .
    .
    KeyReleased

    Um hier auf den Punkt zu kommen:
    Ich möchte, dass diese Verzögerung verschwindet.

    Ich hoffe ich habe mein Problem ausführlich beschrieben, und hoff auch auf baldige Antwort.

    MfG,
    INoNameI!

    2 Mal editiert, zuletzt von INoNameI (1. September 2011 um 20:21)

  • Paulchen
    1
    Paulchen
    Gast
    • 1. September 2011 um 20:41
    • #2
    Zitat von INoNameI

    Um hier auf den Punkt zu kommen:
    Ich möchte, dass diese Verzögerung verschwindet.

    Mach einen Editor auf und halte dort im Textfeld eine Taste gedrückt. Auch hier wird dir eine Verzögerung auffallen. Sinn dieser Verzögerung ist, dass verhindert wird, dass man mit einem einzelnen Tastenanschlag ein- und dasselbe Zeichen mehrmals eingibt.

    Abhängig vom verwendeten Betriebssystem kann man sowohl diese Verzögerung als auch die Wiederholrate einstellen, unter Windows etwa in der Systemsteuerung oder unter System -> Einstellungen -> Tastatur im GNOME-Desktop.

  • Ramses13
    4
    Ramses13
    Mitglied
    Reaktionen
    4
    Punkte
    164
    Beiträge
    31
    • 1. September 2011 um 20:55
    • #3

    Kommt drauf an was du damit machen willst.
    Wenn du z.B. eine Figur in einer Animation (z.B. in einem Spiel) steuern willst, dann wirst du sowieso eine Animationsschleife haben (d.h. ein separater Thread, der in einer Schleife in regelmäßigen Abständen alle Elemente bewegt). Btw.: Falls du so etwas nicht hast, dann kann man so einen Thread auch nur für die Tastatur schreiben, alternativ zur Schleife ist auch ein ein Timer möglich.
    Dann braucht man nur mehr eine Variable, in der der letzte Tastendruck gespeichert wird (bei keyPressed), bzw. beim Loslassen (keyReleased) wieder gelöscht wird. Nun kann man in der Animationsschleife diese Variable abprüfen und hat in regelmäßigen Abständen die Möglichkeit das zu tun was immer man mit diesem Tastendruck tun möchte. Will man mehrere Tasten gleichzeitig auswerten (z.B. Pfeiltasten links und oben für eine Bewegung einer Spielfigur nach links oben), so muss man eben mehrere Tasten separat speichern (d.h. mehrere boolsche Variablen für die jeweiligen Tasten).

    Nachteil des ganzen: Die Taste wird erst eine Kleinigkeit verzögert ausgewertet (max. einen Schleifendurchlauf zu spät). Macht aber bei z.B. 30 Animationsschritten pro Sekunde in einem Spiel normalerweise nichts. Braucht man eine sofortige Reaktion, so muss man die Schleife (Thread) beim ersten Tastendruck starten und beim Loslassen wieder stoppen.

    Hoffe es war verständlich. Ich musste allerdings etwas allgemein bleiben, da ich die näheren Umstände nicht kenne.

    Edit: Das Ändern der Verzögerung/Wiederholrate im Betriebssystem bringt nichts, und zwar aus mehreren Gründen:
    - Man kriegt diese Verzögerung normalerweise nie ganz weg (zumindest nicht unter Windows, unter Linux habe ich das noch nie ausprobiert)
    - Man will wohl kaum jedesmal am Betriebssystem herumpfuschen, wenn man in einem einzelnen Programm keine Tastenverzögerung haben möchte.

    Einmal editiert, zuletzt von Ramses13 (1. September 2011 um 21:22)

  • INoNameI
    3
    INoNameI
    Mitglied
    Punkte
    80
    Beiträge
    13
    • 1. September 2011 um 21:28
    • #4

    Ersteinmal danke für die Antworten.

    Zu meinem Projekt:
    Ich habe vor ein Mario-Spiel zu schreiben, und dieses Spiel soll NICHT in einem Applet laufen.
    Das Wissen, die Bilder etc habe ich ja auch dafür, aber mich stört das nur wenn sich die Spielfigur einen Schritt weiter bewegt
    und dann erst (nach ca. 0.5 sec) anfängt zu laufen.

    Es gibt ja auch noch die veralteten Methoden:

    public boolean keyUp(Event e, int key);
    public boolean keyDown(Event e, int key);

    Bei diesen ist die Verzögerung ja nicht vorhanden soweit ich weiß,
    aber ich glaube fast das diese Methoden außerhalb von Applets nicht, bzw. nur schwer implementierbar sind, oder Irre ich mich?

    MfG,
    INoNameI!

  • INoNameI
    3
    INoNameI
    Mitglied
    Punkte
    80
    Beiträge
    13
    • 1. September 2011 um 21:45
    • #5

    Ja, habe es gerade herausgefunden.

    Java
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package javaapplication13;
    
    
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JFrame;
    
    
    public class KeyListenerTest extends JFrame implements Runnable, KeyListener {
    
        private boolean walk_left  = false;
        private boolean walk_right = false;
    
        public KeyListenerTest() {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.addKeyListener((KeyListener) this);
            Thread thread = new Thread((Runnable) this);
            thread.start();
        }
    
    
        public static void main(String[] args) {
            java.awt.EventQueue.invokeLater(new Runnable() {
    
    
                @Override
                public void run() {
                    new KeyListenerTest().setVisible(true);
                }
            });
        }
    
    
        @Override
        public void run() {
            while(true) {
                System.out.println("WALK_LEFT = " + walk_left + "   |||   WALK_RIGHT = " + walk_right);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Logger.getLogger(KeyListenerTest.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    
    
        @Override
        public void keyTyped(KeyEvent e) {
        }
    
    
        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_LEFT) {
                walk_left = true;
            }
            if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
                walk_right = true;
            }
        }
    
    
        @Override
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_LEFT) {
                walk_left = false;
            }
            if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
                walk_right = false;
            }
        }
    }
    Alles anzeigen


    Das wirst du wohl gemeint haben :D.

    Aufjedenfall nochmals ein großes danke.

    MfG,
    INoNameI!

  • Ramses13
    4
    Ramses13
    Mitglied
    Reaktionen
    4
    Punkte
    164
    Beiträge
    31
    • 1. September 2011 um 21:55
    • #6

    Wie gesagt, bei Super Mario bewegen sich (normalerweise) sowieso alle möglichen Elemente. D.h. du wirst Spielfiguren in regelmäßigen (kurzen) Zeitabständen einen Animationsschritt machen lassen und danach neu zeichnen müssen. Etwas wie eine Animationsschleife ist daher sowieso notwendig und diese kann gleichzeitig auch die Mario-Figur bewegen (abhängig von der gerade gedrückten Taste, die man sich eben beim letzten keyPressed gespeichert hat).
    Das funktioniert für jedes Betriebssystem, in jeder Programmiersprache, ob Applet oder nicht, ...

  • NoxMortem
    8
    NoxMortem
    Mitglied
    Reaktionen
    13
    Punkte
    653
    Beiträge
    116
    • 13. September 2011 um 14:22
    • #7
    Zitat von Ramses13

    Wie gesagt, bei Super Mario bewegen sich (normalerweise) sowieso alle möglichen Elemente. D.h. du wirst Spielfiguren in regelmäßigen (kurzen) Zeitabständen einen Animationsschritt machen lassen und danach neu zeichnen müssen. Etwas wie eine Animationsschleife ist daher sowieso notwendig und diese kann gleichzeitig auch die Mario-Figur bewegen (abhängig von der gerade gedrückten Taste, die man sich eben beim letzten keyPressed gespeichert hat).
    Das funktioniert für jedes Betriebssystem, in jeder Programmiersprache, ob Applet oder nicht, ...


    Ist auch wohl für derartige Spiele die sauberste Variante würde ich meinen.

    Aaaaaaaaaaaaaaaaaaaaaaaaaaaaahc++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah ich hasse dich!

  • Maximilian Rupp 27. Dezember 2024 um 00:26

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Tags

  • game
  • keyevent
  • keylistener
  • spiel programmieren
  • verzögerung

Rechtliches

Impressum

Datenschutzerklärung