java - 移动鼠标时 JPanel FPS 下降

标签 java swing jpanel frame-rate mousemove

我正在使用 Swing 的 JPanel 扩展作为绘图界面,用 Java 制作一个小游戏。

我在面板的paintComponent()内绘制所有内容

游戏运行得很顺利,直到我开始移动鼠标。当我这样做时,我的 FPS 会大幅下降,尤其是当我移动速度非常快时,导致游戏无法玩。 即使我停止绘制鼠标光标,也会发生这种情况。

JComponent 对象上绘图时这是正常的吗?

附注我在任何组件上都找不到任何已注册的 MouseListenerMouseMotionListener 对象。

<小时/>

编辑:

MCVE

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class AnimationSlowDownOnMouse {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame mainWindow = new JFrame("dotShoot");
        mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainWindow.setExtendedState(JFrame.MAXIMIZED_BOTH);

        final GamePanel gp = new GamePanel();
        gp.setPreferredSize(new Dimension(1920, 1080));
        mainWindow.add(gp);

        mainWindow.pack();
        gp.init();

        Thread gameThread = new Thread(new Runnable() {
            @Override
            public void run() {
                final int maxTicksPerSecond = 100;
                final int optimalTimePerTick = 1000 / maxTicksPerSecond;

                final int maxFrameSkips = 5;

                long tickCount = 0L;
                float AvgIES = 0f;
                //int FPS = 0;          
                int DCPS = 0;
                int TPS = 0;
                long timeStarted = System.currentTimeMillis();
                long timeElapsed = 0L;

                int tickReset = 0;
                int drawCallsReset = 0;
                long timeReset = timeStarted;
                float interpolationReset = 0f;

                long nextLoop = timeStarted;
                int frameSkips = 0;

                float interpolation;

                while (true) {
                    synchronized (this) {
                        frameSkips = 0;

                        while (System.currentTimeMillis() > nextLoop && frameSkips < maxFrameSkips) {
                            gp.update(tickCount);
                            nextLoop += optimalTimePerTick;
                            tickCount++;
                            tickReset++;
                            frameSkips++;
                        }

                        interpolation = (float) (System.currentTimeMillis() + optimalTimePerTick - nextLoop) / (float) optimalTimePerTick;
                        gp.setInterpolation(interpolation);
                        gp.repaint();
                        interpolationReset += interpolation;
                        drawCallsReset++;
                        timeElapsed = System.currentTimeMillis() - timeStarted;

                        if (System.currentTimeMillis() - timeReset >= 1000) {
                            AvgIES = interpolationReset / (float) drawCallsReset;
                            interpolationReset = 0f;

                            TPS = tickReset;
                            tickReset = 0;

                            DCPS = drawCallsReset;
                            drawCallsReset = 0;

                            timeReset = System.currentTimeMillis();
                        }
                    }
                }

            }
        });
        gameThread.start();

        mainWindow.setVisible(true);

        gp.requestFocus();
    }

}

class GamePanel extends JPanel {

    /**
     *
     */
    private static final long serialVersionUID = 3110478596996378903L;

    public GamePanel() {
        this.getInputMap().put(KeyStroke.getKeyStroke("pressed A"), "pressed Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("released A"), "released Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("pressed D"), "pressed Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("released D"), "released Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("pressed W"), "pressed Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("released W"), "released Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("pressed S"), "pressed Key");
        this.getInputMap().put(KeyStroke.getKeyStroke("released S"), "released Key");

        this.getActionMap().put("pressed Key", new AbstractAction() {
            private static final long serialVersionUID = 1296609706338138539L;

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (!pks.contains(arg0.getActionCommand())) {
                    pks += arg0.getActionCommand() + ", ";
                }
            }
        });

        this.getActionMap().put("released Key", new AbstractAction() {
            private static final long serialVersionUID = 4364732373538162119L;

            @Override
            public void actionPerformed(ActionEvent arg0) {
                pks = pks.replace(arg0.getActionCommand() + ", ", "");
            }
        });

        this.setBackground(new Color(0x6495ed));
    }

    public void init() {

    }

    private String pks = "";

    public void update(long currentTick) {

    }

    private float interpolation = 0;

    public void setInterpolation(float interpolation) {
        this.interpolation = interpolation;
    }

    private int frames = 0;
    private long timeForFPS = 0;
    private int ActualFPS = 0;

    public int getFPS() {
        return ActualFPS;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.black);
        g.drawString("FPS: " + ActualFPS, 0, 10);
        frames++;
        if (System.currentTimeMillis() - timeForFPS >= 1000) {
            ActualFPS = frames;
            frames = 0;
            timeForFPS = System.currentTimeMillis();
        }
    }
}
<小时/>

编辑2:

http://tinypic.com/r/9bkf4k/8
http://tinypic.com/r/345m24i/8

最佳答案

与其他评论一样,当我在我的计算机上尝试上面的代码时,FPS 没有问题。我还在只有一个处理器的虚拟机上尝试过。当鼠标快速移动时,FPS 仍然没有显着下降。虽然处理器总是显示100%的使用率。您在其他计算机上尝试过此操作吗?我怀疑,你也不会在那里看到 FPS 问题。因此,问题可能出在您的计算机上,而不是您的程序代码上。

关于java - 移动鼠标时 JPanel FPS 下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31660930/

相关文章:

java - 处理已检查和未检查的异常?

java - 为 Java 应用程序设置全局字体

java - 用java画一个简​​单的2D图

java - 在 JScrollpane 内动态更改 JPanel 中的内容可见性

java - 调查有关 String.valueOf(float) 的 Java 错误

java - 执行字符串验证(使用多个字符串)

java - JFrame 不显示来自 JLabel 的图片

java - 缺少 GUI 输出

java - 如何在 JFrame 中设置 JPanel 的大小?

java - 摆脱警告?