当前位置: 代码迷 >> java >> 移动鼠标时JPanel FPS下降
  详细解决方案

移动鼠标时JPanel FPS下降

热度:74   发布时间:2023-08-02 11:22:05.0

我正在使用Java Swing的JPanel扩展作为绘图表面,用Java JPanel小型游戏。

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

在我开始移动鼠标之前,游戏运行平稳。 当我这样做时,我会得到巨大的FPS下降,特别是如果我快速移动它时,将导致游戏无法进行。 即使我停止绘制鼠标光标,也会发生这种情况。

JComponent对象上绘制是否正常?

PS我在任何组件上都找不到任何已注册的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:


与其他注释一样,当我在计算机上尝试上面的代码时,FPS也没有问题。 我也在只有一个处理器的虚拟机上尝试过。 当鼠标快速移动时,FPS仍然没有急剧下降。 尽管处理器始终显示100%使用率。 您是否在其他计算机上尝试过? 我怀疑,您也不会在其中看到FPS问题。 因此,问题可能出在您的计算机上,而不在您的程序代码上。