Java的KeyEvent的方形机芯 [英] Java KeyEvent square movement
本文介绍了Java的KeyEvent的方形机芯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一块code,其中当任何箭头键是pressed的KeyEvent被触发。这反过来又导致广场在屏幕上移动。
现在我注意到,当我preSS按住键,方移动,但开始移动后续动作后的时间很长,如果你明白我的意思?我怎么会去减少这个时间呢?
谢谢!
进口java.awt中的*。
进口的javax.swing *。
进口squarequest.sprites *。
java.awt.event中导入*。
公共类的GamePanel继承JPanel { 私人最终诠释HEIGHT = 400;
私人最终诠释WIDTH = 600;
私人方方;
私人圈圈;
公众的GamePanel(){ addKeyListener(新DirectionListener()); 的setBackground(Color.white);
集preferredSize(新尺寸(宽,高));
setFocusable(真); 方=新广场();
} 公共无效的paintComponent(图形G){
super.paintComponent方法(G);
square.display(G); } 公共类DirectionListener实现的KeyListener {
@覆盖
公共无效的keyReleased(KeyEvent的事件){} @覆盖
公共无效的keyTyped(KeyEvent的事件){}
@覆盖
公共无效键pressed(KeyEvent的事件){ 开关(event.getKey code()){ 案例KeyEvent.VK_UP: square.moveUp();
打破;
案例KeyEvent.VK_DOWN: square.moveDown();
打破;
案例KeyEvent.VK_LEFT: square.moveLeft();
打破;
案例KeyEvent.VK_RIGHT: square.moveRight();
打破;
}
重绘(); }
}
}
解决方案
- 使用一个Swing定时器的实际运动。
- 启动重点preSS定时
- 停在按键释放。
- 或者更好的是,保持定时器一直在运行,但只有基于地图,一个拥有枚举方向键和一个布尔值的状态移动精灵。
- 最好使用键绑定,而不是KeyListeners。
例如,
进口java.awt中的*。
进口的javax.swing *。
//!进口squarequest.sprites *。
java.awt.event中导入*。
进口java.util.EnumMap中;
进口的java.util.HashMap;
进口的java.util.Map;公共类的GamePanel继承JPanel {
私有静态最终诠释ANIMATION_DELAY = 15;
私人最终诠释HEIGHT = 400;
私人最终诠释WIDTH = 600;
私人方方;
私人EnumMap的<方向,布尔> dirMap =新的EnumMap的<>(Direction.class);
私人地图<整数,方向> keyToDir =新的HashMap<>();
//!私人圈圈;
私人定时器animationTimer; 公众的GamePanel(){
为(方向DIR:Direction.values()){
dirMap.put(DIR,Boolean.FALSE);
}
keyToDir.put(KeyEvent.VK_UP,Direction.UP);
keyToDir.put(KeyEvent.VK_DOWN,Direction.DOWN);
keyToDir.put(KeyEvent.VK_LEFT,Direction.LEFT);
keyToDir.put(KeyEvent.VK_RIGHT,Direction.RIGHT);
//! addKeyListener(新DirectionListener());
setKeyBindings();
的setBackground(Color.white);
集preferredSize(新尺寸(宽,高));
setFocusable(真);
方=新广场();
animationTimer =新的Timer(ANIMATION_DELAY,新AnimationListener());
animationTimer.start();
} 私人无效setKeyBindings(){
INT条件= WHEN_IN_FOCUSED_WINDOW;
最终的InputMap InputMap中= getInputMap中(条件);
最终的ActionMap ActionMap中= getActionMap();
布尔[]键pressed = {真,假};
对于(整数键code:keyToDir.keySet()){
方向DIR = keyToDir.get(键code);
对于(布尔安其preSS:关键pressed){
布尔onKeyRelease =安其preSS!; //使绑定清楚如何工作
的KeyStroke keyStroke的= KeyStroke.getKeyStroke(键code,0,
onKeyRelease);
对象键= keyStroke.toString();
inputMap.put(击键键);
actionMap.put(关键,新KeyBindingsAction(DIR,安其preSS));
}
}
} 公共无效的paintComponent(图形G){
super.paintComponent方法(G);
square.display(G);
} //公共类DirectionListener实现的KeyListener {
// @覆盖
//公共无效调用keyReleased(KeyEvent的事件){
// INT键code = event.getKey code();
//如果(keyToDir.keySet()。包括(关键code)){
//方向DIR = keyToDir.get(键code);
// dirMap.put(DIR,FALSE);
//}
//}
//
// @覆盖
//公共无效的keyTyped(KeyEvent的事件){
//}
//
// @覆盖
//公共无效键pressed(KeyEvent的事件){
// INT键code = event.getKey code();
//如果(keyToDir.keySet()。包括(关键code)){
//方向DIR = keyToDir.get(键code);
// dirMap.put(DIR,真);
//}
//}
//} 私有类AnimationListener实现的ActionListener {
@覆盖
公共无效的actionPerformed(ActionEvent的EVT){
布尔重绘= FALSE;
为(方向DIR:Direction.values()){
如果(dirMap.get(DIR)){
square.move(DIR);
重绘= TRUE;
}
}
如果(重绘){
重绘();
}
}
} 私有类KeyBindingsAction扩展AbstractAction {
私人方向DIR;
布尔pressed; 公共KeyBindingsAction(方向DIR,布尔pressed){
this.dir = DIR;
这pressed = pressed。
} @覆盖
公共无效的actionPerformed(ActionEvent的EVT){
dirMap.put(DIR,pressed);
}
} 私有静态无效createAndShowGUI(){
的GamePanel的GamePanel =新的GamePanel();
JFrame的帧=新的JFrame(的GamePanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane()加(的GamePanel)。
frame.pack();
frame.setLocationRelativeTo(NULL);
frame.setVisible(真);
gamePanel.requestFocusInWindow();
} 公共静态无效的主要(字串[] args){
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
createAndShowGUI();
}
});
}
}枚举方向{
向上(0,-1),下(0,1),左(-1,0),RIGHT(1,0);
私人诠释incrX;
私人诠释incrY; 私营方向(INT incrX,诠释incrY){
this.incrX = incrX;
this.incrY = incrY;
} 公众诠释getIncrX(){
返回incrX;
} 公众诠释getIncrY(){
返回incrY;
}
}类方形{
私人INT X = 0;
私人INT Y = 0;
私人INT W = 20;
私人INT H =瓦;
私人INT步= 1;
私人色彩的颜色= Color.red;
私人颜色填充颜色=新的色彩(255,150,150);
私人行程行程=的新BasicStroke(3F,BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND); 公共无效显示(图形G){
Graphics2D的G2D =(Graphics2D的)g.create();
g2d.setColor(填充颜色);
g2d.fillRect(X,Y,W,H);
g2d.setStroke(中风);
g2d.setColor(颜色);
g2d.drawRect(X,Y,W,H);
g2d.dispose();
} 公共无效setStep(INT步骤){
this.step =步骤;
} 公共无效移动(方向DIR){
X + =步* dir.getIncrX();
Y + =步* dir.getIncrY();
}//公共无效MoveRight的(){
// X ++;
//}
//
//公共无效moveLeft(){
// X - ;
//}
//
//公共无效为moveUp(){
// y--;
//}
//
//公共无效下移(){
//ÿ++;
//}
}
I have a piece of code in which a KeyEvent is triggered when any of the arrow keys are pressed. This in turn causes a square to move across the screen.
Now I've noticed that when I press and hold the key, the square moves but the time after the initial movement to the subsequent movements is quite long if you understand what I mean? How would I go about diminishing this time?
Thanks!
import java.awt.*;
import javax.swing.*;
import squarequest.sprites.*;
import java.awt.event.*;
public class GamePanel extends JPanel{
private final int HEIGHT = 400;
private final int WIDTH = 600;
private Square square;
private Circle circle;
public GamePanel(){
addKeyListener(new DirectionListener());
setBackground (Color.white);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
square = new Square();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
square.display(g);
}
public class DirectionListener implements KeyListener{
@Override
public void keyReleased(KeyEvent event) {}
@Override
public void keyTyped(KeyEvent event) {}
@Override
public void keyPressed(KeyEvent event) {
switch(event.getKeyCode()){
case KeyEvent.VK_UP:
square.moveUp();
break;
case KeyEvent.VK_DOWN:
square.moveDown();
break;
case KeyEvent.VK_LEFT:
square.moveLeft();
break;
case KeyEvent.VK_RIGHT:
square.moveRight();
break;
}
repaint();
}
}
}
解决方案
- Use a Swing Timer for the actual movement.
- Start the Timer on key press
- Stop it on key release.
- Or better still, keep the timer always running, but only moving the sprite based on the state of a map, one that holds a Direction enum key and a Boolean value.
- Better to use key bindings rather than KeyListeners.
e.g.,
import java.awt.*;
import javax.swing.*;
//!! import squarequest.sprites.*;
import java.awt.event.*;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class GamePanel extends JPanel {
private static final int ANIMATION_DELAY = 15;
private final int HEIGHT = 400;
private final int WIDTH = 600;
private Square square;
private EnumMap<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
private Map<Integer, Direction> keyToDir = new HashMap<>();
// !! private Circle circle;
private Timer animationTimer;
public GamePanel() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.FALSE);
}
keyToDir.put(KeyEvent.VK_UP, Direction.UP);
keyToDir.put(KeyEvent.VK_DOWN, Direction.DOWN);
keyToDir.put(KeyEvent.VK_LEFT, Direction.LEFT);
keyToDir.put(KeyEvent.VK_RIGHT, Direction.RIGHT);
// !! addKeyListener(new DirectionListener());
setKeyBindings();
setBackground(Color.white);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
square = new Square();
animationTimer = new Timer(ANIMATION_DELAY, new AnimationListener());
animationTimer.start();
}
private void setKeyBindings() {
int condition = WHEN_IN_FOCUSED_WINDOW;
final InputMap inputMap = getInputMap(condition);
final ActionMap actionMap = getActionMap();
boolean[] keyPressed = { true, false };
for (Integer keyCode : keyToDir.keySet()) {
Direction dir = keyToDir.get(keyCode);
for (boolean onKeyPress : keyPressed) {
boolean onKeyRelease = !onKeyPress; // to make it clear how bindings work
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, 0,
onKeyRelease);
Object key = keyStroke.toString();
inputMap.put(keyStroke, key);
actionMap.put(key, new KeyBindingsAction(dir, onKeyPress));
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
square.display(g);
}
// public class DirectionListener implements KeyListener {
// @Override
// public void keyReleased(KeyEvent event) {
// int keyCode = event.getKeyCode();
// if (keyToDir.keySet().contains(keyCode)) {
// Direction dir = keyToDir.get(keyCode);
// dirMap.put(dir, false);
// }
// }
//
// @Override
// public void keyTyped(KeyEvent event) {
// }
//
// @Override
// public void keyPressed(KeyEvent event) {
// int keyCode = event.getKeyCode();
// if (keyToDir.keySet().contains(keyCode)) {
// Direction dir = keyToDir.get(keyCode);
// dirMap.put(dir, true);
// }
// }
// }
private class AnimationListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent evt) {
boolean repaint = false;
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
square.move(dir);
repaint = true;
}
}
if (repaint) {
repaint();
}
}
}
private class KeyBindingsAction extends AbstractAction {
private Direction dir;
boolean pressed;
public KeyBindingsAction(Direction dir, boolean pressed) {
this.dir = dir;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent evt) {
dirMap.put(dir, pressed);
}
}
private static void createAndShowGUI() {
GamePanel gamePanel = new GamePanel();
JFrame frame = new JFrame("GamePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(gamePanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
gamePanel.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
enum Direction {
UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0);
private int incrX;
private int incrY;
private Direction(int incrX, int incrY) {
this.incrX = incrX;
this.incrY = incrY;
}
public int getIncrX() {
return incrX;
}
public int getIncrY() {
return incrY;
}
}
class Square {
private int x = 0;
private int y = 0;
private int w = 20;
private int h = w;
private int step = 1;
private Color color = Color.red;
private Color fillColor = new Color(255, 150, 150);
private Stroke stroke = new BasicStroke(3f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND);
public void display(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(fillColor);
g2d.fillRect(x, y, w, h);
g2d.setStroke(stroke);
g2d.setColor(color);
g2d.drawRect(x, y, w, h);
g2d.dispose();
}
public void setStep(int step) {
this.step = step;
}
public void move(Direction dir) {
x += step * dir.getIncrX();
y += step * dir.getIncrY();
}
// public void moveRight() {
// x++;
// }
//
// public void moveLeft() {
// x--;
// }
//
// public void moveUp() {
// y--;
// }
//
// public void moveDown() {
// y++;
// }
}
这篇关于Java的KeyEvent的方形机芯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文