Java 对象移动

Java object movement(Java 对象移动)
本文介绍了Java 对象移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我试图让一个圆圈在键盘输入中移动.我根本无法移动对象.有人可以帮我找出问题所在吗?这是我的代码:

I am trying to get a circle to move through the input of a keyboard. I am not able to move the object at all. Can someone help me figure out what is wrong? Here is my code:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;


public class AlienInvader extends JPanel implements KeyListener{

    Constants constant = new Constants();

    public void update() {
        constant.x += constant.xvel;
        addKeyListener(this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.MAGENTA);
        g.fillOval(constant.x, constant.y, 30, 30);
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println(constant.x);
        switch(e.getKeyCode()) {
        case KeyEvent.VK_LEFT:
            constant.xvel = -1;
            break;
        case KeyEvent.VK_RIGHT:
            constant.xvel = 1;
            break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        switch(e.getKeyCode()) {
        case KeyEvent.VK_LEFT:
            constant.xvel = -1;
            break;
        case KeyEvent.VK_RIGHT:
            constant.xvel = 1;
            break;
        }
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }


}

我不确定我做错了什么.我以为是因为我没有调用update方法,但是当我在paintComponent中添加了一个if语句(所以它只调用自己一次)并尝试了它时,我没有运气.

I am not sure what I am doing wrong. I thought it was because I wasn't calling the update method, but when I added a if statement in paintComponent (so it only calls itself once) and tried it, I had no luck.

推荐答案

首先,不要在任何 paintXxx 方法中调用 repaint.绘制方法通常被调用以响应对 repaint 的调用,因此您正在创建一个令人讨厌的、永无止境的、消耗资源的地狱循环.

To start with, don't call repaint within any paintXxx method. Paint methods are typically called in response to a call to repaint, therefore you are creating a nasty, never ending, ever consuming loop of resource hell.

其次,KeyListeners 仅在 1- 注册的组件可聚焦 2- 注册的组件具有焦点时才响应键事件.

Secondly, KeyListeners only respond to key events when 1- The component the are registered to are focusable 2- When the component they are registered to have focus.

在这种情况下,它们是一个糟糕的选择.改用 键绑定

They are a poor choice in this case. Use Key bindings instead

第三,您没有提供 preferredSize 提示供布局管理器使用.在您的情况下,这可能是也可能不是一件坏事,但您的组件可能会以 0x0 的大小布局

Thirdly, you are not providing a preferredSize hint for layout managers to use. This may or may not be a bad thing in your case, but it's possible that you component will be laid out with a size of 0x0

示例

类似......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MoveCircle {

    public static void main(String[] args) {
        new MoveCircle();
    }

    public MoveCircle() {
        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 int xDelta = 0;
        private int keyPressCount = 0;
        private Timer repaintTimer;
        private int xPos = 0;
        private int radius = 10;

        public TestPane() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "pressed.left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "pressed.right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "released.left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "released.right");

            am.put("pressed.left", new MoveAction(-2, true));
            am.put("pressed.right", new MoveAction(2, true));
            am.put("released.left", new MoveAction(0, false));
            am.put("released.right", new MoveAction(0, false));

            repaintTimer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += xDelta;
                    if (xPos < 0) {
                        xPos = 0;
                    } else if (xPos + radius > getWidth()) {
                        xPos = getWidth() - radius;
                    }
                    repaint();
                }
            });
            repaintTimer.setInitialDelay(0);
            repaintTimer.setRepeats(true);
            repaintTimer.setCoalesce(true);

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            g2d.drawOval(xPos, 0, radius, radius);
            g2d.dispose();
        }

        public class MoveAction extends AbstractAction {

            private int direction;
            private boolean keyDown;

            public MoveAction(int direction, boolean down) {
                this.direction = direction;
                keyDown = down;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                xDelta = direction;
                if (keyDown) {
                    if (!repaintTimer.isRunning()) {
                        repaintTimer.start();
                    }
                } else {
                    repaintTimer.stop();
                }
            }
        }
    }
}

例如...

这篇关于Java 对象移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)
Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)
Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)
How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)
How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)