按键和按下的键之间的延迟

时间:2014-06-13 17:56:45

标签: java swing animation jpanel keyevent

我注意到,在按住键的同时,键被读取之间有一个短暂的延迟。我的意思是这个;按住任何键并密切观察。模式如下:h.....hhhhhhhhhhhhhhhhhhhhhh其中.表示暂停。这很好,因为当我们输入时,尝试写一个字母会更难,例如' I&#39 ;.

但是如果我们想制作游戏怎么办?我的意思是,我们不喜欢延迟。这是我的问题。现在,让我告诉你我的代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Tutorial3{
    static MyPanel panel;
    public static void main(String[] agrs){
        createAndStartGui();
        new gameplay();
    }
    static void createAndStartGui(){
        JFrame f = new JFrame("tutorial 3");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().setPreferredSize(new Dimension(500, 300));
        f.addKeyListener(new MyKeyListener());

        panel = new MyPanel();
        f.add(panel);

        f.pack();
        f.setVisible(true);
    }
}

class gameplay {
    static String current_key = "stop";

    public gameplay(){
        begin();
    }

    void begin(){
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(Tutorial3.class.getName()).log(Level.SEVERE, null, ex);
            }
            Tutorial3.panel.user.move(current_key);
            Tutorial3.panel.repaint();
            System.out.println(current_key);
            current_key = "stop";
        }
    }

    static void key_event(){

    } 


}

class MyKeyListener extends KeyAdapter{
        public void keyPressed(KeyEvent e){
        int keyCode = e.getKeyCode();
        switch(keyCode){
            case KeyEvent.VK_UP:
                gameplay.current_key = "up";
                break;
            case KeyEvent.VK_DOWN:
                gameplay.current_key = "down";
                break;
            case KeyEvent.VK_LEFT:
                gameplay.current_key = "left";
                break;
            case KeyEvent.VK_RIGHT:
                gameplay.current_key = "right";
                break;
            default:
                gameplay.current_key = "stop";
        }
    }

}

class MyRectangle{
    int x;
    int y;
    public MyRectangle(int x, int y){
        this.x = x;
        this.y = y;
    }
    void move(String direction){
        switch (direction){
            case "up":
                this.y -= 10;
                break;
            case "down":
                this.y += 10;
                break;
            case "left":
                this.x -= 10;
                break;
            case "right":
                this.x += 10;
                break;
            default:
                break;
        }
    }
}

class MyPanel extends JPanel{
    MyRectangle user = new MyRectangle(10, 10);
    public MyPanel(){

    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g.drawRect(user.x, user.y, 10, 10);
    }

}

代码基本上在JPanel上创建一个正方形,并根据用户的输入移动它(右箭头将方形向右移动10个像素)。一切都很好,除了有一个延迟,破坏了经验。

我读过这个问题:Ignoring delay when a key is held down?但遗憾的是,它似乎只适用于JavaScript。有什么帮助吗?

我也很欣赏这类现有问题的链接(我可能错过了)。

1 个答案:

答案 0 :(得分:3)

您现在正在做的是在每100毫秒后将current_key设置为“停止”,并听取keyPressed再次指定方向。这个问题是你受到keyPressed被解雇的频率的限制。

您真正想要做的是在按下方向时开始移动,在释放按键时停止移动。

执行此操作的一种简单方法是从主循环中删除停止行,而在keyReleased中设置MyKeyListener方法,将current_key设置为“停止”。

这样,只要按下一个键,我们就会一直向那个方向移动,直到它被释放。

e.g。

class gameplay {
    static String current_key = "stop";

    public gameplay() {
        begin();
    }

    void begin() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(Tutorial3.class.getName()).log(Level.SEVERE, null, ex);
            }
            Tutorial3.panel.user.move(current_key);
            Tutorial3.panel.repaint();
            System.out.println(current_key);
//          current_key = "stop"; // only "stop" when the key is released
        }
    }

    static void key_event() {}
}

class MyKeyListener extends KeyAdapter {
    // set direction to "stop" when a key is released
    @Override
    public void keyReleased(KeyEvent e) {
        gameplay.current_key = "stop";
    }

    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        switch (keyCode) {
            case KeyEvent.VK_UP:
                gameplay.current_key = "up";
                break;
            case KeyEvent.VK_DOWN:
                gameplay.current_key = "down";
                break;
            case KeyEvent.VK_LEFT:
                gameplay.current_key = "left";
                break;
            case KeyEvent.VK_RIGHT:
                gameplay.current_key = "right";
                break;
            default:
                gameplay.current_key = "stop";
        }
    }
}