【问题标题】:how to use keylistener and timer at the same time?如何同时使用 keylistener 和 timer?
【发布时间】:2015-04-11 03:18:53
【问题描述】:

我正在尝试制作游戏蛇,但我似乎无法让键盘控件与图形显示同时运行。如何在 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;
        }
    }
}

【问题讨论】:

    标签: java swing timer jframe keylistener


    【解决方案1】:
    1. 您需要将KeyControls 注册到能够生成KeyEvents 的东西上
    2. KeyControls 没有必要从 JFrame 扩展,这只会让事情变得混乱。
    3. 考虑使用键绑定 API 而不是KeyListener,它可以让您更好地控制组件在触发键事件之前需要拥有的焦点级别。详情请见How to Use Key Bindings
    4. 避免覆盖 paint 的顶级容器,如 JFrame,在您的情况下,这将在更新框架时导致闪烁。相反,创建一个扩展自 JPanel 之类的自定义类并覆盖它的 paintComponent 方法并将自定义绘画放置在那里。在这个类中封装Timer 和键绑定可能是谨慎的。查看Painting in AWT and SwingPerforming Custom Painting 了解更多详情

    【讨论】:

    • 对我应该在哪里注册 KeyControls 有什么建议吗?
    • 好吧,KeyListener 需要添加到任何能够接收键盘焦点的组件中,这通常是不鼓励它的原因。键绑定只能绑定到从 JComponent 扩展的组件,但允许您定义组件需要的焦点级别以触发键事件,这使我回到第 4 点。创建一个从 JPanel 之类的扩展的自定义组件,将所有逻辑移到它上面并将键绑定绑定到它
    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 2016-09-21
    • 2016-01-27
    • 2012-06-08
    • 1970-01-01
    • 2023-03-15
    • 2018-12-28
    相关资源
    最近更新 更多