【问题标题】:Using keypad to move a circle at angles in java使用键盘在java中以角度移动圆
【发布时间】:2013-04-23 19:42:57
【问题描述】:

所以我有一个应用程序可以成功地向左、向右、向上或向下移动球(椭圆),具体取决于按下键盘的哪个按钮。但是,我无法让球以一定角度移动。我试图通过说如果用户持有 2 个方向键,球会斜着进入。例如,如果他们单击左键和上键,我希望球向西北方向移动。如果你们中的任何人发现导致问题的原因,我将非常感谢您的帮助!

引擎

class KeyClickListener implements KeyListener
        {
        public void keyPressed(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_DOWN )
                {
                    component.moveCircle(1);
                }
            else if (e.getKeyCode() == KeyEvent.VK_UP)
                {
                    component.moveCircle(2);
                }
            else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    component.moveCircle(3);
                }
            else if (e.getKeyCode() == KeyEvent.VK_LEFT)
                {
                    component.moveCircle(5);
                }   
            //this is my attempt at telling whether or not the user was holding two keys
            else if (e.getKeyCode() == KeyEvent.VK_LEFT && e.getKeyCode() == KeyEvent.VK_UP)
                {
                    component.moveCircle(5);
                }
        }
        public void keyReleased(KeyEvent e){}
        public void keyTyped(KeyEvent e){}
    }

圆组件

 public void moveCircle(int w)
 {
    dir = w;
    if (dir == 1)
        {
            y+=20;
            repaint();
            if (y>=560)
                {
                    dir=2;
                }
        }
.  
.
.

else if (dir == 5)
        {
            x-=10;
            y-=10;
            repaint();
            if(x<=0 )
                {
                    dir=3;
                }   
        }
}

【问题讨论】:

    标签: java keyboard actionlistener direction


    【解决方案1】:

    因为按键事件只会报告触发事件的最后一个按键,所以您的最后一个 if 语句将永远不会起作用,因为 keyCode 将永远等于触发事件的最后一个按键。

    相反,您应该维护每个键的“状态”并针对该状态进行处理。

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestKeyListener01 {
    
        public static void main(String[] args) {
            new TestKeyListener01();
        }
    
        public TestKeyListener01() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private boolean arrowUp = false;
            private boolean arrowDown = false;
            private boolean arrowLeft = false;
            private boolean arrowRight = false;
    
            public TestPane() {
                setFocusable(true);
                addKeyListener(new KeyAdapter() {
    
                    @Override
                    public void keyReleased(KeyEvent e) {
                        switch (e.getKeyCode()) {
                            case KeyEvent.VK_DOWN:
                                arrowDown = false;
                                break;
                            case KeyEvent.VK_UP:
                                arrowUp = false;
                                break;
                            case KeyEvent.VK_LEFT:
                                arrowLeft = false;
                                break;
                            case KeyEvent.VK_RIGHT:
                                arrowRight = false;
                                break;
                        }
                        repaint();
                    }
    
                    @Override
                    public void keyPressed(KeyEvent e) {
                        switch (e.getKeyCode()) {
                            case KeyEvent.VK_DOWN:
                                arrowDown = true;
                                break;
                            case KeyEvent.VK_UP:
                                arrowUp = true;
                                break;
                            case KeyEvent.VK_LEFT:
                                arrowLeft = true;
                                break;
                            case KeyEvent.VK_RIGHT:
                                arrowRight = true;
                                break;
                        }
                        repaint();
                    }
                });
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                FontMetrics fm = g2d.getFontMetrics();
                String text = "Up";
                int x = (getWidth() - fm.stringWidth(text)) / 2;
                int y = ((getHeight() / 2) - fm.getHeight());
                draw(g2d, text, x, y, arrowUp);
    
                text = "Down";
                x = (getWidth() - fm.stringWidth(text)) / 2;
                y = ((getHeight() / 2) + fm.getHeight()) + fm.getAscent();
                draw(g2d, text, x, y, arrowDown);
    
                text = "Left";
                x = (getWidth() / 2) - fm.stringWidth(text) - 4;
                y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
                draw(g2d, text, x, y, arrowLeft);
    
                text = "Right";
                x = (getWidth() / 2) + 4;
                y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
                draw(g2d, text, x, y, arrowRight);
    
                g2d.dispose();
            }
    
            protected void draw(Graphics2D g2d, String text, int x, int y, boolean pressed) {
                g2d.setColor(pressed ? Color.BLACK : Color.GRAY);
                g2d.drawString(text, x, y);
            }
        }
    }
    

    我还建议您不要使用KeyListener,而应使用Key Bindings。他们解决了困扰KeyListener

    的烦人焦点问题

    【讨论】:

    • +1 用于键绑定; LinePanel 就是一个例子。
    【解决方案2】:

    将您的 KeyClickListener 更改为并观察魔法!然后签出这个http://zetcode.com/tutorials/javagamestutorial/movingsprites/

        class KeyClickListener implements KeyListener, Runnable
        {
            private boolean moveLeft, moveRight, moveUp, moveDown;
            private Thread runThread;
            public KeyClickListener() {
                moveLeft = moveRight = moveUp = moveDown = false;
                runThread = new Thread(this);
                runThread.start();
            } 
            public void keyPressed(KeyEvent e) {assessKeycodes(e, true);}
            public void keyReleased(KeyEvent e){assessKeycodes(e, false);}
            public void keyTyped(KeyEvent e){}
    
            private void assessKeycodes(KeyEvent e, boolean setTo) {
                switch(e.getKeyCode()) {
                    case KeyEvent.VK_DOWN:
                        moveDown = setTo;
                        break;
                    case KeyEvent.VK_UP:
                        moveDown = setTo;
                        break;
                    case KeyEvent.VK_LEFT:
                        moveDown = setTo;
                        break;
                    case KeyEvent.VK_RIGHT:
                        moveDown = setTo;
                        break;
                }
            }
    
            public void run() {
                while(true) {
                    if (moveDown)
                            component.moveCircle(1);
                    if (moveUp)
                            component.moveCircle(2);
                    if (moveRight)
                            component.moveCircle(3);
                    if (moveLeft)
                            component.moveCircle(5);
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      • 2016-01-21
      • 2014-05-13
      • 2022-12-24
      • 1970-01-01
      相关资源
      最近更新 更多