绘制多个实例后,JPanel 绘图速度变慢

JPanel drawing is slowed down after several instances are painted

我正在构建游戏并使用 JPanel 的绘制功能绘制道路精灵。可以通过拖动鼠标来建造道路(建筑物 class),并且在每个字段上都会出现一个新的道路精灵。但是在我画了大约 20 个道路精灵之后,绘图变得非常慢。

我有一个框架,上面有这个 JPanel。 这是我的游戏绘图所在的 JPanel 的代码:

private class GamePanel extends JPanel implements ActionListener{
        
        Field[][] map = gameEngine.getMap().getFields();
        ArrayList<Building> buildings = gameEngine.getBuildings();
        Timer timer;
        ArrayList<Field> fields = new ArrayList<>();
        GameFrame frame;                                     //REFERENCE FOR THE CONTAINER OF THIS PANEL

        private int mousePosX;
        private int mousePosY;

        GamePanel(GameFrame frame){
        /*...*/
            Mouse mouseListener = new Mouse();
            addMouseListener(mouseListener);
            addMouseMotionListener(mouseListener);
            
            timer = new Timer(1000/30,this);
            timer.start();
        /*...*/
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);       
            draw(g);
        }

        public void draw(Graphics g){
            for(Building b : buildings){
                int drawPosX = b.getLocation().getPos().x*40;
                int drawPosY = b.getLocation().getPos().y*40;

                try {
                    BufferedImage img = ImageIO.read(new File("src/GFX/" + b.getType() + ".png"));
                    g.drawImage(img, drawPosX, drawPosY, null);
                } catch (IOException e) {
                }
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {                            
              // I thought this is not needed because I call "repaint()" only at mouse events (like 
              // building road by dragging)
        }

        public class Mouse extends MouseAdapter{
            @Override
            public void mouseDragged(MouseEvent evt){

                repaint();                            // THIS IS AN EXAMPLE TO WHERE I CALL THE REPAINT()

                fieldPosX = evt.getX() - (evt.getX() % 40);
                fieldPosY = evt.getY() - (evt.getY() % 40);
                
                gameEngine.placeRoad(new SimpleRoad(new Field(fieldPosX/40,fieldPosY/40)));
            }
            
            /*... OTHER MOUSE EVENTS ...*/
        }

        

我认为仅在鼠标事件时调用 repaint() 会优化速度,但事实并非如此。我附上了一张GIF,可以看到经过2条路,速度真的很慢。

我听说过 invokeLater,人们建议我使用它,但我不知道如何在这个项目中实现它。为什么我的游戏在几个建筑之后变慢了,我在哪里犯了错误? invokeLater 会解决问题吗?如何将它放入我的项目中?

感谢您的帮助!

Why is my game getting slower after several buildings,

try
{
    BufferedImage img = ImageIO.read(new File("src/GFX/" + b.getType() + ".png"));
    g.drawImage(img, drawPosX, drawPosY, null);
}

画法中不要I/O。当您添加更多建筑物时,您正在做更多的事情 I/O.

应该在 class 的构造函数中读取图像。

可以将它们保存在一个HashMap中,方便在画法中访问。

或者,图像可以保存为建筑物 class 本身的一部分。