【问题标题】:Java moving rectangle faster?Java移动矩形更快?
【发布时间】:2012-06-14 05:01:01
【问题描述】:

所以我正在尝试用java制作流行的游戏乒乓球。我已经制作了播放器矩形并设置了动作侦听器,因此我准备好在屏幕上上下移动播放器。但是我遇到了一个问题。当我移动玩家时,我可以选择每次移动 X 像素。

但是,如果我将要移动的 X 像素设置为 1。那么玩家移动得太慢了。如果我将 X 像素设置为 10,那么他会跳过 9 像素,动画看起来很粗糙。我怎样才能使动画平滑并仍然快速移动?

这里有一些代码:

public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == keyUp){
                    playerYCordinate -= 10;
                }else if(e.getKeyCode() == keyDown){
                    playerYCordinate += 10;
                }
                repaint();
            }

            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == keyUp){

                }else if(e.getKeyCode() == keyDown){

                }
                repaint();
            }

【问题讨论】:

  • 如需更好的帮助,请尽快发帖SSCCE

标签: java awt java-2d


【解决方案1】:

不要依赖系统提供的按键重复功能。它们可能以低速率发生(这会导致您描述的问题)并且取决于系统键盘设置。

我建议您使用keyPressed 启动TimerkeyReleased 来停止它。

计时器可以安排每 20:th 毫秒左右执行一次TimerTask,它可以更新坐标并调用repaint()。 (不用担心过于频繁地调用repaint()。如果 EDT 跟不上,它会将连续调用重绘为单个绘制。)

【讨论】:

    【解决方案2】:

    我怎样才能使动画平滑并仍然快速移动?

    一种技术是沿着移动对象的路径绘制半透明版本的移动对象,如果每次移动的像素更少。

    例如对于 10 像素的移动,为移动的第一个像素绘制一个 10% 不透明度的版本,第二个移动像素为 20%,以此类推。

    import java.awt.*;
    import java.awt.event.*;
    
    import javax.swing.*;
    
    public class MovingBlock {
    
        MovingBlock() {
            final JPanel gui = new JPanel() {
    
                private static final long serialVersionUID = 1L;
                int x = 0;
                int step = 60;
    
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2 = (Graphics2D)g;
                    x+=10;
                    Color fg = getForeground();
                    for (int ii=x-step; ii<x; ii+=4) {
                        double transparency = (double)(x-ii)/(double)step;
                        Color now = new Color(
                                fg.getRed(),
                                fg.getGreen(),
                                fg.getBlue(),
                                (int)(255*(1-transparency)));
                        g2.setColor(now);
                        g2.fillRect(ii, 3, 5, 10);
                    }
                    if (x>getWidth()) {
                        x=0;
                    }
                }
            };
            gui.setBackground(Color.BLACK);
            gui.setForeground(Color.GREEN.darker());
            gui.setPreferredSize(new Dimension(400,16));
    
            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    gui.repaint();
                }
            };
            Timer timer = new Timer(20, listener);
            timer.start();
    
            JFrame f = new JFrame("Moving Block");
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setContentPane(gui);
            f.pack();
            f.setLocationByPlatform(true);
            f.setVisible(true);
        }
    
        public static void main(String[] args) throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new MovingBlock();
                }
            });
        }
    }
    

    【讨论】:

    • 然后设置玩家在半透明区域上移动时的透明度?
    • 我不确定你的意思。
    • 这是一种光学平滑,就像一条小径,但并不能真正解决您的问题。
    • 是的,我的意思是在移动区域中视觉上平滑它。往上看。当然,使用已经提供的关于听键的提示。我不会重复。
    【解决方案3】:

    在游戏中,传统上使用游戏循环来控制应用程序,而不是驱动 Swing 的事件驱动系统。

    你可以有一个变量来存储桨的运动,比如一个带有UPDOWNSTATIONARY的枚举。您的关键监听器将设置此变量的值,然后游戏循环将检查该变量并相应地更新桨的位置。

    这种技术将应用程序的速度与其运行环境的速度解耦。

    【讨论】:

      【解决方案4】:
      • 不要将KeyListener 用于Swing JComponents

      • KeyBinding 用于Swing JComponents

      • 不要画到JFrame放在那里JPanel和使用方法paintComponent()而不是paint(),你的动作会流畅自然

      【讨论】:

        【解决方案5】:

        只要您依靠按键来控制您的矩形,您就只能以按键重复事件进入的速度(或用户可以键入的速度)移动。要么听听鼠标移动之类的其他声音,要么将键盘配置为更高的重复率。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-22
          • 2014-12-02
          • 2012-01-02
          • 2013-03-21
          • 1970-01-01
          • 1970-01-01
          • 2014-02-21
          相关资源
          最近更新 更多