Java 某些关键事件组合不触发
在创建一个简单的子弹地狱游戏时,我遇到了一个键绑定问题 我将提供一些与键绑定相关的游戏机制的背景信息。在这个二维游戏中,您的角色可以在所有八个方向上以恒定的速度移动,方法是分别按住北、东和西南方向的上、左、下+右箭头组合键。您还可以按住shift键并结合前面提到的任意组合键,以相同的方向移动,但速度较慢 下面是遇到此问题的程序示例的代码。本例中的问题与相对较大的bullet hell程序中的问题相同Java 某些关键事件组合不触发,java,key-bindings,Java,Key Bindings,在创建一个简单的子弹地狱游戏时,我遇到了一个键绑定问题 我将提供一些与键绑定相关的游戏机制的背景信息。在这个二维游戏中,您的角色可以在所有八个方向上以恒定的速度移动,方法是分别按住北、东和西南方向的上、左、下+右箭头组合键。您还可以按住shift键并结合前面提到的任意组合键,以相同的方向移动,但速度较慢 下面是遇到此问题的程序示例的代码。本例中的问题与相对较大的bullet hell程序中的问题相同 /* * Keybind feedback, by Nematodes */ import
/*
* Keybind feedback, by Nematodes
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class keybindFeedback extends JFrame
{
private static final long serialVersionUID = 0L;
JPanel framePanel = new JPanel();
private static Action moveUpTrue;
private static Action moveUpFalse;
private static Action moveUpFocusedTrue;
private static Action moveUpFocusedFalse;
public static void main(String[] args)
{
keybindFeedback createFrame = new keybindFeedback();
createFrame.constructFrame();
}
public void constructFrame()
{
// Construct the frame and frame components
setTitle("Keybind Feedback");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
getContentPane().setLayout(new GridBagLayout());
setVisible(true);
GridBagConstraints gridConstraints;
// This JPanel only exists so that it is easier to focus on the window, so that keyevents will register
gridConstraints = new GridBagConstraints();
gridConstraints.gridx = 0;
gridConstraints.gridy = 0;
framePanel.setBackground(Color.BLACK);
framePanel.setPreferredSize(new Dimension(700, 700));
getContentPane().add(framePanel, gridConstraints);
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds((int) (0.5 * (screenSize.width - getWidth())),
(int) (0.5 * (screenSize.height - getHeight())), getWidth(), getHeight());
// Initialize and map all of the keybinds
moveUpTrue = new MoveUpTrue();
moveUpFalse = new MoveUpFalse();
moveUpFocusedTrue = new MoveUpFocusedTrue();
moveUpFocusedFalse = new MoveUpFocusedFalse();
// Code spacing for placing things in the input map is only wonky in this code-formatting block due to strange spacing issues in stackoverflow
framePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "doMoveUpTrue");
framePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released UP"), "doMoveUpFalse");
framePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("shift UP"), "doMoveUpFocusedTrue");
framePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("shift released UP"), "doMoveUpFocusedFalse");
framePanel.getActionMap().put("doMoveUpTrue", moveUpTrue);
framePanel.getActionMap().put("doMoveUpFalse", moveUpFalse);
framePanel.getActionMap().put("doMoveUpFocusedTrue", moveUpFocusedTrue);
framePanel.getActionMap().put("doMoveUpFocusedFalse", moveUpFocusedFalse);
}
// Keybind actions for up, up released, shift-up, and shift-up released
class MoveUpTrue extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Up");
}
}
class MoveUpFalse extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Up released");
}
}
class MoveUpFocusedTrue extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Shift-up");
}
}
class MoveUpFocusedFalse extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Shift-up released");
}
}
}
如果您按住up键几秒钟,然后将其释放,程序将触发大量向上按下的事件,然后触发向上释放的事件。在游戏中,这将以标准速度向上移动
如果按shift,然后按up几秒钟,然后释放up,程序将触发大量按下shift up的事件,然后触发一个按下shift up的释放事件。必须先按下Shift键,如果要使其工作,则必须最后松开Shift键。在游戏中,这将以较慢的速度向上移动
如果按shift,然后按up几秒钟,然后释放shift,然后在释放shift几秒钟后释放up,程序将首先触发大量按下shift的事件,然后触发按下的事件,最后触发一个向上释放的事件。在游戏中,这将是以较慢的速度向上移动,然后决定以较快的速度向上移动
如果您按up几秒钟,然后按shift,程序将首先触发大量向上按下的事件,然后在按住shift时不触发任何事件。预期的行为是,在按住shift键的同时按下shift键,它应该开始触发shift up pressed事件,而不是up pressed事件。如果玩家以标准速度向上移动,然后想要以较慢的速度移动,这将适用于游戏中。
从上一个场景继续:
如果您在按住shift键的同时释放shift键,则尽管您现在只按下了up键,但它不会触发任何up-pressed事件。如果您现在释放up,它仍然会触发up-released事件,即使它永远不会触发任何up-pressed事件。
如果您在按住shift键的同时释放up,它将触发一个shift up released事件,即使它从未触发任何按下shift up键的事件
这不是我键盘上的键翻转问题,因为它可以组合按下所有这些键。
这不是java不接受关键事件的问题。
这是我使用的Windows 7操作系统的自然行为,这恰好是有问题的。在普通文本框中使用shift键和字母键时,也会看到相同的行为
现在问一下,有没有办法绕过操作系统的按键事件处理,以便按住shift键的同时按下shift键将触发shift-up按下事件?根据我的有限测试,除非在按住shift键之前按下shift键,否则shift+up绑定将不会触发…另请参阅。