1

嘿,谢谢你看我的帖子。整个夏天我一直在做一个充满激情的项目,这个问题已经出现了。首先,这可能算作一个重复的问题,但我一直在寻找这个站点和 Oracle 的修复程序,但找不到一个,或者更可能我只是不理解我正在使用的代码。一个主要的帮助是一艘充满鳗鱼的气垫船来解决这样的问题

我想要一个盒子, , 用, , ,键在一个, 另一个,JPanel周围移动。首先,我通过扩展创建了自己的面板。从那里我设法让运动正常工作,但由于键绑定的工作方式而出现口吃,我读到添加一个摆动计时器会改善口吃。我最初的猜测是我没有正确实施某些事情,或者对我正在做的事情知之甚少,无法看到我的错误。我还尝试设置一面旗帜以帮助持续移动。没有错误消息,还有一些我需要实现的东西,比如防止越界。这是我所拥有的:JFrameJPanelwasdJPanel

public class PlayerPanel extends JPanel {
    private static final int width = 100;
    private static final int height = 200;
    private int xPos, yPos;
    private boolean movingUp, movingDown, movingLeft, movingRight;
    private static final int SPIN_TIMER_PERIOD = 20;
    private Timer timer;
    
    public PlayerPanel() {
        xPos = this.getX();
        yPos = this.getY();
        movingUp = movingDown = movingLeft = movingRight = false;
        timer = new Timer(SPIN_TIMER_PERIOD, new SpinTimerListener());
        timer.setInitialDelay(0);
        timer.start();
        
        setPreferredSize(new Dimension(width, height));
        setBackground(Color.cyan);
        setUpKeyBindings();
    }
    
    private void setUpKeyBindings() {
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inMap = this.getInputMap(condition);
        ActionMap actMap = this.getActionMap();
        
        inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "moveUp");
        actMap.put("moveUp", new KeyAction("up"));
        
        inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "moveDown");
        actMap.put("moveDown", new KeyAction("down"));
        
        inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "moveLeft");
        actMap.put("moveLeft", new KeyAction("left"));
        
        inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "moveRight");
        actMap.put("moveRight", new KeyAction("right"));
    }
    
    public class KeyAction extends AbstractAction {
        private String direction;
        private int delta = 2;

        public KeyAction(String direction) {
            this.direction = direction;
        }
        
        @Override
        public void actionPerformed(ActionEvent e) {
            switch(direction) {
                case "up":
                    movingUp = true;
                    yPos -= delta;
                    break;
                case "down":
                    movingDown = true;
                    yPos += delta;
                    break;
                case "right":
                    movingRight = true;
                    xPos += delta;
                    break;
                case "left":
                    movingLeft = true;
                    xPos -= delta;
                    break;
                default:
                    break;
            }
        }
    }
    
    private class SpinTimerListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            int delta = 5;

            if(movingUp) {
                yPos -= delta;
                movingUp = false;
            }
            else if(movingDown) {
                yPos += delta;
                movingDown = false;
            }
            else if(movingLeft) {
                xPos -= delta;
                movingLeft = false;
            }
            else if(movingRight) {
                xPos += delta;
                movingRight = false;
            }
            setLocation(xPos, yPos);
        }
    }
}

我试图让我的代码最小化,这就是我的目标。

是的,有更有效的编码方法,比如使用枚举来帮助设置我的键绑定,但我的编码理念是:

  • 弄清楚我想做什么,让它工作(通常使用我所说的蛮力代码)
  • 了解它为什么起作用
  • 让它变得更好,让它变得漂亮。

我处于理解阶段。另一个非常有效的观点是为什么我不使用 Graphics,就像在 Graphics g.draw(blah) 中一样。TBH 我不知道。我无法让它工作,在我提出涉及它的问题之前,我需要花更多的时间来处理它,因为在这里要求某人教我如何使用图形似乎不合适。

所以除了像我应该使用的那样使用图形之外,我怎样才能更好地实现我的键绑定和摆动计时器。我在想我使用setLocation可能是一个问题,而不是使用 graphics.repaint 或其他东西,但setLocation调用 repaint 所以我认为这不是主要问题,但可能仍然是一个问题。我为文字墙道歉,但我想尝试彻底,所以......

TL:博士;我正在JPanel使用键绑定和摆动计时器进行自定义移动。运动结结巴巴,我也不希望它。在发布和休息后,我会将四个移动布尔值合并为一个,因为这也可能无济于事,并为方向添加一个状态变量并尝试整理我的代码。感谢您查看我的代码,如果您这样做了,欢迎提供任何帮助。我喜欢学习如何编码和阅读你告诉我我懒得搜索的任何数量的参考资料。

如果您想完全运行我正在运行的内容,这也是我的主要内容,PlayerPanel并且Driver具有 main 方法的类是我正在使用的仅有的两个文件。

public class Driver {

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        frame.setSize(1000, 500);
        
        JPanel background = new JPanel();
        background.setBackground(Color.BLACK);
        
        PlayerPanel player = new PlayerPanel();
        background.add(player);
        
        frame.add(background);
        frame.setVisible(true);
    }
}
4

0 回答 0