java某些键-事件组合未触发
在创建一个简单的子弹地狱游戏时,我遇到了一个键绑定问题
我将提供一些与键绑定相关的游戏机制的背景信息。在这个二维游戏中,您的角色可以通过按住非numpad箭头组合(分别为北、东和西南方向的上、左和下+右)以恒定速度在所有八个方向移动您还可以按住shift键并结合前面提到的任意组合键,以相同的方向移动,但速度较慢
下面是遇到此问题的程序示例的代码。本例中的问题与相对较大的bullet hell程序中的问题相同
/*
* 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不接受关键事件的问题
这是Windows7(我正在使用的操作系统)的自然行为,这恰好是有问题的。在普通文本框中使用shift键和字母键时,也会看到相同的行为
现在要问的是,有没有办法绕过操作系统的按键事件处理,以便按住shift键的同时按下shift键将触发按住shift键的事件
共 (0) 个答案