如何同时使用keylistener和计时器?

时间:2015-04-11 03:18:53

标签: java swing timer jframe keylistener

我正在努力制作游戏蛇,但我似乎无法让键盘控件与图形显示同时运行。如何在timer方法中实现keylistener?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Game extends JFrame {

    private static final long serialVersionUID = 7607561826495057981L;
    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getDefaultScreenDevice();
    int width = gd.getDisplayMode().getWidth();
    int height = gd.getDisplayMode().getHeight();

    private Timer timer;
    private int xCor = 400, yCor = 150;
    private int speed = 1, move = 1;
    private final int top = 0, bottom = height - 10, right = width - 10,
            left = 0;
    private boolean north = false, south = false, east = true, west = false;

    public Game() {
        setTitle("Snake");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(width, height);
        setResizable(false);
        init();
        setVisible(true);
    }

    public void init() {

        timer = new Timer(speed, new TimerListener());

        timer.start();
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.black);
        g.fillRect(xCor, yCor, 10, 10);

    }

    private class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent f) {

            if (south) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    yCor += move;
                }
            }
            if (north) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    yCor -= move;
                }
            }
            if (west) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    xCor -= move;
                }
            }

            if (east) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    xCor += move;

                }
            }
            repaint();
        }
    }

    public static void main(String[] args) {
        new Game();
    }
}

这是我的键盘控制类

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class KeyControls extends JFrame implements KeyListener {

    private static final long serialVersionUID = 2227545284640032216L;
    private boolean north = false, south = false, east = true, west = false;


    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_W && !south) {
            north = true;
            east = false;
            west = false;
            south = false;

        }
        if (i == KeyEvent.VK_S && !north) {
            north = false;
            east = false;
            west = false;
            south = true;
        }
        if (i == KeyEvent.VK_A && !west) {
            north = false;
            east = true;
            west = false;
            south = false;
        }
        if (i == KeyEvent.VK_D && !east) {
            north = false;
            east = false;
            west = true;
            south = false;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  1. 您需要将KeyControls注册为能够生成KeyEvents
  2. 的内容
  3. KeyControls无需延伸JFrame,这只会让事情变得混乱。
  4. 考虑使用键绑定API而不是KeyListener,它可以让您更好地控制组件在触发键事件之前需要具有的焦点级别。有关详细信息,请参阅How to Use Key Bindings
  5. 避免覆盖paintJFrame等顶级容器,在您的情况下,这会在更新帧时导致闪烁。而是创建一个自JPanel之类的自定义类,并覆盖它的paintComponent方法,并在那里放置自定义绘画。将Timer和键绑定封装在此类中也可能是谨慎的。有关详细信息,请查看Painting in AWT and SwingPerforming Custom Painting