Java 如何使用键绑定使矩形在屏幕上移动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20844144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:44:24  来源:igfitidea点击:

How do I make a rectangle move across the screen with key bindings?

javaswinggraphicsawtpaint

提问by user3146998

The game I'm trying to create is snake and so far I've figured out how to use paint(Graphics g)a bit of JPanel, mouse listener and now I'm trying to create a rectangle that will move across the screen and use key bindings or key listener, but I have no idea how I should go about this.

我正在尝试创建的游戏是蛇,到目前为止我已经想出了如何使用paint(Graphics g)一些JPanel鼠标侦听器,现在我正在尝试创建一个将在屏幕上移动并使用键绑定或键侦听器的矩形,但我不知道该怎么做。

Here's my code so far, it has 2 parts. The first part is called snake2because if I don't know what I'm doing I make the same program with different things. Snakeused frame, but Snake2uses JPanel(looks better…)

到目前为止,这是我的代码,它有 2 个部分。第一部分被称为snake2是因为如果我不知道我在做什么,我会用不同的东西制作相同的程序。Snake使用框架,但Snake2使用JPanel(看起来更好......)

    import java.awt.*;

    //required for MouseListener
    import java.awt.event.*;

    //requied for Graohics
    import java.applet.*;
    import javax.swing.*;

    public class Snake2 extends JPanel
    {
      private Rectangle sampleObject;

      public Snake2()
      {
         addMouseListener(new MouseListener());

      }


      /* create background */
      public void paint (Graphics g)
      {
        Font angel = new Font("Angelic War", Font.BOLD, 60);
        Font ith = new Font("Ithorn?t", Font.BOLD, 78);

        setBackground(Color.darkGray);
        g.setColor(Color.darkGray);
        g.fillRect(0,0,700,850);
        g.setColor(Color.gray);
        g.fillRect(50,150,600,650);
        g.setColor(Color.white);
        g.drawRect(50,150,600,650);

        g.drawString("Quit",52,116);
        g.drawRect(50,100,30,20);

        //g.setFont(angel);
        //g.drawString("SNAKE",300,70);
        g.setFont(ith);
        g.drawString("SNAKE",280,90);  
      }

      public void sprite (int x, int y, Graphics g){
        g.setColor(Color.white);
        g.fillRect(300,200,10,10);
      }

      public void start (int x, int y, Graphics g){
        g.setColor(Color.white);
        g.drawString("START GAME",300,425);
      }
    }


    /* Tracks where mouse is clicked */
    class MouseListener extends MouseAdapter
    {
      public void mouseReleased(MouseEvent me)
      {
        if (me.getX() >= 50 && me.getX() <= 80 && me.getY() >= 100 && me.getY() <= 120)
        {
          System.exit(0);
        }

          String str="Mouse Released at "+me.getX()+","+me.getY();
          System.out.println(str);
      }
    }

And the second part is:

第二部分是:

    import javax.swing.JFrame;
    import java.awt.Dimension;

    public class SnakeDisplay
    {

      public static void main ( String [ ] arguments )
      {   
        JFrame frame = new JFrame ( "Snake" );
        Snake2 panel = new Snake2 ( );


        frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
        frame.add ( panel );
        frame.setContentPane ( panel );

        frame.setPreferredSize ( new Dimension ( 700, 850 ) );
        //frame.setLocationRelativeTo ( null );
        frame.setVisible ( true );
        frame.pack ( );     
      }
    }

采纳答案by Paul Samsotha

  1. You should override paintComponentin your JPaneland call super.paintComponent(g)in it.
  2. See How to Use Key Bindings tutorial. Key bindings are preffered in this case rather than a KeyListener
  3. pack()thensetVisible()
  4. You should set global variables for x anf y location, so they can be accessed from within your Action. Then in your actions, increment your x or y and repaint
  1. 你应该覆盖paintComponent你的JPanel并调用super.paintComponent(g)它。
  2. 请参阅如何使用键绑定教程。在这种情况下优先使用键绑定而不是KeyListener
  3. pack()然后setVisible()
  4. 您应该为 x anf y 位置设置全局变量,以便可以从您的Action. 然后在您的操作中,增加您的 x 或 y 并重新绘制

Try running this example

尝试运行这个例子

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyBidings extends JFrame {
    int x = 0;
    int y = 0;

    DrawPanel drawPanel = new DrawPanel();

    public KeyBidings(){
        Action rightAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e) {
                x +=10;
                drawPanel.repaint();
            }
        };

            InputMap inputMap = drawPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = drawPanel.getActionMap();

        inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
        actionMap.put("rightAction", rightAction);

        add(drawPanel);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private class DrawPanel extends JPanel {


        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GRAY);
                    g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.GREEN);
            g.fillRect(x, y, 50, 50);
        }

        public Dimension getPreferredSize() {
            return new Dimension(400, 200);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable(){
            public void run(){
                new KeyBidings();
            }
        });
    }
}

enter image description here

在此处输入图片说明

Here's the code you're more concerned with

这是您更关心的代码

    Action rightAction = new AbstractAction(){
        public void actionPerformed(ActionEvent e) {
            x +=10;
            drawPanel.repaint();
        }
    };

    InputMap inputMap = drawPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
    ActionMap actionMap = drawPanel.getActionMap();

    inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
    actionMap.put("rightAction", rightAction);

Create a custom action and add that action to the action map, linked to the input map keystroke. In the action, just increment or, decrement the x and/or y, depending on the direction, then repaint the panel.

创建自定义操作并将该操作添加到操作映射,链接到输入映射击键。在操作中,只需根据方向增加或减少 x 和/或 y,然后重新绘制面板。



SeeKey binding tutorial| Graphics tutorial

键绑定教程| 图形教程