java中检测多个按键

2024-02-13

我正在尝试创建一个平台,但我一直致力于如何同时检测多个按键。例如,如果我使用运行键并向前运行,然后我按下跳跃键,游戏仍然需要知道运行键是否被按下


这比我平常做的要复杂一些。通常我会允许每个Action直接改变游戏状态。

这个例子展示了如何使用键绑定 http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html用于监控某些按键的按下/释放并从中央池中添加/删除它们的 API。

使用这个API的主要原因是它克服了KeyListener当涉及到焦点上下文时。只要窗口具有焦点,此示例就会检索按键通知。

public class TestMultyKeyPress {

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

    public TestMultyKeyPress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new KeyPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class KeyPane extends JPanel implements KeyManager {

        private TrianglePane upPane;
        private TrianglePane downPane;
        private TrianglePane leftPane;
        private TrianglePane rightPane;
        private List<Integer> keysList = new ArrayList<>(25);

        public KeyPane() {
            setLayout(new GridBagLayout());
            upPane = new TrianglePane(0);
            leftPane = new TrianglePane(1);
            downPane = new TrianglePane(2);
            rightPane = new TrianglePane(3);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            add(upPane, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            add(leftPane, gbc);
            gbc.gridx += 2;
            add(rightPane, gbc);

            gbc.gridx = 1;
            gbc.gridy++;
            add(downPane, gbc);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "KeyPressed.Left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "KeyPressed.Right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "KeyPressed.Up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "KeyPressed.Down");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "KeyReleased.Left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "KeyReleased.Right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "KeyReleased.Up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "KeyReleased.Down");

            am.put("KeyPressed.Left", new KeyAction(KeyEvent.VK_LEFT, false, this));
            am.put("KeyPressed.Right", new KeyAction(KeyEvent.VK_RIGHT, false, this));
            am.put("KeyPressed.Up", new KeyAction(KeyEvent.VK_UP, false, this));
            am.put("KeyPressed.Down", new KeyAction(KeyEvent.VK_DOWN, false, this));

            am.put("KeyReleased.Left", new KeyAction(KeyEvent.VK_LEFT, true, this));
            am.put("KeyReleased.Right", new KeyAction(KeyEvent.VK_RIGHT, true, this));
            am.put("KeyReleased.Up", new KeyAction(KeyEvent.VK_UP, true, this));
            am.put("KeyReleased.Down", new KeyAction(KeyEvent.VK_DOWN, true, this));

        }

        @Override
        public void keyPressed(int keyCode) {
            if (!keysList.contains(keyCode)) {
                keysList.add(new Integer(keyCode));
                updateKeyState();
            }
        }

        @Override
        public void keyReleased(int keyCode) {
            keysList.remove(new Integer(keyCode));
            updateKeyState();
        }

        public void updateKeyState() {
            upPane.setActive(keysList.contains(KeyEvent.VK_UP));
            downPane.setActive(keysList.contains(KeyEvent.VK_DOWN));
            leftPane.setActive(keysList.contains(KeyEvent.VK_LEFT));
            rightPane.setActive(keysList.contains(KeyEvent.VK_RIGHT));
        }

    }

    public interface KeyManager {

        public void keyPressed(int keyCode);

        public void keyReleased(int keyCode);

    }

    public class KeyAction extends AbstractAction {

        private int keyCode;
        private boolean released;
        private KeyManager manager;

        public KeyAction(int keyCode, boolean released, KeyManager manager) {
            this.keyCode = keyCode;
            this.released = released;
            this.manager = manager;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (released) {
                manager.keyReleased(keyCode);
            } else {
                manager.keyPressed(keyCode);
            }
        }

    }

    public class TrianglePane extends JPanel {

        private boolean active;
        private TriangleShape shape;

        public TrianglePane(int direction) {

            shape = new TriangleShape(20);
            AffineTransform at = null;
            switch (direction) {
                case 0:
                    at = AffineTransform.getRotateInstance(Math.toRadians(-90), 10, 10); // UP
                    break;
                case 1:
                    at = AffineTransform.getRotateInstance(Math.toRadians(180), 10, 10); // UP
                    break;
                case 2:
                    at = AffineTransform.getRotateInstance(Math.toRadians(90), 10, 10); // UP
                    break;
                case 3:
                    at = AffineTransform.getRotateInstance(Math.toRadians(0)); // UP
                    break;
            }
            shape.transform(at);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(20, 20);
        }

        public void setActive(boolean value) {
            if (active != value) {
                this.active = value;
                repaint();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - shape.getBounds().width) / 2;
            int y = (getHeight() - shape.getBounds().height) / 2;
            if (active) {
                g2d.setColor(Color.BLACK);
            } else {
                g2d.setColor(Color.GRAY);
            }
            g2d.fill(shape);
        }

    }

    public class TriangleShape extends Path2D.Float {

        public TriangleShape(int size) {
            moveTo(1, 1);
            lineTo(size - 1, (size - 1) / 2);
            lineTo(1, size - 1);
            closePath();
        }

    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中检测多个按键 的相关文章

  • 热重载在docker中运行的java程序

    我开发了一个java程序 应该在docker中运行 然而 我在调试docker中运行的java程序时遇到了很多痛苦 我在网上搜索 一些教程提出了像 spring dev tools 这样的工具 因为我的java程序是基于spring boo
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • jdbc4.MySQLSyntaxErrorException:数据库中不存在表

    我正在使用 SpringBoot 开发一个网络应用程序 这是我的application properties文件来指定访问数据库的凭据 spring datasource driverClassName com mysql jdbc Dri
  • 如何在jsp代码中导入java库?

    我有以下jsp代码 我想添加 java io 等库 我怎样才能做到这一点
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • 如何将文件透明地传输到浏览器?

    受控环境 IE8 IIS 7 ColdFusion 当从 IE 发出指向媒体文件 例如 mp3 mpeg 等 的 GET 请求时 浏览器将启动关联的应用程序 Window Media Player 我猜测 IIS 提供文件的方式允许应用程序
  • 使用 Flyway 和 Hibernate 的 hbm2ddl 在应用程序的生命周期中管理数据库模式

    我正在开发 Spring Hibernate MySql 应用程序 该应用程序尚未投入生产 我目前使用 Hibernatehbm2ddl该功能对于管理域上的更改非常方便 我也打算用Flyway用于数据库迁移 在未来的某个时候 该应用程序将首
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • 运行 Jar 文件时出现问题

    我已将 java 项目编译成 Jar 文件 但运行它时遇到问题 当我跑步时 java jar myJar jar 我收到以下错误 Could not find the main class myClass 类文件不在 jar 的根目录中 因
  • Android JNI C 简单追加函数

    我想制作一个简单的函数 返回两个字符串的值 基本上 java public native String getAppendedString String name c jstring Java com example hellojni He
  • Java - 不要用 bufferedwriter 覆盖

    我有一个程序可以将人员添加到数组列表中 我想做的是将这些人也添加到文本文件中 但程序会覆盖第一行 因此这些人会被删除 如何告诉编译器在下一个空闲行写入 import java io import java util import javax
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • 将 JTextArea 内容写入文件

    我在 Java Swing 中有一个 JTextArea 和一个 提交 按钮 需要将textarea的内容写入一个带有换行符的文件中 我得到的输出是这样的 它被写为文件中的一个字符串 try BufferedWriter fileOut n
  • android Accessibility-service 突然停止触发事件

    我有一个 AccessibilityService 工作正常 但由于开发过程中的某些原因它停止工作 我似乎找不到这个原因 请看一下我的代码并告诉我为什么它不起作用 public class MyServicee extends Access
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp
  • java8 Collectors.toMap() 限制?

    我正在尝试使用java8Collectors toMap on a Stream of ZipEntry 这可能不是最好的想法 因为在处理过程中可能会发生异常 但我想这应该是可能的 我现在收到一个我不明白的编译错误 我猜是类型推理引擎 这是
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item

随机推荐