Using keypad to move a circle at angles in java

本秂侑毒 提交于 2019-12-19 12:08:46

问题


So I have an application that successfully moves a ball (ellipse) left, right, up, or down depending on which button of the keypad is being pressed. However, I'm having trouble getting the ball to move at an angle. I'm trying to do this by saying that if the user holds 2 direction keys, the ball will go in diagonally. For example, If they click the left key and the up key, I want the ball to move in an NorthWest direction. If any of you see what is causing the problem, I'd really appreciate the help!

Engine

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){}
    }

CircleComponent

 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;
                }   
        }
}

回答1:


Because the key events will only report the last key that triggered the event, your last if statement will never work, as the keyCode will only ever equal the last key that triggered the event.

Instead, you should maintain a "state" of each key and process against that state instead.

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);
        }
    }
}

I would also recommend that instead of KeyListener, you should use Key Bindings instead. They solve annoying focus issues that plague KeyListener




回答2:


Change your KeyClickListener to and observe the magic! then checkout this 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);
            }
        }
    }


来源:https://stackoverflow.com/questions/16290543/using-keypad-to-move-a-circle-at-angles-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!