gpt4 book ai didi

Java KeyListener 断断续续

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:50:57 29 4
gpt4 key购买 nike

我正在用 Java 制作一个非常简单的乒乓球游戏,并且我正在使用 KeyListener 进行此操作。我想要它,所以当用户按下键盘上的向右或向左键时,乒乓 block 会朝那个方向移动。这是一个足够简单的任务,但我发现当用户按住键时, block 移动一次,停止一小段时间,然后继续移动直到用户释放键。我注意到当您尝试按住计算机上的字母键时会发生这种情况。如果我尝试按住“a”键,计算机将执行:

a [pause] aaaaaaaaaaaaaaaa

有什么办法可以消除这种卡顿,因为它妨碍了我的小游戏的流畅游戏。快速修复将不胜感激。

最佳答案

I originally had an answer about Key Bindings, but after a little testing I found that they still had the same stutter problem.

不要依赖操作系统的重复率。每个平台可能不同,用户也可以自定义。

而是使用计时器来安排事件。您在 keyPressed 上启动计时器并在 keyReleased 上停止计时器。

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.Map;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.*;

public class KeyboardAnimation implements ActionListener
{
private final static String PRESSED = "pressed ";
private final static String RELEASED = "released ";
private final static Point RELEASED_POINT = new Point(0, 0);

private JComponent component;
private Timer timer;
private Map<String, Point> pressedKeys = new HashMap<String, Point>();

public KeyboardAnimation(JComponent component, int delay)
{
this.component = component;

timer = new Timer(delay, this);
timer.setInitialDelay( 0 );
}

public void addAction(String keyStroke, int deltaX, int deltaY)
{
// InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
InputMap inputMap = component.getInputMap();
ActionMap actionMap = component.getActionMap();

String pressedKey = PRESSED + keyStroke;
KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke( pressedKey );
Action pressedAction = new AnimationAction(keyStroke, new Point(deltaX, deltaY));
inputMap.put(pressedKeyStroke, pressedKey);
actionMap.put(pressedKey, pressedAction);

String releasedKey = RELEASED + keyStroke;
KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke( releasedKey );
Action releasedAction = new AnimationAction(keyStroke, RELEASED_POINT);
inputMap.put(releasedKeyStroke, releasedKey);
actionMap.put(releasedKey, releasedAction);
}

private void handleKeyEvent(String keyStroke, Point moveDelta)
{
// Keep track of which keys are pressed

if (RELEASED_POINT == moveDelta)
pressedKeys.remove( keyStroke );
else
pressedKeys.put(keyStroke, moveDelta);

// Start the Timer when the first key is pressed

if (pressedKeys.size() == 1)
{
timer.start();
}

// Stop the Timer when all keys have been released

if (pressedKeys.size() == 0)
{
timer.stop();
}
}

// Invoked when the Timer fires

public void actionPerformed(ActionEvent e)
{
moveComponent();
}

// Move the component to its new location

private void moveComponent()
{
int componentWidth = component.getSize().width;
int componentHeight = component.getSize().height;

Dimension parentSize = component.getParent().getSize();
int parentWidth = parentSize.width;
int parentHeight = parentSize.height;

// Calculate new move

int deltaX = 0;
int deltaY = 0;

for (Point delta : pressedKeys.values())
{
deltaX += delta.x;
deltaY += delta.y;
}


// Determine next X position

int nextX = Math.max(component.getLocation().x + deltaX, 0);

if ( nextX + componentWidth > parentWidth)
{
nextX = parentWidth - componentWidth;
}

// Determine next Y position

int nextY = Math.max(component.getLocation().y + deltaY, 0);

if ( nextY + componentHeight > parentHeight)
{
nextY = parentHeight - componentHeight;
}

// Move the component

component.setLocation(nextX, nextY);
}

private class AnimationAction extends AbstractAction implements ActionListener
{
private Point moveDelta;

public AnimationAction(String keyStroke, Point moveDelta)
{
super(PRESSED + keyStroke);
putValue(ACTION_COMMAND_KEY, keyStroke);

this.moveDelta = moveDelta;
}

public void actionPerformed(ActionEvent e)
{
handleKeyEvent((String)getValue(ACTION_COMMAND_KEY), moveDelta);
}
}

public static void main(String[] args)
{
JPanel contentPane = new JPanel();
contentPane.setLayout( null );

Icon dukeIcon = null;

try
{
dukeIcon = new ImageIcon( "dukewavered.gif" );
// dukeIcon = new ImageIcon( ImageIO.read( new URL("http://duke.kenai.com/iconSized/duke4.gif") ) );
}
catch(Exception e)
{
System.out.println(e);
}

JLabel duke = new JLabel( dukeIcon );
duke.setSize( duke.getPreferredSize() );
duke.setLocation(100, 100);
contentPane.add( duke );

KeyboardAnimation navigation = new KeyboardAnimation(duke, 24);
navigation.addAction("LEFT", -3, 0);
navigation.addAction("RIGHT", 3, 0);
navigation.addAction("UP", 0, -3);
navigation.addAction("DOWN", 0, 3);

navigation.addAction("A", -5, 0);
navigation.addAction("S", 5, 0);
navigation.addAction("Z", 0, -5);
navigation.addAction("X", 0, 5);
navigation.addAction("V", 5, 5);

JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// frame.getContentPane().add(new JTextField(), BorderLayout.SOUTH);
frame.getContentPane().add(contentPane);
frame.setSize(600, 600);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}

}

此代码已在事件顺序为 keyPressed、keyPressed、keyPressed...keyReleased 的 Windows 上进行了测试。

但是,我认为在 Mac(或 Unix)上事件的顺序是 keyPressed、keyReleased、keyPressed、keyReleased...所以我不确定这段代码是否会比您当前的代码更好。

关于Java KeyListener 断断续续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16328946/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com