Java如何让矩形移动更快?

4
所以我正在尝试在Java中制作流行的游戏Pong。我已经制作了玩家矩形并设置了操作监听器,所以我准备在屏幕上将玩家向上和向下移动。但是我遇到了一个问题。当我移动玩家时,我可以选择每次移动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 - mKorbel
5个回答

4
不要依赖系统提供的按键重复功能。它们可能会发生低频率(这会导致您描述的问题),并且依赖于系统键盘设置。
我建议您使用 keyPressed 启动一个 Timer,并使用 keyReleased 停止它。
计时器可以安排每20毫秒或更长时间执行一次 TimerTask,它可以更新坐标并调用 repaint()。(不用担心过于频繁地调用 repaint()。如果 EDT 无法跟上,它将把连续的调用合并成单个绘画。)

2
在游戏中,传统上使用游戏循环来控制应用程序,而不是驱动Swing的事件驱动系统。
可以使用存储挡板移动的变量,例如具有UP、DOWN和STATIONARY的枚举。您的键监听器将设置此变量的值,然后游戏循环将检查该变量并相应地更新挡板的位置。
这种技术将应用程序的速度与其运行的环境的速度分离开来。

2
如何使动画更加流畅但同时保持快速移动?
一种技巧是在移动物体的路径上画出半透明版本,如果每次移动较少像素,则沿该路径移动。
例如,对于10像素移动,在移动的第1个像素处绘制10%不透明度的版本,在第2个像素处绘制20%等等。 Moving Block
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();
            }
        });
    }
}

当玩家移动到半透明区域时,设置透明度? - Thobias Nordgaard
我不确定你的意思是什么。 - Andrew Thompson
1
这是一种视觉上的平滑,像一个路径,但并不能真正解决你的问题。 - rotsch
是的,我的意思是在移动区域上进行视觉平滑处理。请参见上文。当然,可以使用已提供的有关监听键盘的技巧。我不会重复提及。 - Andrew Thompson

1
  • 不要在Swing JComponents中使用KeyListener

  • 使用KeyBinding来代替Swing JComponents

  • 不要直接在JFrame上绘制,应该放置JPanel并使用paintComponent()方法代替paint()方法,这样你的动画会更加流畅和自然


0
只要你依赖按键来控制矩形,你只能以按键重复事件的速度移动(或者以用户打字的速度移动)。要么监听其他事件,比如鼠标移动,要么将键盘配置为更高的重复率。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接