Java的KeyEvent的方形机芯 [英] Java KeyEvent square movement

查看:163
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆